menu sin JS, iconos propios en vez de emoji, chats y tribus mas usables, README al dia
La 1.3.5 manda script-src 'none': fuera mobile_menu.js y mobile_pub.js. La hoja del menu se abre con el ancla #oasis-menu y :target, y el gesto atras la cierra sin cambiar de pantalla. La barra del pub solo sale si hay algo que contar. - iconos de linea propios (images/mobile-ico-*.svg, con mask) en los avisos de version y de sugerencia, las fichas de visibilidad y Compartir, en vez de emoji - avisos de arriba en una linea cada uno - chats: Responder es un boton con su nombre y Enviar ocupa el ancho; lo mismo en la respuesta del foro - tribus: ancla en las pestañas, todas en mayusculas, etiquetas y votos del foro de 44px - comentarios abiertos con la opcion del dev (setCommentsOpen) - Publicar al primer sitio de escribir encendido - buscador con "mas opciones" de la 1.3.5 tambien en form.filter-box - zonas tactiles y letra que quedaban cortas en fichas, pager, hora de comentario - README con capturas nuevas: actividad y menu de serie, perfil Activista, tribu, blog y ajustes; portada con los colores de serie - guia: sin JS desde la 1.3.5, la hoja con :target y los iconos mobile-*.svg
|
|
@ -46,7 +46,7 @@ Dónde va cada cosa:
|
||||||
|---|---|
|
|---|---|
|
||||||
| Cambiar colores, tamaños, márgenes | `styles/mobile_ux.css` (piezas) o `styles/activista.css` (lanzador y barras) |
|
| Cambiar colores, tamaños, márgenes | `styles/mobile_ux.css` (piezas) o `styles/activista.css` (lanzador y barras) |
|
||||||
| Cambiar los colores de serie o las paletas | Variables `--a26-*` de `themes/Activista.css`; las paletas, en `mobile_settings.js` |
|
| Cambiar los colores de serie o las paletas | Variables `--a26-*` de `themes/Activista.css`; las paletas, en `mobile_settings.js` |
|
||||||
| La barra de unirse a un pub | `views/mobile_pubbar.js` y `public/js/mobile_pub.js` |
|
| La barra de unirse a un pub | `views/mobile_pubbar.js` |
|
||||||
| Otro HTML en una pantalla del dev | Función en `views/mobile_ui.js` + una línea en su vista |
|
| Otro HTML en una pantalla del dev | Función en `views/mobile_ui.js` + una línea en su vista |
|
||||||
| Una pantalla nueva | Vista propia en `views/mobile_*.js` + ruta en `fork_routes.js` |
|
| Una pantalla nueva | Vista propia en `views/mobile_*.js` + ruta en `fork_routes.js` |
|
||||||
| Algo en Ajustes del móvil | `views/mobile_settings.js` |
|
| Algo en Ajustes del móvil | `views/mobile_settings.js` |
|
||||||
|
|
@ -81,7 +81,8 @@ Cómo seguir modificando, paso a paso:
|
||||||
es una regla del modelo, así que se explica en pantalla y punto.
|
es una regla del modelo, así que se explica en pantalla y punto.
|
||||||
- `src/server/` (arranque de SSB, `ssb_config.js`, `package.json`).
|
- `src/server/` (arranque de SSB, `ssb_config.js`, `package.json`).
|
||||||
- `src/backend/request_guards.js`, que lleva la CSP. Nada de `style=""` ni de
|
- `src/backend/request_guards.js`, que lleva la CSP. Nada de `style=""` ni de
|
||||||
`<script>` en la página.
|
`<script>` en la página. Desde la 1.3.5 es `script-src 'none'`: tampoco valen
|
||||||
|
ficheros `.js` propios. Lo que haga falta, con enlaces, formularios y CSS.
|
||||||
- Las traducciones del dev, `translations/oasis_*.js`. Se reescriben casi en cada
|
- Las traducciones del dev, `translations/oasis_*.js`. Se reescriben casi en cada
|
||||||
versión.
|
versión.
|
||||||
- `styles/style.css` y `styles/mobile.css`.
|
- `styles/style.css` y `styles/mobile.css`.
|
||||||
|
|
@ -131,9 +132,10 @@ tiene o lo está haciendo.
|
||||||
## Navegación
|
## Navegación
|
||||||
|
|
||||||
Al abrir se ve la actividad. Los módulos están en la quinta pestaña de abajo, Menú,
|
Al abrir se ve la actividad. Los módulos están en la quinta pestaña de abajo, Menú,
|
||||||
que abre una hoja con el lanzador (`hive_views.js`: una casilla y CSS). Un script
|
que abre una hoja con el lanzador (`hive_views.js`). La abre el ancla `#oasis-menu`
|
||||||
mínimo, `public/js/mobile_menu.js`, hace que el botón atrás de Android cierre la hoja;
|
y la pinta `:target`: abrirla deja una entrada en el historial, así que el gesto atrás
|
||||||
sin él el menú funciona igual. La barra tiene cuatro atajos más Menú. Cada perfil trae los suyos (`BARS` en
|
la cierra sin cambiar de pantalla. La X, tocar fuera o volver a tocar Menú van a
|
||||||
|
`#menu-cerrado`, un ancla que no existe, para que la página no salte arriba. La barra tiene cuatro atajos más Menú. Cada perfil trae los suyos (`BARS` en
|
||||||
`fork_workflows.js`) y quien la cambia desde «Tu barra» la cambia solo para ese perfil
|
`fork_workflows.js`) y quien la cambia desde «Tu barra» la cambia solo para ese perfil
|
||||||
(`bottomBarBySkin` en la config; sin perfil reconocido, `bottomBarPins`). Por qué
|
(`bottomBarBySkin` en la config; sin perfil reconocido, `bottomBarPins`). Por qué
|
||||||
así: `docs/ESTUDIO_NAVEGACION.md`. Si se cambia, que sea con una prueba que lo
|
así: `docs/ESTUDIO_NAVEGACION.md`. Si se cambia, que sea con una prueba que lo
|
||||||
|
|
@ -152,9 +154,9 @@ Aquí se puede hacer lo que haga falta.
|
||||||
Activista, el único del móvil (Acampada y el OasisMobile del dev se quitaron del
|
Activista, el único del móvil (Acampada y el OasisMobile del dev se quitaron del
|
||||||
selector el 20/10/2026). Lo más simple posible: letra del sistema, bordes finos y
|
selector el 20/10/2026). Lo más simple posible: letra del sistema, bordes finos y
|
||||||
sin sombras. El skin quita lo que sobra; los colores los pone cada cual.
|
sin sombras. El skin quita lo que sobra; los colores los pone cada cual.
|
||||||
- `src/views/mobile_pubbar.js` y `public/js/mobile_pub.js`: la barra fija de unirse a
|
- `src/views/mobile_pubbar.js`: la barra fija de unirse a un pub (y de restaurar una
|
||||||
un pub (y de restaurar una copia), encima de la barra de abajo. Se pone al día sin
|
copia), encima de la barra de abajo. Solo sale si hay algo que contar y se pone al
|
||||||
recargar, preguntando a `/mobile/pub-status`; el estado sale de
|
día al cambiar de pantalla (sin JS); el estado sale de
|
||||||
`backupModel.restoreStatus()`, que `backend.js` le pasa a `fork_routes.js` en la
|
`backupModel.restoreStatus()`, que `backend.js` le pasa a `fork_routes.js` en la
|
||||||
línea que lo monta.
|
línea que lo monta.
|
||||||
- `src/views/mobile_ui.js`: lo que se enchufa en vistas del dev.
|
- `src/views/mobile_ui.js`: lo que se enchufa en vistas del dev.
|
||||||
|
|
@ -169,7 +171,9 @@ Aquí se puede hacer lo que haga falta.
|
||||||
- `src/views/mobile_icons.js`: los iconos.
|
- `src/views/mobile_icons.js`: los iconos.
|
||||||
- `src/backend/fork_routes.js`: nuestro router. Va justo delante del del dev.
|
- `src/backend/fork_routes.js`: nuestro router. Va justo delante del del dev.
|
||||||
- `src/backend/mobile_layer.js`: lo que nuestra interfaz necesita del backend
|
- `src/backend/mobile_layer.js`: lo que nuestra interfaz necesita del backend
|
||||||
(avatar, filtro y lanzador de la barra de arriba). La monta `fork_routes.js`.
|
(avatar, filtro y lanzador de la barra de arriba). La monta `fork_routes.js`. También
|
||||||
|
deja abiertos los comentarios de las fichas con la opción del dev
|
||||||
|
(`comments_view.setCommentsOpen`), salvo en el parlamento.
|
||||||
- `src/models/fork_workflows.js`: nuestros workflows, que en el móvil hacen de skins:
|
- `src/models/fork_workflows.js`: nuestros workflows, que en el móvil hacen de skins:
|
||||||
cada uno enciende unos módulos y trae su barra de abajo. Activista (acción directa,
|
cada uno enciende unos módulos y trae su barra de abajo. Activista (acción directa,
|
||||||
6 módulos) es el de serie, después Acampada (16) y los del dev; en Ajustes y en la
|
6 módulos) es el de serie, después Acampada (16) y los del dev; en Ajustes y en la
|
||||||
|
|
@ -179,6 +183,13 @@ Aquí se puede hacer lo que haga falta.
|
||||||
puesto (le pasa a Movimiento, el `activists` del dev, y a Por defecto).
|
puesto (le pasa a Movimiento, el `activists` del dev, y a Por defecto).
|
||||||
- `src/client/assets/translations/i18n_fork.js`: nuestros textos.
|
- `src/client/assets/translations/i18n_fork.js`: nuestros textos.
|
||||||
- `src/client/assets/images/ux-*.svg`: nuestras imágenes.
|
- `src/client/assets/images/ux-*.svg`: nuestras imágenes.
|
||||||
|
- `src/client/assets/images/mobile-*.svg`: iconos de línea que `mobile_ux.css` pinta
|
||||||
|
con `mask` en sitios del dev que llevan emoji o un carácter (avisos de arriba, fichas
|
||||||
|
de visibilidad, Compartir, estado del teléfono, responder y enviar en chats). Se
|
||||||
|
esconde el carácter con `font-size: 0` y el icono toma el color del texto. Mismo
|
||||||
|
trazo para todos: 24x24, línea de 2, puntas redondas. Los del menú y la barra de
|
||||||
|
abajo están en `views/mobile_icons.js` y no se tocan desde aquí. Nada de emoji ni de
|
||||||
|
logotipos (tampoco el robot de las sugerencias del dev).
|
||||||
- `android/scripts/sobre_oficial.sh`: monta la APK sobre la oficial del dev. El resto
|
- `android/scripts/sobre_oficial.sh`: monta la APK sobre la oficial del dev. El resto
|
||||||
de `android/` (el proyecto Gradle propio) queda como estaba, sin uso.
|
de `android/` (el proyecto Gradle propio) queda como estaba, sin uso.
|
||||||
- `android/icono/`: el icono adaptativo (la isla del logo de Oasis sobre su fondo).
|
- `android/icono/`: el icono adaptativo (la isla del logo de Oasis sobre su fondo).
|
||||||
|
|
|
||||||
61
README.md
|
|
@ -18,24 +18,35 @@ 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
|
las traducciones son de epsylon y no se tocan; lo nuestro va en hojas, vistas y rutas
|
||||||
propias.
|
propias.
|
||||||
|
|
||||||
Versión base: Oasis 1.3.3 · Rama: `PRUEBAS` ·
|
Versión base: Oasis 1.3.5 · Rama: `PRUEBAS` ·
|
||||||
[Documentación completa](https://gitea.laenre.net/hacklab/OASIS_MOBILE/wiki) ·
|
[Documentación completa](https://gitea.laenre.net/hacklab/OASIS_MOBILE/wiki) ·
|
||||||
[Versión de escritorio](https://gitea.laenre.net/hacklab/OASIS_LINUX)
|
[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
|
Android 7 o superior, 64 bits · se instala junto al Oasis oficial sin pisarlo
|
||||||
|
|
||||||
### Novedades de esta versión
|
### 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.5: cabecera por módulo, buscador con más opciones, avisos de
|
||||||
chats privados y tribus, visibilidad de menciones y las traducciones nuevas.
|
versión y sugerencias, y su CSP sin JavaScript en la página.
|
||||||
- Arranca en modo acampada: chats, teléfono, salas, pads, foro, wiki, tribus,
|
- Arranca con el perfil Mínimo: chats, teléfono, eventos, emergencias, invitaciones y
|
||||||
parlamento, votaciones y eventos. El resto se enciende en *Módulos* o en
|
copia de seguridad. Encima van Acampada (16 módulos), Activista (24) y los del dev,
|
||||||
*Ajustes → Workflows*.
|
de menos a más, cada uno con su barra de abajo. Se cambia en *Ajustes → Perfil*.
|
||||||
- Las llamadas son las de Oasis. Fuera Karvan, el módulo propio de salas: ahora se usan
|
- Un solo skin, Activista: letra del sistema, bordes finos y sin sombras. Los colores
|
||||||
el Teléfono y las Salas del dev, con su levantar la mano, grabación y emisión.
|
de serie son los de la APK oficial (negro y oro) y se cambian en *Ajustes → Colores*.
|
||||||
|
- Menú sin JavaScript: la hoja se abre con un ancla y el gesto atrás la cierra sin
|
||||||
|
cambiar de pantalla.
|
||||||
|
- Tribus: las pestañas se quedan a la vista al cambiar de sección, todas en el mismo
|
||||||
|
estilo, y los botones de la columna (unirse, invitar, suscribirse, etiquetas) de
|
||||||
|
44 px.
|
||||||
|
- Responder en los chats es un botón con su nombre, no una flecha de 27 px junto a la
|
||||||
|
hora; Enviar ocupa el ancho. Los comentarios salen abiertos, con la caja a la vista.
|
||||||
|
- Iconos de línea propios en vez de los emoji del dev en los avisos, las fichas de
|
||||||
|
visibilidad (pública, mutuos, cifrada, licencia, tribu) y Compartir.
|
||||||
|
- Publicar lleva al primer sitio de escribir que esté encendido (blog, feed, foro o
|
||||||
|
wiki); antes, sin blogs, acababa en Módulos.
|
||||||
- La APK se monta sobre la oficial: se coge la del dev, se le cambia el backend por el
|
- La APK se monta sobre la oficial: se coge la del dev, se le cambia el backend por el
|
||||||
de la rama y se le da otro nombre de paquete. Así trae todo lo nativo del dev (el
|
de la rama y se le da otro nombre de paquete. Así trae todo lo nativo del dev (el
|
||||||
puente de audio y cámara, las notificaciones de llamada) y convive con la oficial.
|
puente de audio y cámara, las notificaciones de llamada) y convive con la oficial.
|
||||||
|
|
@ -64,15 +75,15 @@ Android 7 o superior, 64 bits · se instala junto al Oasis oficial sin pisarlo
|
||||||
| | Oasis oficial | Esta rama |
|
| | Oasis oficial | Esta rama |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Llamadas y salas | Teléfono y Salas, con micrófono y cámara | Los mismos, tal cual |
|
| Llamadas y salas | Teléfono y Salas, con micrófono y cámara | Los mismos, tal cual |
|
||||||
| Interfaz de móvil | El menú de escritorio en una pantalla pequeña | Tema Acampada, lanzador con iconos, fichas, barra de cuatro atajos |
|
| Interfaz de móvil | El menú de escritorio en una pantalla pequeña | Skin Activista, actividad al abrir, hoja de Menú con iconos, barra de cuatro atajos |
|
||||||
| Primer arranque | Casi sesenta módulos encendidos | Modo acampada: lo justo para organizarse |
|
| Primer arranque | Casi sesenta módulos encendidos | Perfil Mínimo (6 módulos) y una escalera de perfiles hasta los del dev |
|
||||||
| Votaciones | Seis opciones fijas en una tabla | Sí/No, semáforo o termómetro, con barras |
|
| 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 |
|
| Varias identidades | Una por instalación | Varias en el mismo móvil, con aviso si dos comparten clave |
|
||||||
| App Android | La del dev | La del dev, con el backend de la rama y paquete propio (`net.laenre.oasis`) |
|
| App Android | La del dev | La del dev, con el backend de la rama y paquete propio (`net.laenre.oasis`) |
|
||||||
| Metadatos de las fotos | Se quitan solo si está `sharp`; en Android nunca | Se quitan siempre: GPS, marca, modelo, número de serie |
|
| 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
|
Los nombres de las categorías, los módulos y el resto de la aplicación son los de
|
||||||
epsylon, sin tocar. Con el tema OasisMobile se ve el del propio dev.
|
epsylon, sin tocar.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -127,20 +138,20 @@ En la barra de arriba, junto al avatar, está el botón de *No molestar* del Tel
|
||||||

|

|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="docs/capturas/01-portada.png" width="200">
|
<img src="docs/capturas/01-actividad.png" width="200">
|
||||||
<img src="docs/capturas/02-tribus.png" width="200">
|
<img src="docs/capturas/02-menu.png" width="200">
|
||||||
<img src="docs/capturas/03-votacion.png" width="200">
|
<img src="docs/capturas/03-menu-activista.png" width="200">
|
||||||
<img src="docs/capturas/04-modulos.png" width="200">
|
|
||||||
</p>
|
</p>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="docs/capturas/05-ajustes.png" width="200">
|
<img src="docs/capturas/04-tribu.png" width="200">
|
||||||
<img src="docs/capturas/06-barra.png" width="200">
|
<img src="docs/capturas/05-blog.png" width="200">
|
||||||
<img src="docs/capturas/08-salas.png" width="200">
|
<img src="docs/capturas/06-ajustes.png" width="200">
|
||||||
<img src="docs/capturas/07-oasismobile.png" width="200">
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
La actividad al abrir, tribus, una votación de semáforo, módulos, ajustes, la barra de
|
Lo que sale al instalarla: la actividad al abrir y la hoja de Menú con el perfil
|
||||||
atajos, las salas del dev y el menú con el tema OasisMobile del dev.
|
Mínimo. Después, con el perfil Activista: el menú completo, una tribu, un blog y
|
||||||
|
Ajustes. Capturas a 412 px, en español, con los colores de serie. Cómo rehacerlas:
|
||||||
|
`docs/capturas/generar_portada.py`.
|
||||||
|
|
||||||
Casi sesenta módulos no caben en la pantalla de un teléfono. Al abrir la app se ve la
|
Casi sesenta módulos no caben en la pantalla de un teléfono. Al abrir la app se ve la
|
||||||
actividad, lo que ha pasado en la red. Abajo hay cuatro atajos que eliges tú y una
|
actividad, lo que ha pasado en la red. Abajo hay cuatro atajos que eliges tú y una
|
||||||
|
|
@ -148,9 +159,9 @@ quinta pestaña fija, Menú, que abre desde abajo una hoja con todos los módulo
|
||||||
secciones, como el cajón de apps del móvil. Está en todas las pantallas. Por qué así,
|
secciones, como el cajón de apps del móvil. Está en todas las pantallas. Por qué así,
|
||||||
y no un menú arriba o una hamburguesa: [docs/ESTUDIO_NAVEGACION.md](docs/ESTUDIO_NAVEGACION.md).
|
y no un menú arriba o una hamburguesa: [docs/ESTUDIO_NAVEGACION.md](docs/ESTUDIO_NAVEGACION.md).
|
||||||
|
|
||||||
Solo aparecen los módulos activos. En *Ajustes → Workflows* se eligen de golpe: el de
|
Solo aparecen los módulos activos. En *Ajustes → Perfil* se eligen de golpe, de
|
||||||
acampada deja lo justo para organizarse. En el móvil un workflow cambia los módulos,
|
menos a más: Mínimo, Acampada, Activista y los del dev. Un perfil cambia los módulos y
|
||||||
no el aspecto: el aspecto se elige en *Ajustes → Tema* (Acampada u OasisMobile).
|
la barra de abajo, no el aspecto: los colores van en *Ajustes → Colores*.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,10 @@ mismo lanzador de ahora). Se cierra tocando fuera, con la X o volviendo a tocar
|
||||||
|
|
||||||
Es la idea de B, un botón que despliega las opciones, pero puesto donde llega el
|
Es la idea de B, un botón que despliega las opciones, pero puesto donde llega el
|
||||||
pulgar y donde está el resto de la navegación. Funciona igual en todas las pantallas.
|
pulgar y donde está el resto de la navegación. Funciona igual en todas las pantallas.
|
||||||
Está hecho con una casilla y CSS; un script mínimo hace que el botón atrás de Android
|
Está hecho con un ancla y CSS (`:target`), sin JS: la CSP de la 1.3.5 no deja ninguno.
|
||||||
cierre la hoja en vez de cambiar de página.
|
Abrir la hoja deja una entrada en el historial y atrás la cierra sin cambiar de
|
||||||
|
página. Al volver atrás desde un módulo abierto desde la hoja, la hoja sale abierta:
|
||||||
|
se vuelve a donde se estaba.
|
||||||
|
|
||||||
## Lo que salió en la prueba (emulador, 19/10/2026)
|
## Lo que salió en la prueba (emulador, 19/10/2026)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ nuestros. Después, APK nueva con `sobre_oficial.sh` y repetir las pruebas.
|
||||||
|
|
||||||
Menú y perfiles:
|
Menú y perfiles:
|
||||||
|
|
||||||
- Publicar va siempre a `/blogs`; en Empleo y Negocio, que no tienen blogs, acaba en
|
- Hecho (23/10): Publicar va al primer sitio de escribir encendido (blog, feed, foro,
|
||||||
`/modules`. Llevarlo a crear según los módulos encendidos.
|
wiki).
|
||||||
|
|
||||||
Medidas:
|
Medidas:
|
||||||
|
|
||||||
|
|
@ -33,17 +33,13 @@ Medidas:
|
||||||
|
|
||||||
Tribus:
|
Tribus:
|
||||||
|
|
||||||
- Al tocar una pestaña se recarga arriba y su contenido queda bajo la cabecera. Hace
|
- Hecho (23/10): ancla `#tribe-tabs` en las pestañas (desde `mobile_ui.tribeTabs`) y
|
||||||
falta un ancla en el enlace: pedírsela al dev o meterla con el enganche de
|
todas en mayúsculas. Queda: imagen enorme en Gobierno.
|
||||||
`tribes_view.js`.
|
|
||||||
- Pestañas de 40 px, mayúsculas mezcladas ("Habitantes" y "GOBIERNO") y la fila se
|
|
||||||
corta con un "Más" debajo. Imagen enorme en Gobierno.
|
|
||||||
|
|
||||||
Blogs:
|
Blogs:
|
||||||
|
|
||||||
- La caja de comentar va tras un desplegable que solo dice "✑(0)": ponerle texto.
|
- Hecho (23/10): comentarios abiertos con la opción del dev
|
||||||
- El botón de enviar comentario queda 161 px bajo la barra de abajo.
|
(`comments_view.setCommentsOpen`, desde `mobile_layer.js`), salvo en el parlamento.
|
||||||
- Los comentarios salen plegados: quien comenta no ve el suyo al volver.
|
|
||||||
- Input de 32 px en el formulario de crear.
|
- Input de 32 px en el formulario de crear.
|
||||||
|
|
||||||
Wiki y pads:
|
Wiki y pads:
|
||||||
|
|
@ -118,3 +114,29 @@ Todas las listas:
|
||||||
grande y el nombre después.
|
grande y el nombre después.
|
||||||
- Rehacer la APK con `sobre_oficial.sh` y pasar `TESTS/perfiles` (ahora hay 10
|
- Rehacer la APK con `sobre_oficial.sh` y pasar `TESTS/perfiles` (ahora hay 10
|
||||||
perfiles y la barra cambia con cada uno).
|
perfiles y la barra cambia con cada uno).
|
||||||
|
|
||||||
|
|
||||||
|
## Tras las pruebas de tribus y mensajería (23/10)
|
||||||
|
|
||||||
|
`TESTS/tribus/` (local): dos identidades de usar y tirar, B ve desde fuera la tribu de
|
||||||
|
A, se une, recorre las 24 pestañas, escribe en el feed y el foro, y comenta un blog.
|
||||||
|
Pasa entero salvo lo de abajo.
|
||||||
|
|
||||||
|
Arreglado en la capa: la hoja del menú sin JS (`:target`), iconos propios en vez de
|
||||||
|
emoji en avisos, fichas de visibilidad y Compartir, avisos de arriba en una línea,
|
||||||
|
responder y enviar en los chats, buscador con "más opciones" de la 1.3.5 en
|
||||||
|
`form.filter-box`, botones de voto del foro, etiquetas de la tribu, hora de un
|
||||||
|
comentario, ficha PÚBLICO y etiquetas del menú que se salían.
|
||||||
|
|
||||||
|
Pedirle al dev:
|
||||||
|
|
||||||
|
- **Dejar una tribu no pide confirmación.** El botón DEJAR va directo a
|
||||||
|
`/tribes/leave/:id`. Lo mismo con la ✕ de borrar un comentario. Él ya tiene
|
||||||
|
`confirmPage` (lo usa para unirse con invitación abierta).
|
||||||
|
- **Enlace a un hilo que no existe.** En Actividad, la ficha de un comentario a un
|
||||||
|
evento lleva a `/thread/<id>` y sale "No se ha encontrado".
|
||||||
|
- **Emoji metidos en el texto**: "👥: 1 · 💬 3" en foros, listas y actividad, y
|
||||||
|
"🔔 SUSCRIBIRSE". Con un `span` alrededor del emoji, como ya hace en las fichas de
|
||||||
|
visibilidad, se podrían cambiar por iconos desde CSS.
|
||||||
|
- **Etiquetas de la barra de abajo**: "Votaciones" no cabe con cinco pestañas a 412 px
|
||||||
|
y sale "Votacion…".
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 305 KiB After Width: | Height: | Size: 141 KiB |
BIN
docs/capturas/01-actividad.png
Normal file
|
After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 134 KiB |
BIN
docs/capturas/02-menu.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 160 KiB |
BIN
docs/capturas/03-menu-activista.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 133 KiB |
BIN
docs/capturas/04-tribu.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 110 KiB |
BIN
docs/capturas/05-blog.png
Normal file
|
After Width: | Height: | Size: 61 KiB |
BIN
docs/capturas/06-ajustes.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 78 KiB |
|
|
@ -1,9 +1,11 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""Portada y esquemas del README, con la paleta del tema Acampada.
|
"""Portada y esquemas del README.
|
||||||
|
|
||||||
Las capturas de movil (01..08) se hacen aparte, con la app arrancada en un nodo de
|
Las capturas de movil (01..06) 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
|
pruebas a 412x915 y escala 2, en español y con lo que trae de serie (perfil Minimo y
|
||||||
dibuja esquema-interfaz.png, esquema-rama.png y esquema-llamadas.png.
|
colores del dev; 03 a 06 con el perfil Activista). Este script compone 00-portada.png
|
||||||
|
a partir de ellas, con los colores de serie, y dibuja esquema-interfaz.png,
|
||||||
|
esquema-rama.png y esquema-llamadas.png (estos aun con la paleta de Acampada).
|
||||||
El texto vive aqui: se cambia y se relanza, nunca se retocan los PNG a mano.
|
El texto vive aqui: se cambia y se relanza, nunca se retocan los PNG a mano.
|
||||||
|
|
||||||
python3 docs/capturas/generar_portada.py
|
python3 docs/capturas/generar_portada.py
|
||||||
|
|
@ -17,22 +19,25 @@ ANTON = HERE.parents[1] / "src/client/assets/fonts/Anton-Regular.ttf"
|
||||||
SANS = "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
|
SANS = "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
|
||||||
|
|
||||||
BG, FG, NEON, MUTED = "#ffffff", "#000000", "#00e5ff", "#555555"
|
BG, FG, NEON, MUTED = "#ffffff", "#000000", "#00e5ff", "#555555"
|
||||||
|
# colores de serie del movil (los de la APK oficial del dev)
|
||||||
|
DEV_BG, DEV_CARD, DEV_FG, DEV_ACCENT, DEV_MUTED = "#121212", "#1e1e1e", "#ffd700", "#ffa300", "#bbbbbb"
|
||||||
|
SANS_BOLD = "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf"
|
||||||
|
|
||||||
|
|
||||||
def font(path, size):
|
def font(path, size):
|
||||||
return ImageFont.truetype(str(path), size)
|
return ImageFont.truetype(str(path), size)
|
||||||
|
|
||||||
|
|
||||||
def phone(shot, width):
|
def phone(shot, width, fg=FG, neon=NEON):
|
||||||
"""Una captura dentro de un marco negro grueso con la sombra cian de los botones."""
|
"""Una captura dentro de un marco grueso con una sombra de color debajo."""
|
||||||
im = Image.open(HERE / shot).convert("RGB")
|
im = Image.open(HERE / shot).convert("RGB")
|
||||||
h = round(im.height * width / im.width)
|
h = round(im.height * width / im.width)
|
||||||
im = im.resize((width, h), Image.LANCZOS)
|
im = im.resize((width, h), Image.LANCZOS)
|
||||||
pad, radius, shadow = 10, 34, 10
|
pad, radius, shadow = 10, 34, 10
|
||||||
frame = Image.new("RGBA", (width + 2 * pad, h + 2 * pad + shadow), (0, 0, 0, 0))
|
frame = Image.new("RGBA", (width + 2 * pad, h + 2 * pad + shadow), (0, 0, 0, 0))
|
||||||
d = ImageDraw.Draw(frame)
|
d = ImageDraw.Draw(frame)
|
||||||
d.rounded_rectangle((0, shadow, width + 2 * pad - 1, h + 2 * pad + shadow - 1), radius, fill=NEON)
|
d.rounded_rectangle((0, shadow, width + 2 * pad - 1, h + 2 * pad + shadow - 1), radius, fill=neon)
|
||||||
d.rounded_rectangle((0, 0, width + 2 * pad - 1, h + 2 * pad - 1), radius, fill=FG)
|
d.rounded_rectangle((0, 0, width + 2 * pad - 1, h + 2 * pad - 1), radius, fill=fg)
|
||||||
mask = Image.new("L", im.size, 0)
|
mask = Image.new("L", im.size, 0)
|
||||||
ImageDraw.Draw(mask).rounded_rectangle((0, 0, width - 1, h - 1), radius - pad, fill=255)
|
ImageDraw.Draw(mask).rounded_rectangle((0, 0, width - 1, h - 1), radius - pad, fill=255)
|
||||||
frame.paste(im, (pad, pad), mask)
|
frame.paste(im, (pad, pad), mask)
|
||||||
|
|
@ -41,23 +46,23 @@ def phone(shot, width):
|
||||||
|
|
||||||
def portada():
|
def portada():
|
||||||
W, H = 1600, 1100
|
W, H = 1600, 1100
|
||||||
out = Image.new("RGB", (W, H), BG)
|
out = Image.new("RGB", (W, H), DEV_BG)
|
||||||
d = ImageDraw.Draw(out)
|
d = ImageDraw.Draw(out)
|
||||||
d.text((80, 40), "OASIS MOBILE", font=font(ANTON, 92), fill=FG)
|
d.text((80, 40), "OASIS MOBILE", font=font(SANS_BOLD, 84), fill=DEV_FG)
|
||||||
bottom = d.textbbox((80, 40), "OASIS MOBILE", font=font(ANTON, 92))[3]
|
bottom = d.textbbox((80, 40), "OASIS MOBILE", font=font(SANS_BOLD, 84))[3]
|
||||||
d.rectangle((80, bottom + 12, 420, bottom + 20), fill=FG)
|
d.rectangle((80, bottom + 12, 420, bottom + 18), fill=DEV_ACCENT)
|
||||||
d.text((80, 196), "Rama PRUEBAS del hacklab · base Oasis 1.3.3 · tema Acampada, pensado para el pulgar",
|
d.text((80, 186), "Rama PRUEBAS del hacklab · base Oasis 1.3.5 · lo que sale al instalarla",
|
||||||
font=font(SANS, 27), fill=MUTED)
|
font=font(SANS, 27), fill=DEV_MUTED)
|
||||||
shots = [("01-portada.png", "Actividad al abrir"), ("02-tribus.png", "Tribus en filas"),
|
shots = [("01-actividad.png", "Actividad al abrir"), ("02-menu.png", "Menú, perfil Mínimo"),
|
||||||
("03-votacion.png", "Votar en semáforo"), ("07-oasismobile.png", "El menú, tema del dev")]
|
("03-menu-activista.png", "Menú, perfil Activista"), ("04-tribu.png", "Una tribu")]
|
||||||
pw, gap, top = 320, 50, 270
|
pw, gap, top = 320, 50, 260
|
||||||
x = (W - (4 * (pw + 20) + 3 * gap)) // 2
|
x = (W - (4 * (pw + 20) + 3 * gap)) // 2
|
||||||
cap = font(ANTON, 34)
|
cap = font(SANS_BOLD, 26)
|
||||||
for shot, label in shots:
|
for shot, label in shots:
|
||||||
fr = phone(shot, pw)
|
fr = phone(shot, pw, fg="#000000", neon=DEV_ACCENT)
|
||||||
out.paste(fr, (x, top), fr)
|
out.paste(fr, (x, top), fr)
|
||||||
tw = d.textlength(label.upper(), font=cap)
|
tw = d.textlength(label, font=cap)
|
||||||
d.text((x + (fr.width - tw) / 2, top + fr.height + 18), label.upper(), font=cap, fill=FG)
|
d.text((x + (fr.width - tw) / 2, top + fr.height + 18), label, font=cap, fill=DEV_FG)
|
||||||
x += fr.width + gap
|
x += fr.width + gap
|
||||||
out.save(HERE / "00-portada.png", optimize=True)
|
out.save(HERE / "00-portada.png", optimize=True)
|
||||||
|
|
||||||
|
|
@ -202,7 +207,7 @@ def esquema_llamadas():
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
portada()
|
import sys
|
||||||
esquema()
|
# sin argumentos, todo; con nombres, solo esos (p. ej. "portada")
|
||||||
esquema_rama()
|
for name in sys.argv[1:] or ["portada", "esquema", "esquema_rama", "esquema_llamadas"]:
|
||||||
esquema_llamadas()
|
globals()[name]()
|
||||||
|
|
|
||||||
|
|
@ -50,13 +50,7 @@ const mobileLayer = require('./mobile_layer')({ getViewerId, about });
|
||||||
const back = String(body.returnTo || '');
|
const back = String(body.returnTo || '');
|
||||||
ctx.redirect(/^\/(settings|welcome)(#[a-z-]+)?$/.test(back) ? back : '/settings#colors');
|
ctx.redirect(/^\/(settings|welcome)(#[a-z-]+)?$/.test(back) ? back : '/settings#colors');
|
||||||
})
|
})
|
||||||
// barra de unirse a un pub (mobile_pubbar.js): el estado para el script, sin
|
// barra de unirse a un pub (mobile_pubbar.js): cerrar el aviso de terminado
|
||||||
// recargar la pagina, y cerrar el aviso de terminado
|
|
||||||
.get('/mobile/pub-status', async (ctx, next) => {
|
|
||||||
if (!isMobile()) return next();
|
|
||||||
ctx.set('Cache-Control', 'no-store');
|
|
||||||
ctx.body = pubBar.status() || { kind: 'none', running: false };
|
|
||||||
})
|
|
||||||
.post('/mobile/pub-status/dismiss', koaBody(), async (ctx, next) => {
|
.post('/mobile/pub-status/dismiss', koaBody(), async (ctx, next) => {
|
||||||
if (!isMobile()) return next();
|
if (!isMobile()) return next();
|
||||||
pubBar.dismiss();
|
pubBar.dismiss();
|
||||||
|
|
|
||||||
|
|
@ -51,9 +51,16 @@ module.exports = ({ getViewerId, about }) => {
|
||||||
// el lanzador ya no va en la portada: la portada es la actividad y los modulos
|
// el lanzador ya no va en la portada: la portada es la actividad y los modulos
|
||||||
// estan en la hoja de la pestaña Menu (docs/ESTUDIO_NAVEGACION.md)
|
// estan en la hoja de la pestaña Menu (docs/ESTUDIO_NAVEGACION.md)
|
||||||
global.__OASIS_SHOW_HIVE__ = false;
|
global.__OASIS_SHOW_HIVE__ = false;
|
||||||
// en Ajustes el nombre y el avatar se leen al momento (se acaban de cambiar en
|
// comentarios abiertos en las fichas: plegados, la caja de comentar iba tras un
|
||||||
// /profile/edit, la pantalla del dev); en el resto, como mucho cada minuto
|
// "✑(0)" sin texto y quien comentaba no veia el suyo al volver. Es la opcion del dev
|
||||||
if (!avatarAt || ctx.path === '/settings') await refreshAvatar();
|
// para ?comments=open (comments_view.setCommentsOpen). En el parlamento hay un bloque
|
||||||
|
// por propuesta en la lista: ahi se quedan plegados
|
||||||
|
if (ctx.method === 'GET' && !ctx.path.startsWith('/parliament')) {
|
||||||
|
try { require('../views/comments_view').setCommentsOpen(true); } catch (_) {}
|
||||||
|
}
|
||||||
|
// en Ajustes y en el perfil (adonde vuelve el dev tras /profile/edit) el nombre y el
|
||||||
|
// avatar se leen al momento; en el resto, como mucho cada minuto
|
||||||
|
if (!avatarAt || ctx.path === '/settings' || ctx.path === '/profile') await refreshAvatar();
|
||||||
else if (Date.now() - avatarAt > 60000) refreshAvatar();
|
else if (Date.now() - avatarAt > 60000) refreshAvatar();
|
||||||
return next();
|
return next();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
1
src/client/assets/images/mobile-ico-actualizar.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v12"/><path d="M7 10l5 5 5-5"/><path d="M4 17v3h16v-3"/></svg>
|
||||||
|
After Width: | Height: | Size: 227 B |
1
src/client/assets/images/mobile-ico-cifrado.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/></svg>
|
||||||
|
After Width: | Height: | Size: 242 B |
1
src/client/assets/images/mobile-ico-compartir.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 15V3"/><path d="M8 7l4-4 4 4"/><path d="M5 12v8h14v-8"/></svg>
|
||||||
|
After Width: | Height: | Size: 226 B |
1
src/client/assets/images/mobile-ico-enviar.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l16-8-6 16-3-7z"/></svg>
|
||||||
|
After Width: | Height: | Size: 189 B |
1
src/client/assets/images/mobile-ico-licencia.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3h8l4 4v14H6z"/><path d="M14 3v4h4"/><path d="M9 12h6M9 16h6"/></svg>
|
||||||
|
After Width: | Height: | Size: 232 B |
1
src/client/assets/images/mobile-ico-mutuos.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="8" r="3"/><path d="M3 20a6 6 0 0 1 12 0"/><circle cx="17" cy="9" r="2.5"/><path d="M16 14a5 5 0 0 1 5 5"/></svg>
|
||||||
|
After Width: | Height: | Size: 282 B |
1
src/client/assets/images/mobile-ico-publico.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M3 12h18"/><path d="M12 3a14 14 0 0 1 0 18a14 14 0 0 1 0-18z"/></svg>
|
||||||
|
After Width: | Height: | Size: 260 B |
1
src/client/assets/images/mobile-ico-red.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="12" r="2.5"/><circle cx="18" cy="6" r="2.5"/><circle cx="18" cy="18" r="2.5"/><path d="M8.3 11l7.4-3.8M8.3 13l7.4 3.8"/></svg>
|
||||||
|
After Width: | Height: | Size: 296 B |
1
src/client/assets/images/mobile-ico-responder.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 7L4 12l5 5"/><path d="M4 12h10a6 6 0 0 1 6 6v1"/></svg>
|
||||||
|
After Width: | Height: | Size: 218 B |
1
src/client/assets/images/mobile-ico-sugerencia.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M10 8l4 4-4 4"/></svg>
|
||||||
|
After Width: | Height: | Size: 213 B |
1
src/client/assets/images/mobile-ico-tiempo.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>
|
||||||
|
After Width: | Height: | Size: 211 B |
1
src/client/assets/images/mobile-ico-tribu.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 4L3 20h18z"/><path d="M12 4v16"/><path d="M9 20l3-5 3 5"/></svg>
|
||||||
|
After Width: | Height: | Size: 228 B |
1
src/client/assets/images/mobile-phone-dnd.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 3h4l2 5-2.5 1.5a11 11 0 0 0 6 6L16 13l5 2v4a2 2 0 0 1-2 2A17 17 0 0 1 3 5a2 2 0 0 1 2-2z"/><path d="M22 2L2 22"/></svg>
|
||||||
|
After Width: | Height: | Size: 282 B |
1
src/client/assets/images/mobile-phone.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 3h4l2 5-2.5 1.5a11 11 0 0 0 6 6L16 13l5 2v4a2 2 0 0 1-2 2A17 17 0 0 1 3 5a2 2 0 0 1 2-2z"/></svg>
|
||||||
|
After Width: | Height: | Size: 260 B |
|
|
@ -799,7 +799,7 @@ body { padding-top: 74px; } /* espejo { display: contents; }
|
||||||
min-height: 0 !important; padding: 0 !important; gap: 0 !important;
|
min-height: 0 !important; padding: 0 !important; gap: 0 !important;
|
||||||
z-index: auto !important;
|
z-index: auto !important;
|
||||||
}
|
}
|
||||||
body:has(.oasis-nav-side-toggle) { padding-top: 84px !important; }
|
body:has(.oasis-nav-side-toggle) { padding-top: 74px !important; }
|
||||||
.oasis-nav-side-toggle ~ .header .oasis-mobile-menus,
|
.oasis-nav-side-toggle ~ .header .oasis-mobile-menus,
|
||||||
.oasis-nav-side-toggle ~ .header .top-bar-left nav,
|
.oasis-nav-side-toggle ~ .header .top-bar-left nav,
|
||||||
.oasis-nav-side-toggle ~ .header .top-bar-right nav,
|
.oasis-nav-side-toggle ~ .header .top-bar-right nav,
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@
|
||||||
.welcome-banner .welcome-banner-close { position: absolute !important; top: 0 !important; right: 0 !important; margin: 0 !important; }
|
.welcome-banner .welcome-banner-close { position: absolute !important; top: 0 !important; right: 0 !important; margin: 0 !important; }
|
||||||
.welcome-banner .welcome-banner-close-btn {
|
.welcome-banner .welcome-banner-close-btn {
|
||||||
min-height: 44px !important; height: 44px !important; width: 44px !important; padding: 0 !important; margin: 0 !important;
|
min-height: 44px !important; height: 44px !important; width: 44px !important; padding: 0 !important; margin: 0 !important;
|
||||||
font-size: 16px !important; color: var(--ux-muted) !important;
|
font-size: 16px !important; color: var(--ux-fg) !important; /* el gris sobre el tinte del banner no llegaba a 4,5 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- pie de una linea ---------- */
|
/* ---------- pie de una linea ---------- */
|
||||||
|
|
@ -322,6 +322,10 @@ a:focus-visible, button:focus-visible, summary:focus-visible, label.module-switc
|
||||||
por lado) y el texto de una votacion o una tribu se quedaba en 264 de 412px */
|
por lado) y el texto de una votacion o una tribu se quedaba en 264 de 412px */
|
||||||
body .main-content { padding-left: 14px !important; padding-right: 14px !important; }
|
body .main-content { padding-left: 14px !important; padding-right: 14px !important; }
|
||||||
body .main-content > .main-column { padding-left: 0 !important; padding-right: 0 !important; }
|
body .main-content > .main-column { padding-left: 0 !important; padding-right: 0 !important; }
|
||||||
|
/* y arriba: la barra fija ya deja su holgura (body 74px); con los 20+10 de contenido y
|
||||||
|
columna habia 67px vacios antes del titulo de cada pantalla */
|
||||||
|
body .main-content { padding-top: 6px !important; }
|
||||||
|
body .main-content > .main-column { padding-top: 0 !important; }
|
||||||
.main-column :is(.tribe-details, .tribe-side, .tribe-main, .job-section, .vote-form, .tribe-content) {
|
.main-column :is(.tribe-details, .tribe-side, .tribe-main, .job-section, .vote-form, .tribe-content) {
|
||||||
padding-left: 0 !important; padding-right: 0 !important; margin-left: 0 !important; margin-right: 0 !important;
|
padding-left: 0 !important; padding-right: 0 !important; margin-left: 0 !important; margin-right: 0 !important;
|
||||||
width: 100% !important; max-width: 100% !important; box-sizing: border-box;
|
width: 100% !important; max-width: 100% !important; box-sizing: border-box;
|
||||||
|
|
@ -479,13 +483,33 @@ form.oasis-phone-state {
|
||||||
/* mobile.css lo fija con .oasis-nav-side-toggle ~ .header ...: hace falta mas especificidad */
|
/* mobile.css lo fija con .oasis-nav-side-toggle ~ .header ...: hace falta mas especificidad */
|
||||||
form.oasis-phone-state .oasis-phone-state-btn,
|
form.oasis-phone-state .oasis-phone-state-btn,
|
||||||
body .oasis-nav-side-toggle ~ .header form.oasis-phone-state .oasis-phone-state-btn,
|
body .oasis-nav-side-toggle ~ .header form.oasis-phone-state .oasis-phone-state-btn,
|
||||||
body form.oasis-phone-state button.oasis-phone-state-btn.pm-exposition-chip {
|
body form.oasis-phone-state button.oasis-phone-state-btn.pm-exposition-chip[type] {
|
||||||
min-width: 44px !important; max-width: 44px !important; max-height: 44px !important;
|
min-width: 44px !important; max-width: 44px !important; max-height: 44px !important;
|
||||||
width: 44px !important; height: 44px !important; min-height: 44px !important; padding: 0 !important; margin: 0 !important;
|
width: 44px !important; height: 44px !important; min-height: 44px !important; padding: 0 !important; margin: 0 !important;
|
||||||
display: inline-flex !important; align-items: center; justify-content: center;
|
display: inline-flex !important; align-items: center; justify-content: center;
|
||||||
border-radius: 50% !important; box-shadow: none !important; font-size: 20px !important;
|
border-radius: 50% !important; box-shadow: none !important; font-size: 20px !important;
|
||||||
}
|
}
|
||||||
.oasis-mobile-topbar .omt-menus { padding-right: 46px; }
|
.oasis-mobile-topbar .omt-menus { padding-right: 180px; }
|
||||||
|
/* el boton era un disco amarillo con un ✆ de fuente: parecia "llamar" y es el estado
|
||||||
|
del telefono (si saltan las llamadas o no). Pastilla con borde, icono dibujado y el
|
||||||
|
nombre del estado, que es el title del dev ya traducido. En No molestar (la clase
|
||||||
|
pm-exposition-hidden), rellena y con el telefono tachado. Solo CSS */
|
||||||
|
body form.oasis-phone-state button.oasis-phone-state-btn.pm-exposition-chip[type] {
|
||||||
|
width: auto !important; max-width: 180px !important; min-width: 44px !important; padding: 0 12px 0 10px !important;
|
||||||
|
border-radius: 22px !important; border: 1px solid var(--ux-line) !important;
|
||||||
|
background: var(--ux-bg) !important; color: var(--ux-fg) !important;
|
||||||
|
font-family: var(--ux-text) !important; font-size: 13px !important; font-weight: 600 !important; letter-spacing: 0 !important; text-transform: none !important;
|
||||||
|
}
|
||||||
|
body form.oasis-phone-state button.oasis-phone-state-btn > .pm-exposition-icon { display: none !important; }
|
||||||
|
body form.oasis-phone-state button.oasis-phone-state-btn::before {
|
||||||
|
content: ""; flex: 0 0 auto; width: 18px; height: 18px; margin-right: 6px; background-color: currentColor;
|
||||||
|
-webkit-mask: url(/assets/images/mobile-phone.svg) center / contain no-repeat; mask: url(/assets/images/mobile-phone.svg) center / contain no-repeat;
|
||||||
|
}
|
||||||
|
body form.oasis-phone-state button.oasis-phone-state-btn[title]::after { content: attr(title); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
|
||||||
|
body form.oasis-phone-state button.oasis-phone-state-btn.pm-exposition-chip.pm-exposition-hidden[type] { background: var(--ux-accent) !important; color: var(--ux-on-accent) !important; border-color: var(--ux-accent) !important; }
|
||||||
|
body form.oasis-phone-state button.oasis-phone-state-btn.pm-exposition-hidden::before {
|
||||||
|
-webkit-mask-image: url(/assets/images/mobile-phone-dnd.svg); mask-image: url(/assets/images/mobile-phone-dnd.svg);
|
||||||
|
}
|
||||||
|
|
||||||
/* barras de la votacion: juntas, y las etiquetas del dev (CONFUNDIDO, SEGUIR
|
/* barras de la votacion: juntas, y las etiquetas del dev (CONFUNDIDO, SEGUIR
|
||||||
MAYORIA) en el mismo tipo que las nuestras (Si, No) */
|
MAYORIA) en el mismo tipo que las nuestras (Si, No) */
|
||||||
|
|
@ -537,15 +561,16 @@ body > .welcome-banner { order: -1; margin-top: 10px !important; }
|
||||||
|
|
||||||
/* ---------- pestaña Menu y su hoja con todos los modulos ---------- */
|
/* ---------- pestaña Menu y su hoja con todos los modulos ---------- */
|
||||||
/* la portada es la actividad; los modulos se abren desde abajo, como el "Mas" de
|
/* la portada es la actividad; los modulos se abren desde abajo, como el "Mas" de
|
||||||
Android (docs/ESTUDIO_NAVEGACION.md). Una casilla oculta abre y cierra la hoja */
|
Android (docs/ESTUDIO_NAVEGACION.md). La abre el ancla #oasis-menu (:target) y la
|
||||||
.oasis-bottombar input.menu-toggle { position: absolute; opacity: 0; width: 0 !important; height: 0 !important; min-height: 0 !important; pointer-events: none; }
|
cierra cualquier otra; con la hoja abierta, la pestaña Menu es la de cerrar */
|
||||||
.oasis-bottombar label.bb-menu { cursor: pointer; }
|
.oasis-bottombar a.bb-menu-close, .oasis-bottombar:target a.bb-menu:not(.bb-menu-close) { display: none !important; }
|
||||||
.oasis-bottombar .menu-toggle:checked ~ label.bb-menu .bb-ico.has-svg { background: var(--ux-accent) !important; color: var(--ux-on-accent) !important; }
|
.oasis-bottombar:target a.bb-menu-close { display: flex !important; }
|
||||||
|
.oasis-bottombar:target a.bb-menu-close .bb-ico.has-svg { background: var(--ux-accent) !important; color: var(--ux-on-accent) !important; }
|
||||||
.oasis-bottombar .menu-sheet, .oasis-bottombar .menu-sheet-backdrop { display: none; }
|
.oasis-bottombar .menu-sheet, .oasis-bottombar .menu-sheet-backdrop { display: none; }
|
||||||
.oasis-bottombar .menu-toggle:checked ~ .menu-sheet-backdrop {
|
.oasis-bottombar:target .menu-sheet-backdrop {
|
||||||
display: block; position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 1002; background: rgba(0, 0, 0, .45);
|
display: block; position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 1002; background: rgba(0, 0, 0, .45);
|
||||||
}
|
}
|
||||||
.oasis-bottombar .menu-toggle:checked ~ .menu-sheet {
|
.oasis-bottombar:target .menu-sheet {
|
||||||
display: block; position: fixed; left: 0; right: 0; z-index: 1003;
|
display: block; position: fixed; left: 0; right: 0; z-index: 1003;
|
||||||
bottom: 0; max-height: 82vh; max-height: 82dvh; overflow-y: auto; overscroll-behavior: contain;
|
bottom: 0; max-height: 82vh; max-height: 82dvh; overflow-y: auto; overscroll-behavior: contain;
|
||||||
padding: 8px 14px calc(18px + var(--inset-bottom));
|
padding: 8px 14px calc(18px + var(--inset-bottom));
|
||||||
|
|
@ -570,9 +595,9 @@ body > .welcome-banner { order: -1; margin-top: 10px !important; }
|
||||||
/* cinco pestañas: que quepan a 360px */
|
/* cinco pestañas: que quepan a 360px */
|
||||||
.oasis-bottombar .bb-item { flex: 1 1 0 !important; min-width: 0 !important; }
|
.oasis-bottombar .bb-item { flex: 1 1 0 !important; min-width: 0 !important; }
|
||||||
@media (max-width: 380px) { .oasis-bottombar .bb-lbl { font-size: 11px !important; } }
|
@media (max-width: 380px) { .oasis-bottombar .bb-lbl { font-size: 11px !important; } }
|
||||||
.oasis-bottombar .menu-toggle:checked ~ div.menu-sheet { background: var(--ux-bg) !important; bottom: calc(66px + var(--inset-bottom)); border-radius: 22px 22px 0 0 !important; border: 0 !important; border-top: 1px solid var(--ux-line) !important; }
|
.oasis-bottombar:target div.menu-sheet { background: var(--ux-bg) !important; bottom: calc(66px + var(--inset-bottom)); border-radius: 22px 22px 0 0 !important; border: 0 !important; border-top: 1px solid var(--ux-line) !important; }
|
||||||
.oasis-bottombar div.menu-sheet-head { background: var(--ux-bg) !important; border: 0 !important; border-bottom: 1px solid var(--ux-line) !important; }
|
.oasis-bottombar div.menu-sheet-head { background: var(--ux-bg) !important; border: 0 !important; border-bottom: 1px solid var(--ux-line) !important; }
|
||||||
.oasis-bottombar .menu-toggle:checked ~ .menu-sheet-backdrop { bottom: calc(66px + var(--inset-bottom)); }
|
.oasis-bottombar:target .menu-sheet-backdrop { bottom: calc(66px + var(--inset-bottom)); }
|
||||||
/* en la hoja todo tiene que caber sin deslizar: cinco iconos por fila y mas pequeños
|
/* en la hoja todo tiene que caber sin deslizar: cinco iconos por fila y mas pequeños
|
||||||
(con 20 modulos la rejilla del lanzador medía 1.200px para 690 de hoja) */
|
(con 20 modulos la rejilla del lanzador medía 1.200px para 690 de hoja) */
|
||||||
.menu-sheet .launcher .ln-grid { display: grid !important; grid-template-columns: repeat(5, 1fr) !important; gap: 8px 2px !important; }
|
.menu-sheet .launcher .ln-grid { display: grid !important; grid-template-columns: repeat(5, 1fr) !important; gap: 8px 2px !important; }
|
||||||
|
|
@ -582,7 +607,7 @@ body > .welcome-banner { order: -1; margin-top: 10px !important; }
|
||||||
.menu-sheet .launcher .ln-title { font-size: 15px !important; margin: 0 0 6px !important; padding: 0 0 2px !important; border-bottom-width: 2px !important; }
|
.menu-sheet .launcher .ln-title { font-size: 15px !important; margin: 0 0 6px !important; padding: 0 0 2px !important; border-bottom-width: 2px !important; }
|
||||||
.menu-sheet .launcher .ln-group + .ln-group { margin-top: 10px !important; }
|
.menu-sheet .launcher .ln-group + .ln-group { margin-top: 10px !important; }
|
||||||
/* con el menu abierto, solo Menu lleva la pastilla */
|
/* con el menu abierto, solo Menu lleva la pastilla */
|
||||||
.oasis-bottombar .menu-toggle:checked ~ a.bb-item.current .bb-ico.has-svg { background: transparent !important; color: var(--ux-fg) !important; }
|
.oasis-bottombar:target a.bb-item.current .bb-ico.has-svg { background: transparent !important; color: var(--ux-fg) !important; }
|
||||||
/* los grupos de uno o dos modulos (Biblioteca, Oficina, Gobernanza...) van de dos en
|
/* los grupos de uno o dos modulos (Biblioteca, Oficina, Gobernanza...) van de dos en
|
||||||
dos, uno al lado del otro; los grandes ocupan el ancho. Hace falta :has(): en los
|
dos, uno al lado del otro; los grandes ocupan el ancho. Hace falta :has(): en los
|
||||||
WebView viejos (Android 9-11 sin actualizar) cada grupo va a lo ancho */
|
WebView viejos (Android 9-11 sin actualizar) cada grupo va a lo ancho */
|
||||||
|
|
@ -594,7 +619,7 @@ body > .welcome-banner { order: -1; margin-top: 10px !important; }
|
||||||
.menu-sheet .launcher .ln-group:not(:has(.ln-app:nth-child(3))) .ln-grid { grid-template-columns: 1fr 1fr !important; }
|
.menu-sheet .launcher .ln-group:not(:has(.ln-app:nth-child(3))) .ln-grid { grid-template-columns: 1fr 1fr !important; }
|
||||||
}
|
}
|
||||||
/* con el menu abierto, el boton de No molestar no se monta encima de la hoja */
|
/* con el menu abierto, el boton de No molestar no se monta encima de la hoja */
|
||||||
body:has(#oasis-menu-toggle:checked) form.oasis-phone-state { display: none !important; }
|
body:has(#oasis-menu:target) form.oasis-phone-state { display: none !important; }
|
||||||
|
|
||||||
/* ---------- tipo de portada: un toque y guardado ---------- */
|
/* ---------- tipo de portada: un toque y guardado ---------- */
|
||||||
/* bienvenida y Ajustes: cada opcion es un boton. En el movil, una fila por opcion con
|
/* bienvenida y Ajustes: cada opcion es un boton. En el movil, una fila por opcion con
|
||||||
|
|
@ -635,7 +660,10 @@ body:has(#oasis-menu-toggle:checked) form.oasis-phone-state { display: none !imp
|
||||||
/* ---------- Ajustes: los seis accesos de arriba (mobile_settings.js) ---------- */
|
/* ---------- Ajustes: los seis accesos de arriba (mobile_settings.js) ---------- */
|
||||||
/* rejilla de 3x2 a 360px: icono, nombre y lo que hay puesto. Cada acceso baja a su
|
/* rejilla de 3x2 a 360px: icono, nombre y lo que hay puesto. Cada acceso baja a su
|
||||||
bloque, que se para debajo de la barra de arriba (67px) */
|
bloque, que se para debajo de la barra de arriba (67px) */
|
||||||
.main-column section[id] { scroll-margin-top: calc(76px + var(--inset-top)); }
|
.main-column section[id], #tribe-tabs, #comments, #comments-latest { scroll-margin-top: calc(76px + var(--inset-top)); }
|
||||||
|
/* pestañas de tribu: el dev mezcla "Habitantes" y "GOBIERNO"; todas en mayusculas,
|
||||||
|
como las fichas de filtro (::first-letter no va en un inline-flex) */
|
||||||
|
.main-column a.tribe-tab, .main-column details.tribe-tabs-more > summary { text-transform: uppercase !important; font-size: 13px !important; letter-spacing: 0 !important; padding: 4px 6px !important; }
|
||||||
.main-column div.quick-grid { display: grid !important; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-gap: 10px; margin: 0 0 6px !important; padding: 0 !important; }
|
.main-column div.quick-grid { display: grid !important; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-gap: 10px; margin: 0 0 6px !important; padding: 0 !important; }
|
||||||
.main-column a.quick-tile {
|
.main-column a.quick-tile {
|
||||||
display: flex !important; flex-direction: column; align-items: center; justify-content: flex-start; text-align: center;
|
display: flex !important; flex-direction: column; align-items: center; justify-content: flex-start; text-align: center;
|
||||||
|
|
@ -715,7 +743,7 @@ body:has(#oasis-menu-toggle:checked) form.oasis-phone-state { display: none !imp
|
||||||
}
|
}
|
||||||
.main-column .mobile-filter > label.mobile-filter-btn::after { content: "\25BE"; margin-left: 8px; font-size: 16px; }
|
.main-column .mobile-filter > label.mobile-filter-btn::after { content: "\25BE"; margin-left: 8px; font-size: 16px; }
|
||||||
.main-column .mobile-filter > input:checked + label.mobile-filter-btn::after { content: "\25B4"; }
|
.main-column .mobile-filter > input:checked + label.mobile-filter-btn::after { content: "\25B4"; }
|
||||||
.main-column .mobile-filter.is-filtered > label.mobile-filter-btn { background: var(--ux-accent); color: var(--ux-on-accent); border-color: var(--ux-accent); }
|
.main-column .mobile-filter.is-filtered > label.mobile-filter-btn { background: var(--ux-accent) !important; color: var(--ux-on-accent) !important; border-color: var(--ux-accent) !important; }
|
||||||
.main-column .mobile-filter .activity-filter-now { margin-left: 8px; font-weight: 400; text-transform: none; letter-spacing: 0; }
|
.main-column .mobile-filter .activity-filter-now { margin-left: 8px; font-weight: 400; text-transform: none; letter-spacing: 0; }
|
||||||
.main-column .mobile-filter .activity-filter-now::before { content: "\00B7"; margin-right: 8px; }
|
.main-column .mobile-filter .activity-filter-now::before { content: "\00B7"; margin-right: 8px; }
|
||||||
.main-column .mobile-filter > div.mobile-filter-chips { display: none !important; }
|
.main-column .mobile-filter > div.mobile-filter-chips { display: none !important; }
|
||||||
|
|
@ -765,9 +793,9 @@ nav.oasis-bottombar div.pub-bar div.pub-bar-body { flex: 1 1 auto; min-width: 0;
|
||||||
.pub-bar .pub-bar-close button { min-width: 44px; min-height: 44px !important; padding: 0 !important; margin: 0 !important; border: 0 !important; background: transparent !important; color: var(--ux-fg) !important; font-size: 18px !important; }
|
.pub-bar .pub-bar-close button { min-width: 44px; min-height: 44px !important; padding: 0 !important; margin: 0 !important; border: 0 !important; background: transparent !important; color: var(--ux-fg) !important; font-size: 18px !important; }
|
||||||
.pub-bar[data-running="1"] .pub-bar-close { display: none; }
|
.pub-bar[data-running="1"] .pub-bar-close { display: none; }
|
||||||
/* que la barra no tape lo ultimo de la pagina */
|
/* que la barra no tape lo ultimo de la pagina */
|
||||||
body.has-pub-bar { padding-bottom: calc(190px + var(--inset-bottom)) !important; }
|
body:has(div.pub-bar) { padding-bottom: calc(190px + var(--inset-bottom)) !important; }
|
||||||
/* con el menu abierto, la barra se va */
|
/* con el menu abierto, la barra se va */
|
||||||
body:has(#oasis-menu-toggle:checked) .pub-bar { display: none !important; }
|
body:has(#oasis-menu:target) .pub-bar { display: none !important; }
|
||||||
|
|
||||||
/* ---------- zonas tactiles (pruebas de usabilidad del 20/10) ---------- */
|
/* ---------- zonas tactiles (pruebas de usabilidad del 20/10) ---------- */
|
||||||
/* en el Pixel 9 se midieron por debajo de 44px: logo y avatar de la barra de arriba
|
/* en el Pixel 9 se midieron por debajo de 44px: logo y avatar de la barra de arriba
|
||||||
|
|
@ -802,7 +830,7 @@ body .oasis-mobile-topbar .omt-logo img, body .oasis-mobile-topbar .omt-avatar i
|
||||||
@media (min-width: 700px) {
|
@media (min-width: 700px) {
|
||||||
body .main-content { max-width: 720px !important; margin-left: auto !important; margin-right: auto !important; width: 100% !important; box-sizing: border-box; }
|
body .main-content { max-width: 720px !important; margin-left: auto !important; margin-right: auto !important; width: 100% !important; box-sizing: border-box; }
|
||||||
body > .welcome-banner { width: calc(100% - 28px) !important; max-width: 692px !important; margin-left: auto !important; margin-right: auto !important; box-sizing: border-box; }
|
body > .welcome-banner { width: calc(100% - 28px) !important; max-width: 692px !important; margin-left: auto !important; margin-right: auto !important; box-sizing: border-box; }
|
||||||
.oasis-bottombar .menu-toggle:checked ~ div.menu-sheet { left: 50%; right: auto; width: 640px; margin-left: -320px; }
|
.oasis-bottombar:target div.menu-sheet { left: 50%; right: auto; width: 640px; margin-left: -320px; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- WebView viejos ---------- */
|
/* ---------- WebView viejos ---------- */
|
||||||
|
|
@ -841,7 +869,7 @@ body .oasis-mobile-topbar .omt-logo img, body .oasis-mobile-topbar .omt-avatar i
|
||||||
.main-column div.apk-modbar .apk-pin { margin: 0 0 0 10px !important; width: auto !important; flex: 0 0 auto; }
|
.main-column div.apk-modbar .apk-pin { margin: 0 0 0 10px !important; width: auto !important; flex: 0 0 auto; }
|
||||||
/* las fichas de la cabecera en rejilla de tres columnas, sin deslizar de lado */
|
/* las fichas de la cabecera en rejilla de tres columnas, sin deslizar de lado */
|
||||||
.main-column div.apk-modbar > .apk-strip:not(.mobile-filter) {
|
.main-column div.apk-modbar > .apk-strip:not(.mobile-filter) {
|
||||||
display: grid !important; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-gap: 8px;
|
display: grid !important; grid-template-columns: repeat(3, minmax(0, 1fr)) !important; grid-gap: 8px;
|
||||||
overflow: visible !important; margin: 0 0 10px !important; padding: 0 !important; white-space: normal !important;
|
overflow: visible !important; margin: 0 0 10px !important; padding: 0 !important; white-space: normal !important;
|
||||||
}
|
}
|
||||||
.main-column div.apk-modbar > .apk-strip:not(.mobile-filter) > *,
|
.main-column div.apk-modbar > .apk-strip:not(.mobile-filter) > *,
|
||||||
|
|
@ -859,6 +887,14 @@ body .oasis-mobile-topbar .omt-logo img, body .oasis-mobile-topbar .omt-avatar i
|
||||||
/* la seccion que se queda vacia cuando la cabecera se lleva las fichas y el buscador */
|
/* la seccion que se queda vacia cuando la cabecera se lleva las fichas y el buscador */
|
||||||
.main-column > section:empty, .main-column div.activity-toolbar-row:empty { display: none !important; }
|
.main-column > section:empty, .main-column div.activity-toolbar-row:empty { display: none !important; }
|
||||||
.main-column > section > div.activity-toolbar-row:only-child:empty { display: none !important; }
|
.main-column > section > div.activity-toolbar-row:only-child:empty { display: none !important; }
|
||||||
|
.main-column > section:has(> div.activity-toolbar-row:only-child:empty) { display: none !important; }
|
||||||
|
/* las secciones del dev llevan 16px arriba y 20 abajo; en columna flex no se juntan */
|
||||||
|
.main-column > section { margin-top: 0 !important; }
|
||||||
|
/* cuatro fichas (todas, recientes, mias, top): en una fila, no tres y una suelta.
|
||||||
|
Sin :has (WebView viejo) se quedan en tres y una */
|
||||||
|
.main-column div.apk-modbar > .apk-strip:not(.mobile-filter) > form:only-child:has(> button:first-child:nth-last-child(4)) { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; }
|
||||||
|
.main-column div.apk-modbar > .apk-strip:not(.mobile-filter) > form:only-child > button:first-child:nth-last-child(4),
|
||||||
|
.main-column div.apk-modbar > .apk-strip:not(.mobile-filter) > form:only-child > button:first-child:nth-last-child(4) ~ button { padding: 4px 2px !important; font-size: 13px !important; }
|
||||||
|
|
||||||
/* cabecera de tarjeta de la 1.3.5: autoria a la izquierda (nombre cortado con ...) y
|
/* cabecera de tarjeta de la 1.3.5: autoria a la izquierda (nombre cortado con ...) y
|
||||||
el menu ⋯ y la flecha juntos a la derecha. Pisa lo de la 1.3.3 (columna) */
|
el menu ⋯ y la flecha juntos a la derecha. Pisa lo de la 1.3.3 (columna) */
|
||||||
|
|
@ -878,7 +914,7 @@ body .oasis-mobile-topbar .omt-logo img, body .oasis-mobile-topbar .omt-avatar i
|
||||||
.main-column div.card-chips-row > * { margin: 0 6px 6px 0 !important; }
|
.main-column div.card-chips-row > * { margin: 0 6px 6px 0 !important; }
|
||||||
/* algunas tiras son un solo formulario con todos los botones (Eventos): la rejilla va dentro */
|
/* algunas tiras son un solo formulario con todos los botones (Eventos): la rejilla va dentro */
|
||||||
.main-column div.apk-modbar > .apk-strip:not(.mobile-filter) > form:only-child {
|
.main-column div.apk-modbar > .apk-strip:not(.mobile-filter) > form:only-child {
|
||||||
grid-column: 1 / -1; display: grid !important; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-gap: 8px;
|
grid-column: 1 / -1; display: grid !important; grid-template-columns: repeat(3, minmax(0, 1fr)) !important; grid-gap: 8px;
|
||||||
min-height: 0 !important; padding: 0 !important;
|
min-height: 0 !important; padding: 0 !important;
|
||||||
}
|
}
|
||||||
.main-column div.apk-modbar > .apk-strip:not(.mobile-filter) > form:only-child > button { min-height: 44px !important; margin: 0 !important; }
|
.main-column div.apk-modbar > .apk-strip:not(.mobile-filter) > form:only-child > button { min-height: 44px !important; margin: 0 !important; }
|
||||||
|
|
@ -943,3 +979,183 @@ html[lang="ar"] .main-column input, html[lang="ar"] .main-column textarea { dire
|
||||||
}
|
}
|
||||||
.main-column div.card-header.card-top > div.content-actions { padding-bottom: 32px !important; }
|
.main-column div.card-header.card-top > div.content-actions { padding-bottom: 32px !important; }
|
||||||
.main-column div.content-actions > * + * { margin-left: 28px !important; }
|
.main-column div.content-actions > * + * { margin-left: 28px !important; }
|
||||||
|
|
||||||
|
/* ---------- zonas tactiles y letra que quedaban cortas (pruebas del 20/10) ---------- */
|
||||||
|
.main-column a.card-byline-avatar { display: inline-flex !important; align-items: center; justify-content: center; min-width: 44px !important; min-height: 44px !important; }
|
||||||
|
.main-column a.share-summary-link, .main-column summary.comments-summary, .main-column summary.opinions-summary,
|
||||||
|
.main-column summary.tribe-members-count, .main-column a.larp-my-house-link, .main-column a.wallet-chip-link, .main-column a.graphos-zoom-btn, .main-column a.update-download-link {
|
||||||
|
display: inline-flex !important; align-items: center; min-height: 44px !important; box-sizing: border-box;
|
||||||
|
}
|
||||||
|
/* enlace de wiki a una pagina que no existe: va en el texto, 24px como los demas */
|
||||||
|
.main-column a.wiki-link { display: inline-block; min-height: 24px; line-height: 24px; }
|
||||||
|
/* etiquetas de 10-11px del dev (melodia, parlamento y gobierno de tribu, perfil) */
|
||||||
|
.main-column .melody-note-type, .main-column .kpi__label, .main-column .inhabitant-stat-label { font-size: 12px !important; }
|
||||||
|
/* casilla dentro de su etiqueta (permitir comentarios): se toca la etiqueta entera */
|
||||||
|
.main-column form label:not([class]) { display: inline-flex; align-items: center; min-height: 44px; }
|
||||||
|
/* el nombre en la ficha de habitante (mobile_base lo deja en linea, 18px) */
|
||||||
|
.main-column p.inhabitant-left-name > a.user-link { display: inline-block; min-height: 24px; line-height: 24px; }
|
||||||
|
.main-column .profile-side-mention > a { display: inline-flex; align-items: center; min-height: 44px; max-width: 100%; }
|
||||||
|
.main-column .profile-side-mention > a > strong { min-width: 0; overflow-wrap: anywhere; word-break: break-all; }
|
||||||
|
|
||||||
|
/* colores fijos de style.css que no siguen la paleta: con Papel, Lila o Bosque el nombre
|
||||||
|
de la tarjeta (#FFD700), el telefono (fondo #1A1A1A) y el chip "Tu" (#2a2a2a) quedaban
|
||||||
|
a contraste 1,0-1,4 */
|
||||||
|
.main-column .card-byline a.user-link { color: var(--ux-fg) !important; }
|
||||||
|
.main-column div.wallet-line { background: var(--ux-bg) !important; color: var(--ux-fg) !important; }
|
||||||
|
.main-column div.wallet-line .wallet-address { color: var(--ux-fg) !important; }
|
||||||
|
.main-column span.status.you { background: var(--ux-accent) !important; color: var(--ux-on-accent) !important; }
|
||||||
|
|
||||||
|
/* Actividad con un modulo filtrado: las fichas que llevan a ese modulo (todas,
|
||||||
|
recientes, mias, top) en una fila, no una por fila. La flecha sobra */
|
||||||
|
.main-column div.activity-toolbar-row { display: flex !important; flex-direction: row !important; flex-wrap: wrap !important; align-items: center !important; gap: 0 !important; width: auto !important; margin: 0 -4px 8px !important; padding: 0 !important; }
|
||||||
|
.main-column div.activity-toolbar-row > span.activity-subchip-label { display: none !important; }
|
||||||
|
.main-column div.activity-toolbar-row > a.activity-chip {
|
||||||
|
display: inline-flex !important; flex: 1 1 0 !important; width: auto !important; min-width: 0 !important; justify-content: center; align-items: center;
|
||||||
|
min-height: 44px !important; margin: 0 4px 8px !important; padding: 4px 2px !important; font-size: 13px !important;
|
||||||
|
}
|
||||||
|
.main-column div.activity-toolbar-row > :not(a):not(span.activity-subchip-label) { flex: 1 1 100%; margin-left: 4px !important; margin-right: 4px !important; }
|
||||||
|
|
||||||
|
/* Habitantes: la ficha del dev va dentro de otra tarjeta; la de dentro sin marco */
|
||||||
|
.main-column div.trending-card div.inhabitant-card { background: transparent !important; border: 0 !important; box-shadow: none !important; padding: 0 !important; }
|
||||||
|
.main-column div.trending-card div.inhabitant-card::before, .main-column div.trending-card div.inhabitant-card::after { display: none !important; }
|
||||||
|
|
||||||
|
/* ---------- buscador de /search de la 1.3.5 (apk-searchform) ----------
|
||||||
|
su CSS esta en OasisMobile.css, que con Activista no carga: el campo se quedaba en
|
||||||
|
26px y los campos de "mas" siempre a la vista. Casilla + etiqueta, sin JS */
|
||||||
|
.main-column form.apk-searchform { display: flex !important; flex-wrap: wrap !important; align-items: center !important; position: relative; }
|
||||||
|
.main-column form.apk-searchform > input.filter-box__input { flex: 1 1 0 !important; min-width: 0 !important; width: auto !important; min-height: 48px !important; }
|
||||||
|
.main-column form.apk-searchform > div.filter-box__controls { display: flex !important; flex: 0 0 auto !important; align-items: center; width: auto !important; margin: 0 0 0 8px !important; padding: 0 !important; }
|
||||||
|
.main-column form.apk-searchform label.apk-more-btn {
|
||||||
|
display: inline-flex !important; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; margin: 0 8px 0 0 !important;
|
||||||
|
border: 1px solid var(--ux-line) !important; border-radius: 12px !important; cursor: pointer; color: var(--ux-fg) !important;
|
||||||
|
}
|
||||||
|
.main-column form.apk-searchform label.apk-more-btn::after { content: "\2295"; font-size: 22px; line-height: 1; }
|
||||||
|
.main-column form.apk-searchform > input.apk-more-toggle { position: absolute !important; opacity: 0 !important; width: 1px !important; height: 1px !important; margin: 0 !important; pointer-events: none; }
|
||||||
|
.main-column form.apk-searchform > div.apk-more-fields { display: none !important; flex: 1 1 100% !important; margin: 10px 0 0 !important; padding: 0 !important; }
|
||||||
|
.main-column form.apk-searchform > input.apk-more-toggle:checked ~ div.apk-more-fields { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-gap: 10px; }
|
||||||
|
.main-column form.apk-searchform div.apk-more-field { display: flex !important; flex-direction: column !important; min-width: 0; margin: 0 !important; padding: 0 !important; }
|
||||||
|
.main-column form.apk-searchform span.apk-more-label { font-size: 13px !important; color: var(--ux-muted) !important; margin: 0 0 4px !important; }
|
||||||
|
.main-column form.apk-searchform div.apk-more-field > input, .main-column form.apk-searchform div.apk-more-field > select { width: 100% !important; min-width: 0 !important; min-height: 44px !important; box-sizing: border-box; margin: 0 !important; }
|
||||||
|
|
||||||
|
/* aviso de sugerencia (robot) del dev: el enlace era una linea de 23px cortada a "Orden ..." */
|
||||||
|
.main-column div.update-banner.ai-suggestion-banner, div.update-banner.ai-suggestion-banner { display: flex !important; align-items: center !important; flex-wrap: nowrap !important; }
|
||||||
|
div.update-banner.ai-suggestion-banner > .update-banner-icon { display: block !important; flex: 0 0 auto; margin: 0 8px 0 0 !important; position: static !important; }
|
||||||
|
div.update-banner.ai-suggestion-banner > a.update-banner-link {
|
||||||
|
flex: 1 1 auto !important; min-width: 0 !important; max-width: none !important; display: block !important; min-height: 44px; line-height: 44px !important;
|
||||||
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||||||
|
}
|
||||||
|
div.update-banner.ai-suggestion-banner > form.welcome-banner-close { position: static !important; flex: 0 0 auto !important; width: auto !important; margin: 0 0 0 8px !important; padding: 0 !important; }
|
||||||
|
div.update-banner.ai-suggestion-banner > form > button.welcome-banner-close-btn { width: 44px !important; min-width: 44px !important; max-width: 44px !important; min-height: 44px !important; padding: 0 !important; color: var(--ux-fg) !important; }
|
||||||
|
|
||||||
|
/* "EN RESPUESTA A" en las respuestas de Actividad: 10,7px */
|
||||||
|
.main-column .reply-context-label, .main-column .reply-context-label > a.tag-link { font-size: 12px !important; }
|
||||||
|
|
||||||
|
/* ocultar un comentario (ojo): el dev lo pone a left:-12px y se montaba sobre el borde
|
||||||
|
de la ficha y el nombre. Arriba a la derecha, dentro */
|
||||||
|
.main-column div.votations-comment-card { padding-right: 56px !important; }
|
||||||
|
.main-column div.votations-comment-card > form.comment-delete-form { left: auto !important; right: 6px !important; top: 6px !important; width: auto !important; }
|
||||||
|
.main-column div.votations-comment-card > form.comment-delete-form > button { min-width: 44px !important; min-height: 44px !important; }
|
||||||
|
|
||||||
|
/* paginacion del dev (10 / 50 / 100 / todos): fondo #1C1C1C fijo, con paletas claras
|
||||||
|
el texto quedaba a contraste 1,0-1,1 */
|
||||||
|
.main-column a.oasis-pager-btn { display: inline-flex !important; align-items: center; min-height: 44px; background: var(--ux-bg) !important; color: var(--ux-fg) !important; border: 1px solid var(--ux-line) !important; }
|
||||||
|
.main-column a.oasis-pager-btn.active { background: var(--ux-accent) !important; color: var(--ux-on-accent) !important; border-color: var(--ux-accent) !important; }
|
||||||
|
.main-column .oasis-pager-info { color: var(--ux-muted) !important; font-size: 13px !important; }
|
||||||
|
|
||||||
|
/* ---------- tribus y foro (TESTS/tribus, 23/10) ---------- */
|
||||||
|
/* votar un hilo del foro (▲ ▼): 30px */
|
||||||
|
.main-column button.score-btn { min-width: 44px !important; min-height: 44px !important; padding: 0 !important; }
|
||||||
|
/* etiquetas de la columna de la tribu: se tocan como fichas, no van en el texto */
|
||||||
|
.main-column .tribe-side-tags a.tag-link { display: inline-flex !important; align-items: center; min-height: 44px !important; box-sizing: border-box; }
|
||||||
|
/* la hora de un comentario lleva al hilo: era una linea de 34px */
|
||||||
|
.main-column .created-at a:not(.user-link) { display: inline-flex !important; align-items: center; min-height: 44px; }
|
||||||
|
/* ficha de con quien se comparte (PUBLICO, el nombre de la tribu): 22px. Bordes
|
||||||
|
transparentes arriba y abajo para llegar a 44 sin que la ficha se vea mas alta */
|
||||||
|
.main-column a.pm-exposition-chip-link { display: inline-flex !important; align-items: center; min-height: 44px; box-sizing: border-box; border-top: 11px solid transparent !important; border-bottom: 11px solid transparent !important; background-clip: padding-box !important; }
|
||||||
|
/* correos y enlaces sueltos en el texto de una publicacion: 16px de alto */
|
||||||
|
.main-column a[href^="mailto:"] { display: inline-block; min-height: 24px; line-height: 24px; }
|
||||||
|
.main-column span.internal-link-kind { font-size: 12px !important; }
|
||||||
|
/* titulo de una tarjeta que lleva a su ficha (Actividad): 26px */
|
||||||
|
.main-column div.card-field > a.card-value { display: inline-flex !important; align-items: center; min-height: 44px; }
|
||||||
|
|
||||||
|
/* ---------- iconos propios en vez de los emoji del dev (23/10) ----------
|
||||||
|
Los avisos, las fichas de con quien se comparte y Compartir llevaban emoji (el robot,
|
||||||
|
la llave inglesa, el globo, el candado). Se esconde el caracter y se dibuja un icono
|
||||||
|
de linea, del color del texto. Lo que escribe la gente no se toca */
|
||||||
|
.update-banner > .update-banner-icon, .main-column span.pm-exposition-icon, .main-column span.share-summary-icon {
|
||||||
|
font-size: 0 !important; display: inline-block !important; flex: 0 0 auto;
|
||||||
|
width: 18px !important; height: 18px !important; margin: 0 6px 0 0 !important; vertical-align: -3px;
|
||||||
|
background-color: currentColor; -webkit-mask: url(/assets/images/mobile-ico-publico.svg) center / contain no-repeat; mask: url(/assets/images/mobile-ico-publico.svg) center / contain no-repeat;
|
||||||
|
}
|
||||||
|
.main-column .pm-exposition-chip span.pm-exposition-icon, .update-banner > .update-banner-icon { background-color: currentColor !important; color: inherit !important; font-size: 0 !important; }
|
||||||
|
.update-banner > .update-banner-icon { width: 22px !important; height: 22px !important; -webkit-mask-image: url(/assets/images/mobile-ico-actualizar.svg); mask-image: url(/assets/images/mobile-ico-actualizar.svg); }
|
||||||
|
.update-banner.ai-suggestion-banner > .update-banner-icon { -webkit-mask-image: url(/assets/images/mobile-ico-sugerencia.svg); mask-image: url(/assets/images/mobile-ico-sugerencia.svg); }
|
||||||
|
.main-column span.share-summary-icon { -webkit-mask-image: url(/assets/images/mobile-ico-compartir.svg); mask-image: url(/assets/images/mobile-ico-compartir.svg); }
|
||||||
|
.main-column .pm-exposition-mutuals > span.pm-exposition-icon { -webkit-mask-image: url(/assets/images/mobile-ico-mutuos.svg); mask-image: url(/assets/images/mobile-ico-mutuos.svg); }
|
||||||
|
.main-column .pm-exposition-encrypted > span.pm-exposition-icon { -webkit-mask-image: url(/assets/images/mobile-ico-cifrado.svg); mask-image: url(/assets/images/mobile-ico-cifrado.svg); }
|
||||||
|
.main-column .pm-exposition-license > span.pm-exposition-icon { -webkit-mask-image: url(/assets/images/mobile-ico-licencia.svg); mask-image: url(/assets/images/mobile-ico-licencia.svg); }
|
||||||
|
.main-column .pm-exposition-tribe > span.pm-exposition-icon { -webkit-mask-image: url(/assets/images/mobile-ico-tribu.svg); mask-image: url(/assets/images/mobile-ico-tribu.svg); }
|
||||||
|
.main-column .pm-exposition-transport > span.pm-exposition-icon, .main-column .pm-exposition-fediverse > span.pm-exposition-icon { -webkit-mask-image: url(/assets/images/mobile-ico-red.svg); mask-image: url(/assets/images/mobile-ico-red.svg); }
|
||||||
|
.main-column [class*="pm-exposition-lifespan"] > span.pm-exposition-icon { -webkit-mask-image: url(/assets/images/mobile-ico-tiempo.svg); mask-image: url(/assets/images/mobile-ico-tiempo.svg); }
|
||||||
|
.main-column .pm-exposition-chip span.pm-exposition-icon { width: 14px !important; height: 14px !important; margin-right: 4px !important; vertical-align: -2px; }
|
||||||
|
|
||||||
|
/* los dos avisos de arriba (version nueva y sugerencia) se comian 150px en cada
|
||||||
|
pantalla: una linea cada uno, juntos */
|
||||||
|
.main-column .apk-banners { margin: 0 0 8px !important; }
|
||||||
|
.main-column .apk-banners > div.update-banner, body div.update-banner { min-height: 0 !important; padding: 4px 4px 4px 12px !important; margin: 0 0 6px !important; align-items: center !important; }
|
||||||
|
.main-column .apk-banners > div.update-banner > .update-banner-text { flex: 1 1 auto; min-width: 0; font-size: 13px !important; line-height: 1.3 !important; }
|
||||||
|
.main-column .apk-banners > div.update-banner > a.update-banner-link { flex: 0 0 auto; display: inline-flex !important; align-items: center; min-height: 44px; margin-left: 8px !important; font-size: 13px !important; }
|
||||||
|
.main-column .apk-banners > div.update-banner.ai-suggestion-banner > a.update-banner-link { flex: 1 1 auto !important; margin-left: 0 !important; }
|
||||||
|
|
||||||
|
/* buscador con "mas opciones" de la 1.3.5 tambien en form.filter-box (Imagenes y
|
||||||
|
otros): la casilla salia suelta y Buscar caia a otra linea */
|
||||||
|
.main-column input.apk-more-toggle { position: absolute !important; opacity: 0 !important; width: 1px !important; height: 1px !important; margin: 0 !important; pointer-events: none; }
|
||||||
|
.main-column form.filter-box { display: flex !important; flex-wrap: wrap !important; align-items: center !important; position: relative; }
|
||||||
|
/* con la casilla de "mas" el select va dentro del desplegable: fila, no columna */
|
||||||
|
.main-column form.filter-box.filter-box:has(> input.apk-more-toggle) { flex-direction: row !important; }
|
||||||
|
.main-column form.filter-box > input.filter-box__input { flex: 1 1 0 !important; min-width: 0 !important; width: auto !important; }
|
||||||
|
.main-column form.filter-box > div.filter-box__controls { display: flex !important; flex: 0 0 auto !important; align-items: center; width: auto !important; margin: 0 0 0 8px !important; padding: 0 !important; }
|
||||||
|
.main-column form.filter-box label.apk-more-btn {
|
||||||
|
display: inline-flex !important; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; margin: 0 8px 0 0 !important;
|
||||||
|
border: 1px solid var(--ux-line) !important; border-radius: 12px !important; cursor: pointer; color: var(--ux-fg) !important;
|
||||||
|
}
|
||||||
|
.main-column form.filter-box label.apk-more-btn::after { content: "\2295"; font-size: 22px; line-height: 1; }
|
||||||
|
.main-column form.filter-box > div.apk-more-fields { display: none !important; flex: 1 1 100% !important; margin: 10px 0 0 !important; padding: 0 !important; }
|
||||||
|
.main-column form.filter-box > input.apk-more-toggle:checked ~ div.apk-more-fields { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-gap: 10px; }
|
||||||
|
.main-column form.filter-box div.apk-more-fields > select, .main-column form.filter-box div.apk-more-fields > input, .main-column form.filter-box div.apk-more-fields > div { width: 100% !important; min-width: 0 !important; min-height: 44px !important; box-sizing: border-box; margin: 0 !important; }
|
||||||
|
|
||||||
|
/* ---------- chats: responder, reacciones y enviar (23/10) ----------
|
||||||
|
Responder a un mensaje era un "↩" de 27x20 junto a la hora: ni se veia ni se
|
||||||
|
acertaba. Pastilla con icono y la palabra (el title del dev, ya traducido) */
|
||||||
|
.main-column .chat-message-meta a.chat-reply-btn, .main-column .chat-msg-actions a.chat-reply-btn {
|
||||||
|
display: inline-flex !important; align-items: center; min-height: 44px; padding: 0 12px 0 10px !important; margin-left: auto;
|
||||||
|
border: 1px solid var(--ux-line) !important; border-radius: 22px !important; opacity: 1 !important;
|
||||||
|
font-size: 0 !important; color: var(--ux-fg) !important; text-decoration: none !important;
|
||||||
|
}
|
||||||
|
.main-column .chat-message-meta a.chat-reply-btn::before, .main-column .chat-msg-actions a.chat-reply-btn::before {
|
||||||
|
content: ""; width: 18px; height: 18px; margin-right: 6px; background-color: currentColor;
|
||||||
|
-webkit-mask: url(/assets/images/mobile-ico-responder.svg) center / contain no-repeat; mask: url(/assets/images/mobile-ico-responder.svg) center / contain no-repeat;
|
||||||
|
}
|
||||||
|
.main-column .chat-message-meta a.chat-reply-btn[title]::after, .main-column .chat-msg-actions a.chat-reply-btn[title]::after { content: attr(title); font-size: 13px; font-weight: 600; }
|
||||||
|
.main-column button.chat-react-btn { min-height: 44px !important; min-width: 44px !important; }
|
||||||
|
/* enviar (chat y respuesta del foro): un disco con ➤ o ↩ y nada mas. Ancho entero,
|
||||||
|
icono y la palabra */
|
||||||
|
body .main-column .chat-message-form button.filter-btn, body .main-column button.forum-send-btn {
|
||||||
|
display: flex !important; line-height: 1 !important; padding: 0 16px !important; align-items: center; justify-content: center; width: 100% !important; max-width: none !important;
|
||||||
|
min-height: 48px !important; height: auto !important; border-radius: 12px !important; font-size: 15px !important; font-weight: 700 !important;
|
||||||
|
background: var(--ux-accent) !important; color: var(--ux-on-accent) !important; border: 0 !important;
|
||||||
|
}
|
||||||
|
body .main-column .chat-message-form button.filter-btn::before, body .main-column button.forum-send-btn::before {
|
||||||
|
content: "" !important; width: 18px; height: 18px; margin-right: 8px; background-color: currentColor !important;
|
||||||
|
-webkit-mask: url(/assets/images/mobile-ico-enviar.svg) center / contain no-repeat; mask: url(/assets/images/mobile-ico-enviar.svg) center / contain no-repeat;
|
||||||
|
}
|
||||||
|
/* hoja del menu: "Configuracion" y "Copia de seguridad" se salian de su casilla a 412px.
|
||||||
|
Solo la etiqueta; los iconos quedan como estan */
|
||||||
|
.menu-sheet .launcher .ln-lbl { max-width: 100%; white-space: normal !important; overflow-wrap: anywhere; -webkit-hyphens: auto; hyphens: auto; text-align: center; }
|
||||||
|
/* Ajustes, Actualizacion: "Version instalada" se cortaba en su celda */
|
||||||
|
.main-column table.torrent-file-info td.tribe-info-label { white-space: normal !important; overflow: visible !important; text-overflow: clip !important; }
|
||||||
|
/* botones de icono del dev en las fichas de Ficheros y Torrents: 34px */
|
||||||
|
.main-column button.btn-singleview { min-width: 44px !important; min-height: 44px !important; }
|
||||||
|
/* titulos de tarjeta (videos, audios) y categorias de opinion (Amor, Interesante): 26px y 10,5px */
|
||||||
|
.main-column a.card-title-link { display: inline-flex !important; align-items: center; min-height: 44px; }
|
||||||
|
.main-column span.vote-category { font-size: 12px !important; }
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,6 @@ module.exports = {
|
||||||
bbMenuClose: "Close",
|
bbMenuClose: "Close",
|
||||||
uxPickHint: "Tap one and it is saved. You can change it any time in Settings.",
|
uxPickHint: "Tap one and it is saved. You can change it any time in Settings.",
|
||||||
uxPickCurrent: "In use",
|
uxPickCurrent: "In use",
|
||||||
pubBarJoining: "Joining the pub… it can take up to a minute. Keep the app open.",
|
|
||||||
pubBarJoinFailed: "If you did not get into the pub, the usual reasons are: no connection (wifi or data), the pub is down, or the invite was already used. Try another pub from the list, or later.",
|
|
||||||
pubBarDownload: "Downloading the network from {pub} ({tier})…",
|
pubBarDownload: "Downloading the network from {pub} ({tier})…",
|
||||||
pubBarTierRecent: "the latest",
|
pubBarTierRecent: "the latest",
|
||||||
pubBarTierFull: "everything before",
|
pubBarTierFull: "everything before",
|
||||||
|
|
@ -165,8 +163,6 @@ module.exports = {
|
||||||
bbMenuClose: "Cerrar",
|
bbMenuClose: "Cerrar",
|
||||||
uxPickHint: "Toca uno y queda guardado. Puedes cambiarlo cuando quieras en Ajustes.",
|
uxPickHint: "Toca uno y queda guardado. Puedes cambiarlo cuando quieras en Ajustes.",
|
||||||
uxPickCurrent: "En uso",
|
uxPickCurrent: "En uso",
|
||||||
pubBarJoining: "Uniéndote al pub… puede tardar hasta un minuto. No cierres la app.",
|
|
||||||
pubBarJoinFailed: "Si no has entrado en el pub, lo más habitual es: no hay conexión (wifi o datos), el pub está caído o la invitación ya se ha usado. Prueba con otro pub de la lista o más tarde.",
|
|
||||||
pubBarDownload: "Descargando la red de {pub} ({tier})…",
|
pubBarDownload: "Descargando la red de {pub} ({tier})…",
|
||||||
pubBarTierRecent: "lo más reciente",
|
pubBarTierRecent: "lo más reciente",
|
||||||
pubBarTierFull: "todo lo anterior",
|
pubBarTierFull: "todo lo anterior",
|
||||||
|
|
@ -313,8 +309,6 @@ module.exports = {
|
||||||
bbMenuClose: "Tanca",
|
bbMenuClose: "Tanca",
|
||||||
uxPickHint: "Toca'n un i queda desat. El pots canviar quan vulguis a Configuració.",
|
uxPickHint: "Toca'n un i queda desat. El pots canviar quan vulguis a Configuració.",
|
||||||
uxPickCurrent: "En ús",
|
uxPickCurrent: "En ús",
|
||||||
pubBarJoining: "T'estàs unint al pub… pot trigar fins a un minut. No tanquis l'app.",
|
|
||||||
pubBarJoinFailed: "Si no has entrat al pub, el més habitual és: no hi ha connexió (wifi o dades), el pub ha caigut o la invitació ja s'ha fet servir. Prova amb un altre pub de la llista o més tard.",
|
|
||||||
pubBarDownload: "Descarregant la xarxa de {pub} ({tier})…",
|
pubBarDownload: "Descarregant la xarxa de {pub} ({tier})…",
|
||||||
pubBarTierRecent: "el més recent",
|
pubBarTierRecent: "el més recent",
|
||||||
pubBarTierFull: "tot l'anterior",
|
pubBarTierFull: "tot l'anterior",
|
||||||
|
|
@ -451,8 +445,6 @@ module.exports = {
|
||||||
bbMenuClose: "Pechar",
|
bbMenuClose: "Pechar",
|
||||||
uxPickHint: "Toca un e queda gardado. Podes cambialo cando queiras en Axustes.",
|
uxPickHint: "Toca un e queda gardado. Podes cambialo cando queiras en Axustes.",
|
||||||
uxPickCurrent: "En uso",
|
uxPickCurrent: "En uso",
|
||||||
pubBarJoining: "Uníndote ao pub… pode tardar ata un minuto. Non peches a app.",
|
|
||||||
pubBarJoinFailed: "Se non entraches no pub, o máis habitual é: non hai conexión (wifi ou datos), o pub está caído ou o convite xa se usou. Proba con outro pub da lista ou máis tarde.",
|
|
||||||
pubBarDownload: "Descargando a rede de {pub} ({tier})…",
|
pubBarDownload: "Descargando a rede de {pub} ({tier})…",
|
||||||
pubBarTierRecent: "o máis recente",
|
pubBarTierRecent: "o máis recente",
|
||||||
pubBarTierFull: "todo o anterior",
|
pubBarTierFull: "todo o anterior",
|
||||||
|
|
@ -590,8 +582,6 @@ module.exports = {
|
||||||
bbMenuClose: "Fermer",
|
bbMenuClose: "Fermer",
|
||||||
uxPickHint: "Touchez-en un et c'est enregistré. Vous pouvez le changer à tout moment dans les Paramètres.",
|
uxPickHint: "Touchez-en un et c'est enregistré. Vous pouvez le changer à tout moment dans les Paramètres.",
|
||||||
uxPickCurrent: "Actuel",
|
uxPickCurrent: "Actuel",
|
||||||
pubBarJoining: "Connexion au pub… cela peut prendre jusqu'à une minute. Gardez l'app ouverte.",
|
|
||||||
pubBarJoinFailed: "Si vous n'êtes pas entré dans le pub, c'est souvent : pas de connexion (wifi ou données), pub hors service, ou invitation déjà utilisée. Essayez un autre pub de la liste, ou plus tard.",
|
|
||||||
pubBarDownload: "Téléchargement du réseau depuis {pub} ({tier})…",
|
pubBarDownload: "Téléchargement du réseau depuis {pub} ({tier})…",
|
||||||
pubBarTierRecent: "le plus récent",
|
pubBarTierRecent: "le plus récent",
|
||||||
pubBarTierFull: "tout le reste",
|
pubBarTierFull: "tout le reste",
|
||||||
|
|
@ -733,8 +723,6 @@ module.exports = {
|
||||||
bbMenuClose: "Itxi",
|
bbMenuClose: "Itxi",
|
||||||
uxPickHint: "Bat ukitu eta gordeta geratzen da. Nahi duzunean alda dezakezu Ezarpenetan.",
|
uxPickHint: "Bat ukitu eta gordeta geratzen da. Nahi duzunean alda dezakezu Ezarpenetan.",
|
||||||
uxPickCurrent: "Erabiltzen",
|
uxPickCurrent: "Erabiltzen",
|
||||||
pubBarJoining: "Pubera sartzen… minutu bat arte iraun dezake. Ez itxi aplikazioa.",
|
|
||||||
pubBarJoinFailed: "Pubean sartu ez bazara, ohikoena hau da: ez dago konexiorik (wifia edo datuak), puba eroria dago edo gonbidapena erabilita dago. Saiatu zerrendako beste pub batekin edo geroago.",
|
|
||||||
pubBarDownload: "{pub}-ren sarea deskargatzen ({tier})…",
|
pubBarDownload: "{pub}-ren sarea deskargatzen ({tier})…",
|
||||||
pubBarTierRecent: "berriena",
|
pubBarTierRecent: "berriena",
|
||||||
pubBarTierFull: "aurreko guztia",
|
pubBarTierFull: "aurreko guztia",
|
||||||
|
|
@ -876,8 +864,6 @@ module.exports = {
|
||||||
bbMenuClose: "Schließen",
|
bbMenuClose: "Schließen",
|
||||||
uxPickHint: "Tippe eins an und es ist gespeichert. Du kannst es jederzeit in den Einstellungen ändern.",
|
uxPickHint: "Tippe eins an und es ist gespeichert. Du kannst es jederzeit in den Einstellungen ändern.",
|
||||||
uxPickCurrent: "Aktiv",
|
uxPickCurrent: "Aktiv",
|
||||||
pubBarJoining: "Beitritt zum Pub… das kann bis zu einer Minute dauern. Lass die App offen.",
|
|
||||||
pubBarJoinFailed: "Wenn du nicht in den Pub gekommen bist, liegt es meist daran: keine Verbindung (WLAN oder Daten), der Pub ist down oder die Einladung wurde schon benutzt. Probier einen anderen Pub aus der Liste oder später.",
|
|
||||||
pubBarDownload: "Netzwerk wird von {pub} geladen ({tier})…",
|
pubBarDownload: "Netzwerk wird von {pub} geladen ({tier})…",
|
||||||
pubBarTierRecent: "das Neueste",
|
pubBarTierRecent: "das Neueste",
|
||||||
pubBarTierFull: "alles davor",
|
pubBarTierFull: "alles davor",
|
||||||
|
|
@ -1019,8 +1005,6 @@ module.exports = {
|
||||||
bbMenuClose: "Chiudi",
|
bbMenuClose: "Chiudi",
|
||||||
uxPickHint: "Toccane uno ed è salvato. Puoi cambiarlo quando vuoi nelle Impostazioni.",
|
uxPickHint: "Toccane uno ed è salvato. Puoi cambiarlo quando vuoi nelle Impostazioni.",
|
||||||
uxPickCurrent: "In uso",
|
uxPickCurrent: "In uso",
|
||||||
pubBarJoining: "Ti stai unendo al pub… può volerci fino a un minuto. Tieni l'app aperta.",
|
|
||||||
pubBarJoinFailed: "Se non sei entrato nel pub, di solito è perché: non c'è connessione (wifi o dati), il pub è giù o l'invito è già stato usato. Prova un altro pub della lista, o più tardi.",
|
|
||||||
pubBarDownload: "Scaricamento della rete da {pub} ({tier})…",
|
pubBarDownload: "Scaricamento della rete da {pub} ({tier})…",
|
||||||
pubBarTierRecent: "il più recente",
|
pubBarTierRecent: "il più recente",
|
||||||
pubBarTierFull: "tutto il resto",
|
pubBarTierFull: "tutto il resto",
|
||||||
|
|
@ -1162,8 +1146,6 @@ module.exports = {
|
||||||
bbMenuClose: "Fechar",
|
bbMenuClose: "Fechar",
|
||||||
uxPickHint: "Toque num e fica guardado. Pode mudá-lo quando quiser nas Definições.",
|
uxPickHint: "Toque num e fica guardado. Pode mudá-lo quando quiser nas Definições.",
|
||||||
uxPickCurrent: "Em uso",
|
uxPickCurrent: "Em uso",
|
||||||
pubBarJoining: "A entrar no pub… pode demorar até um minuto. Não feche a app.",
|
|
||||||
pubBarJoinFailed: "Se não entrou no pub, o mais habitual é: não há ligação (wifi ou dados), o pub está em baixo ou o convite já foi usado. Tente outro pub da lista, ou mais tarde.",
|
|
||||||
pubBarDownload: "A descarregar a rede de {pub} ({tier})…",
|
pubBarDownload: "A descarregar a rede de {pub} ({tier})…",
|
||||||
pubBarTierRecent: "o mais recente",
|
pubBarTierRecent: "o mais recente",
|
||||||
pubBarTierFull: "tudo o anterior",
|
pubBarTierFull: "tudo o anterior",
|
||||||
|
|
@ -1305,8 +1287,6 @@ module.exports = {
|
||||||
bbMenuClose: "关闭",
|
bbMenuClose: "关闭",
|
||||||
uxPickHint: "点一下即保存。随时可以在设置中更改。",
|
uxPickHint: "点一下即保存。随时可以在设置中更改。",
|
||||||
uxPickCurrent: "使用中",
|
uxPickCurrent: "使用中",
|
||||||
pubBarJoining: "正在加入 pub……最多可能需要一分钟。请不要关闭应用。",
|
|
||||||
pubBarJoinFailed: "如果没有进入 pub,常见原因是:没有网络(wifi 或流量)、pub 已停止服务,或邀请已被使用。请尝试列表中的其他 pub,或稍后再试。",
|
|
||||||
pubBarDownload: "正在从 {pub} 下载网络({tier})……",
|
pubBarDownload: "正在从 {pub} 下载网络({tier})……",
|
||||||
pubBarTierRecent: "最新内容",
|
pubBarTierRecent: "最新内容",
|
||||||
pubBarTierFull: "之前的全部",
|
pubBarTierFull: "之前的全部",
|
||||||
|
|
@ -1448,8 +1428,6 @@ module.exports = {
|
||||||
bbMenuClose: "إغلاق",
|
bbMenuClose: "إغلاق",
|
||||||
uxPickHint: "المس واحدًا ويُحفظ. يمكنك تغييره في أي وقت من الإعدادات.",
|
uxPickHint: "المس واحدًا ويُحفظ. يمكنك تغييره في أي وقت من الإعدادات.",
|
||||||
uxPickCurrent: "قيد الاستخدام",
|
uxPickCurrent: "قيد الاستخدام",
|
||||||
pubBarJoining: "جارٍ الانضمام إلى الـ pub… قد يستغرق ذلك دقيقة. أبقِ التطبيق مفتوحًا.",
|
|
||||||
pubBarJoinFailed: "إن لم تدخل إلى الـ pub، فالأسباب المعتادة: لا يوجد اتصال (واي فاي أو بيانات)، أو الـ pub متوقف، أو الدعوة استُخدمت من قبل. جرّب pub آخر من القائمة أو لاحقًا.",
|
|
||||||
pubBarDownload: "جارٍ تنزيل الشبكة من {pub} ({tier})…",
|
pubBarDownload: "جارٍ تنزيل الشبكة من {pub} ({tier})…",
|
||||||
pubBarTierRecent: "الأحدث",
|
pubBarTierRecent: "الأحدث",
|
||||||
pubBarTierFull: "كل ما سبق",
|
pubBarTierFull: "كل ما سبق",
|
||||||
|
|
@ -1591,8 +1569,6 @@ module.exports = {
|
||||||
bbMenuClose: "बंद करें",
|
bbMenuClose: "बंद करें",
|
||||||
uxPickHint: "एक पर टैप करें और वह सेव हो जाएगा। सेटिंग्स में इसे कभी भी बदल सकते हैं।",
|
uxPickHint: "एक पर टैप करें और वह सेव हो जाएगा। सेटिंग्स में इसे कभी भी बदल सकते हैं।",
|
||||||
uxPickCurrent: "चालू",
|
uxPickCurrent: "चालू",
|
||||||
pubBarJoining: "pub से जुड़ रहे हैं… इसमें एक मिनट तक लग सकता है। ऐप खुला रखें।",
|
|
||||||
pubBarJoinFailed: "अगर आप pub में नहीं जा पाए, तो आम वजहें हैं: कनेक्शन नहीं है (वाई-फ़ाई या डेटा), pub बंद है, या निमंत्रण पहले ही इस्तेमाल हो चुका है। सूची से कोई दूसरा pub आज़माएँ, या बाद में।",
|
|
||||||
pubBarDownload: "{pub} से नेटवर्क डाउनलोड हो रहा है ({tier})…",
|
pubBarDownload: "{pub} से नेटवर्क डाउनलोड हो रहा है ({tier})…",
|
||||||
pubBarTierRecent: "सबसे नया",
|
pubBarTierRecent: "सबसे नया",
|
||||||
pubBarTierFull: "पहले का सब कुछ",
|
pubBarTierFull: "पहले का सब कुछ",
|
||||||
|
|
@ -1734,8 +1710,6 @@ module.exports = {
|
||||||
bbMenuClose: "Закрыть",
|
bbMenuClose: "Закрыть",
|
||||||
uxPickHint: "Нажмите на вариант, и он сохранится. Изменить можно в любой момент в Настройках.",
|
uxPickHint: "Нажмите на вариант, и он сохранится. Изменить можно в любой момент в Настройках.",
|
||||||
uxPickCurrent: "Сейчас",
|
uxPickCurrent: "Сейчас",
|
||||||
pubBarJoining: "Подключение к пабу… это может занять до минуты. Не закрывайте приложение.",
|
|
||||||
pubBarJoinFailed: "Если не удалось войти в паб, обычно причина такая: нет связи (wifi или мобильные данные), паб недоступен или приглашение уже использовано. Попробуйте другой паб из списка или позже.",
|
|
||||||
pubBarDownload: "Загрузка сети с {pub} ({tier})…",
|
pubBarDownload: "Загрузка сети с {pub} ({tier})…",
|
||||||
pubBarTierRecent: "самое новое",
|
pubBarTierRecent: "самое новое",
|
||||||
pubBarTierFull: "всё остальное",
|
pubBarTierFull: "всё остальное",
|
||||||
|
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
// Hoja del menu (pestaña Menu de la barra de abajo). Abre y cierra con una casilla
|
|
||||||
// y CSS; esto solo hace que el boton atras de Android cierre la hoja en vez de
|
|
||||||
// cambiar de pagina. Ver docs/ESTUDIO_NAVEGACION.md.
|
|
||||||
(function () {
|
|
||||||
var box = document.getElementById('oasis-menu-toggle');
|
|
||||||
if (!box || !window.history || !history.pushState) return;
|
|
||||||
var sheet = document.querySelector('.menu-sheet');
|
|
||||||
var pending = null;
|
|
||||||
if (history.state && history.state.oasisMenu) box.checked = true;
|
|
||||||
box.addEventListener('change', function () {
|
|
||||||
if (box.checked) { history.pushState({ oasisMenu: true }, ''); }
|
|
||||||
else if (history.state && history.state.oasisMenu) { history.back(); }
|
|
||||||
});
|
|
||||||
window.addEventListener('popstate', function () {
|
|
||||||
if (box.checked) box.checked = false;
|
|
||||||
// se navega despues de que la vuelta atras termine (en WebView 69, si no, se
|
|
||||||
// perdia la entrada nueva)
|
|
||||||
if (pending) setTimeout(follow, 50);
|
|
||||||
});
|
|
||||||
function follow() { if (pending) { var go = pending; pending = null; location.href = go; } }
|
|
||||||
// al ir a un modulo desde la hoja, primero se quita la entrada de la hoja: si no,
|
|
||||||
// al volver atras desde el modulo la portada aparecia con la hoja abierta
|
|
||||||
if (sheet) sheet.addEventListener('click', function (e) {
|
|
||||||
var a = e.target.closest ? e.target.closest('a[href]') : null;
|
|
||||||
if (!a || !(history.state && history.state.oasisMenu)) return;
|
|
||||||
e.preventDefault();
|
|
||||||
pending = a.href;
|
|
||||||
history.back();
|
|
||||||
setTimeout(follow, 1000);
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
// Barra de unirse a un pub (ver views/mobile_pubbar.js). Sin este script la barra se
|
|
||||||
// ve igual al cargar cada pagina; con el, se pone al dia sola y sale nada mas tocar
|
|
||||||
// "unirse", sin recargar la pagina.
|
|
||||||
(function () {
|
|
||||||
var bar = document.getElementById('pub-bar');
|
|
||||||
if (!bar || !window.fetch) return;
|
|
||||||
var text = bar.querySelector('.pub-bar-text');
|
|
||||||
var hint = bar.querySelector('.pub-bar-hint');
|
|
||||||
var meter = bar.querySelector('.pub-bar-meter');
|
|
||||||
var timer = null;
|
|
||||||
|
|
||||||
function show(s) {
|
|
||||||
if (!s || s.kind === 'none') { bar.hidden = true; document.body.classList.remove('has-pub-bar'); return; }
|
|
||||||
bar.hidden = false;
|
|
||||||
document.body.classList.add('has-pub-bar');
|
|
||||||
bar.className = 'pub-bar is-' + s.kind;
|
|
||||||
bar.setAttribute('data-running', s.running ? '1' : '0');
|
|
||||||
text.textContent = s.text || '';
|
|
||||||
hint.textContent = s.hint || '';
|
|
||||||
if (s.pct == null) meter.removeAttribute('value'); else meter.value = s.pct;
|
|
||||||
}
|
|
||||||
|
|
||||||
function poll() {
|
|
||||||
fetch('/mobile/pub-status', { credentials: 'same-origin', cache: 'no-store' })
|
|
||||||
.then(function (r) { return r.json(); })
|
|
||||||
.then(function (s) {
|
|
||||||
show(s);
|
|
||||||
clearTimeout(timer);
|
|
||||||
if (s && s.running) timer = setTimeout(poll, 2000);
|
|
||||||
})
|
|
||||||
.catch(function () { clearTimeout(timer); timer = setTimeout(poll, 5000); });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bar.hidden) document.body.classList.add('has-pub-bar');
|
|
||||||
if (bar.getAttribute('data-running') === '1') timer = setTimeout(poll, 2000);
|
|
||||||
|
|
||||||
// despues de intentar unirse: si no ha arrancado ninguna descarga, explicar las
|
|
||||||
// causas habituales (el aviso del dev a veces dice "codigo no valido" cuando lo
|
|
||||||
// que pasa es que no hay red). Solo se mira nuestro estado, no la pagina del dev
|
|
||||||
var tried = 0;
|
|
||||||
try { tried = Number(sessionStorage.getItem('oasisPubJoin')) || 0; sessionStorage.removeItem('oasisPubJoin'); } catch (_) {}
|
|
||||||
if (tried && Date.now() - tried < 3 * 60 * 1000 && bar.hidden) {
|
|
||||||
fetch('/mobile/pub-status', { credentials: 'same-origin', cache: 'no-store' })
|
|
||||||
.then(function (r) { return r.json(); })
|
|
||||||
.then(function (s) {
|
|
||||||
if (s && s.kind !== 'none') { show(s); if (s.running) timer = setTimeout(poll, 2000); return; }
|
|
||||||
show({ kind: 'error', running: false, pct: null, text: bar.getAttribute('data-failed'), hint: '' });
|
|
||||||
})
|
|
||||||
.catch(function () {});
|
|
||||||
}
|
|
||||||
|
|
||||||
// al tocar unirse (Invitaciones, bienvenida, Ajustes, importar pubs): la barra sale ya. El
|
|
||||||
// dev tarda en contestar mientras conecta con el pub y la pantalla se quedaba quieta
|
|
||||||
document.addEventListener('submit', function (e) {
|
|
||||||
var f = e.target;
|
|
||||||
var action = (f && f.getAttribute('action')) || '';
|
|
||||||
var by = e.submitter && e.submitter.value;
|
|
||||||
if (!/^\/(invites\/join|invites\/import-pubs|settings\/invite\/accept|welcome\/community)$/.test(action) || by === 'skip') return;
|
|
||||||
// en la bienvenida, solo si hay algun pub marcado (sin e.submitter en WebView viejos)
|
|
||||||
if (action === '/welcome/community' && !f.querySelector('input[name="pub"]:checked')) return;
|
|
||||||
try { sessionStorage.setItem('oasisPubJoin', String(Date.now())); } catch (_) {}
|
|
||||||
show({ kind: 'joining', running: true, pct: null, text: bar.getAttribute('data-joining'), hint: '' });
|
|
||||||
});
|
|
||||||
|
|
||||||
// cerrar sin cambiar de pagina
|
|
||||||
var close = bar.querySelector('.pub-bar-close');
|
|
||||||
if (close) close.addEventListener('submit', function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
fetch(close.getAttribute('action'), { method: 'POST', credentials: 'same-origin' }).catch(function () {});
|
|
||||||
show(null);
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
|
|
@ -146,8 +146,7 @@ exports.backupView = async ({ type = "RECOVERY", options = null, restoreJob = nu
|
||||||
div({ class: "div-center backup-wrap" }, body)
|
div({ class: "div-center backup-wrap" }, body)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
// movil: sin recargar cada 5s; la barra del pub (mobile_pubbar.js) se pone al dia sola
|
return restoreJob && restoreJob.running ? html.replace('</head>', '<meta http-equiv="refresh" content="5"></head>') : html;
|
||||||
return restoreJob && restoreJob.running && !require('./mobile_ui').isMobile() ? html.replace('</head>', '<meta http-equiv="refresh" content="5"></head>') : html;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.renderRestoreStatus = renderRestoreStatus;
|
exports.renderRestoreStatus = renderRestoreStatus;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
// cada integracion. Aqui solo depende de i18n, que se inyecta porque main_views
|
// cada integracion. Aqui solo depende de i18n, que se inyecta porque main_views
|
||||||
// lo muta en cada peticion sin reasignarlo.
|
// lo muta en cada peticion sin reasignarlo.
|
||||||
|
|
||||||
const { a, button, div, form, h2, h3, img, input, label, nav, p, script, section, span } = require("../server/node_modules/hyperaxe");
|
const { a, button, div, form, h2, h3, img, input, nav, p, section, span } = require("../server/node_modules/hyperaxe");
|
||||||
const { getConfig } = require("../configs/config-manager.js");
|
const { getConfig } = require("../configs/config-manager.js");
|
||||||
const sharedState = require("../configs/shared-state");
|
const sharedState = require("../configs/shared-state");
|
||||||
const { iconNode, iconKeyOf } = require("./mobile_icons");
|
const { iconNode, iconKeyOf } = require("./mobile_icons");
|
||||||
|
|
@ -109,34 +109,41 @@ module.exports = ({ i18n }) => {
|
||||||
.map(key => PINNABLE_MODULES.find(m => m.key === key))
|
.map(key => PINNABLE_MODULES.find(m => m.key === key))
|
||||||
.filter(m => m && modOn(m.mod))
|
.filter(m => m && modOn(m.mod))
|
||||||
.slice(0, MAX);
|
.slice(0, MAX);
|
||||||
|
// Publicar: el /publish del dev va siempre a crear un blog, y sin blogs (Empleo,
|
||||||
|
// Negocio) acababa en /modules. Aqui, al primer sitio de escribir que este encendido
|
||||||
|
const WRITE_TO = [['blogsMod', '/blogs?filter=CREATE'], ['feedMod', '/feed/create'], ['forumMod', '/forum?filter=create'], ['wikiMod', '/wiki?filter=create']];
|
||||||
|
const writeTo = (WRITE_TO.find(([mod]) => modOn(mod)) || [null, '/publish'])[1];
|
||||||
const slots = pins.map(m => bbLink(
|
const slots = pins.map(m => bbLink(
|
||||||
m.href, m.glyph, i18n[m.labelKey] || m.key, m.key === 'inbox' ? inboxN : 0
|
m.key === 'publish' ? writeTo : m.href, m.glyph, i18n[m.labelKey] || m.key, m.key === 'inbox' ? inboxN : 0
|
||||||
));
|
));
|
||||||
// quinta pestaña fija: Menu abre desde abajo una hoja con todos los modulos (el
|
// quinta pestaña fija: Menu abre desde abajo una hoja con todos los modulos (el
|
||||||
// lanzador). Sin JS: una casilla y CSS. autocomplete=off para que al volver atras
|
// lanzador). Sin JS (la CSP de la 1.3.5 no deja ninguno): un ancla #oasis-menu y
|
||||||
// el navegador no la deje abierta. Ver docs/ESTUDIO_NAVEGACION.md
|
// :target. Abrir deja una entrada en el historial, asi que atras cierra la hoja.
|
||||||
|
// Cerrar va a un ancla que no existe para que la pagina no salte arriba.
|
||||||
|
// Ver docs/ESTUDIO_NAVEGACION.md
|
||||||
const menuLabel = i18n.bbMenu || 'Menu';
|
const menuLabel = i18n.bbMenu || 'Menu';
|
||||||
|
const closeLabel = i18n.bbMenuClose || 'Close';
|
||||||
return nav(
|
return nav(
|
||||||
{ class: "oasis-bottombar", attrs: { "aria-label": i18n.bbQuickActions || "Quick actions" } },
|
{ id: 'oasis-menu', class: "oasis-bottombar", attrs: { "aria-label": i18n.bbQuickActions || "Quick actions" } },
|
||||||
input({ type: 'checkbox', id: 'oasis-menu-toggle', class: 'menu-toggle', autocomplete: 'off', 'aria-label': menuLabel }),
|
|
||||||
...slots,
|
...slots,
|
||||||
label({ class: 'bb-item bb-menu', for: 'oasis-menu-toggle' },
|
a({ class: 'bb-item bb-menu', href: '#oasis-menu' },
|
||||||
iconNode('bb-ico', 'modules', '▦'),
|
iconNode('bb-ico', 'modules', '▦'),
|
||||||
span({ class: 'bb-lbl' }, menuLabel)
|
span({ class: 'bb-lbl' }, menuLabel)
|
||||||
),
|
),
|
||||||
label({ class: 'menu-sheet-backdrop', for: 'oasis-menu-toggle', 'aria-hidden': 'true' }),
|
a({ class: 'bb-item bb-menu bb-menu-close', href: '#menu-cerrado', 'aria-label': closeLabel },
|
||||||
|
iconNode('bb-ico', 'modules', '▦'),
|
||||||
|
span({ class: 'bb-lbl' }, menuLabel)
|
||||||
|
),
|
||||||
|
a({ class: 'menu-sheet-backdrop', href: '#menu-cerrado', 'aria-hidden': 'true', tabindex: '-1' }),
|
||||||
div({ class: 'menu-sheet', role: 'dialog', 'aria-label': menuLabel },
|
div({ class: 'menu-sheet', role: 'dialog', 'aria-label': menuLabel },
|
||||||
div({ class: 'menu-sheet-head' },
|
div({ class: 'menu-sheet-head' },
|
||||||
span({ class: 'menu-sheet-title' }, menuLabel),
|
span({ class: 'menu-sheet-title' }, menuLabel),
|
||||||
label({ class: 'menu-sheet-close', for: 'oasis-menu-toggle', 'aria-label': i18n.bbMenuClose || 'Close' }, '✕')
|
a({ class: 'menu-sheet-close', href: '#menu-cerrado', 'aria-label': closeLabel }, '✕')
|
||||||
),
|
),
|
||||||
renderHiveNav()
|
renderHiveNav()
|
||||||
),
|
),
|
||||||
// atras cierra la hoja (sin este script el menu funciona igual)
|
// unirse a un pub: barra fija encima de esta (mobile_pubbar.js)
|
||||||
script({ src: '/js/mobile_menu.js', defer: 'defer' }),
|
require('./mobile_pubbar').pubBar()
|
||||||
// unirse a un pub: barra fija encima de esta, al dia sin recargar (mobile_pubbar.js)
|
|
||||||
require('./mobile_pubbar').pubBar(),
|
|
||||||
script({ src: '/js/mobile_pub.js', defer: 'defer' })
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,7 @@
|
||||||
// Su pantalla de bienvenida lo enseñaba recargandose entera cada 5 segundos y, si
|
// Su pantalla de bienvenida lo enseñaba recargandose entera cada 5 segundos y, si
|
||||||
// fallaba, solo decia el error en ingles. Aqui va una barra fija encima de la barra
|
// fallaba, solo decia el error en ingles. Aqui va una barra fija encima de la barra
|
||||||
// de abajo, en todas las pantallas, que dice en claro que esta pasando y por que
|
// de abajo, en todas las pantallas, que dice en claro que esta pasando y por que
|
||||||
// falla. La pinta hive_views.js (la barra de abajo es nuestra) y la mantiene al dia
|
// falla. La pinta hive_views.js (la barra de abajo es nuestra) en cada pantalla.
|
||||||
// public/js/mobile_pub.js preguntando a /mobile/pub-status, sin recargar.
|
|
||||||
//
|
//
|
||||||
// El estado lo lee de backupModel.restoreStatus(), que le pasa fork_routes.js al
|
// El estado lo lee de backupModel.restoreStatus(), que le pasa fork_routes.js al
|
||||||
// montarse (es una funcion del dev; no se cambia nada suyo).
|
// montarse (es una funcion del dev; no se cambia nada suyo).
|
||||||
|
|
@ -95,22 +94,17 @@ const backupStatus = (job, i18n) => {
|
||||||
text: fill(i18n.pubBarBackupDone || "Backup restored: {n} messages.", { n: num((job.result || {}).messages) }) };
|
text: fill(i18n.pubBarBackupDone || "Backup restored: {n} messages.", { n: num((job.result || {}).messages) }) };
|
||||||
};
|
};
|
||||||
|
|
||||||
// la barra; siempre se pinta (oculta si no hay nada) para que el script la enseñe
|
// la barra, solo si hay algo que contar. Sin JS (la CSP de la 1.3.5 no deja ninguno)
|
||||||
// al tocar "unirse", antes de que conteste el dev
|
// se pone al dia al cambiar de pantalla
|
||||||
const pubBar = () => {
|
const pubBar = () => {
|
||||||
const i18n = t();
|
const i18n = t();
|
||||||
const s = status();
|
const s = status();
|
||||||
return div({
|
if (!s) return null;
|
||||||
id: "pub-bar", class: `pub-bar${s ? ` is-${s.kind}` : ""}`, role: "status", "aria-live": "polite",
|
return div({ id: "pub-bar", class: `pub-bar is-${s.kind}`, role: "status", "data-running": s.running ? "1" : "0" },
|
||||||
"data-running": s && s.running ? "1" : "0",
|
|
||||||
"data-joining": i18n.pubBarJoining || "Joining the pub… it can take up to a minute. Keep the app open.",
|
|
||||||
"data-failed": i18n.pubBarJoinFailed || "If you did not get into the pub, the usual reasons are: no connection (wifi or data), the pub is down, or the invite was already used. Try another pub from the list, or later.",
|
|
||||||
...(s ? {} : { hidden: true })
|
|
||||||
},
|
|
||||||
div({ class: "pub-bar-body" },
|
div({ class: "pub-bar-body" },
|
||||||
p({ class: "pub-bar-text" }, s ? s.text : ""),
|
p({ class: "pub-bar-text" }, s.text),
|
||||||
p({ class: "pub-bar-hint" }, s ? s.hint : ""),
|
s.hint ? p({ class: "pub-bar-hint" }, s.hint) : null,
|
||||||
progress({ class: "pub-bar-meter", max: "100", ...(s && s.pct != null ? { value: String(s.pct) } : {}) })
|
progress({ class: "pub-bar-meter", max: "100", ...(s.pct != null ? { value: String(s.pct) } : {}) })
|
||||||
),
|
),
|
||||||
form({ method: "POST", action: "/mobile/pub-status/dismiss", class: "pub-bar-close" },
|
form({ method: "POST", action: "/mobile/pub-status/dismiss", class: "pub-bar-close" },
|
||||||
button({ type: "submit", "aria-label": i18n.pubBarClose || "Close" }, "✕"))
|
button({ type: "submit", "aria-label": i18n.pubBarClose || "Close" }, "✕"))
|
||||||
|
|
|
||||||
|
|
@ -92,11 +92,11 @@ const TRIBE_MAIN_TABS = ['activity', 'inhabitants', 'governance', 'votations', '
|
||||||
const tribeTabs = (tribe, section, sections) => {
|
const tribeTabs = (tribe, section, sections) => {
|
||||||
const i18n = t();
|
const i18n = t();
|
||||||
const all = sections.flatMap(g => g.items);
|
const all = sections.flatMap(g => g.items);
|
||||||
const tab = (s) => a({ href: `/tribe/${encodeURIComponent(tribe.id)}?section=${encodeURIComponent(s.key)}`, class: section === s.key ? 'tribe-tab is-current' : 'tribe-tab', ...(section === s.key ? { 'aria-current': 'page' } : {}) }, s.label);
|
const tab = (s) => a({ href: `/tribe/${encodeURIComponent(tribe.id)}?section=${encodeURIComponent(s.key)}#tribe-tabs`, class: section === s.key ? 'tribe-tab is-current' : 'tribe-tab', ...(section === s.key ? { 'aria-current': 'page' } : {}) }, s.label);
|
||||||
const main = all.filter(s => TRIBE_MAIN_TABS.includes(s.key));
|
const main = all.filter(s => TRIBE_MAIN_TABS.includes(s.key));
|
||||||
const rest = all.filter(s => !TRIBE_MAIN_TABS.includes(s.key));
|
const rest = all.filter(s => !TRIBE_MAIN_TABS.includes(s.key));
|
||||||
const currentRest = rest.find(s => s.key === section);
|
const currentRest = rest.find(s => s.key === section);
|
||||||
return nav({ class: 'tribe-tabs', 'aria-label': i18n.tribeSectionsLabel || 'Sections' },
|
return nav({ id: 'tribe-tabs', class: 'tribe-tabs', 'aria-label': i18n.tribeSectionsLabel || 'Sections' },
|
||||||
div({ class: 'tribe-tabs-strip' }, ...(currentRest ? [tab(currentRest)] : []), ...main.map(tab)),
|
div({ class: 'tribe-tabs-strip' }, ...(currentRest ? [tab(currentRest)] : []), ...main.map(tab)),
|
||||||
details({ class: 'tribe-tabs-more' },
|
details({ class: 'tribe-tabs-more' },
|
||||||
summary(i18n.tribeSectionsMore || 'More'),
|
summary(i18n.tribeSectionsMore || 'More'),
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,5 @@ exports.welcomeView = async (status, profile = {}) => {
|
||||||
button({ type: "submit", class: "welcome-skip-btn" }, i18n.welcomeSkip)))
|
button({ type: "submit", class: "welcome-skip-btn" }, i18n.welcomeSkip)))
|
||||||
: null
|
: null
|
||||||
)
|
)
|
||||||
// movil: sin recargar cada 5s; la barra del pub (mobile_pubbar.js) se pone al dia sola
|
return status.bootstrap && status.bootstrap.running ? html.replace('</head>', '<meta http-equiv="refresh" content="5"></head>') : html
|
||||||
return status.bootstrap && status.bootstrap.running && !mobileUi.isMobile() ? html.replace('</head>', '<meta http-equiv="refresh" content="5"></head>') : html
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||