From b277f8e1cfbdc5297a744891ffa68ee18467bcaa Mon Sep 17 00:00:00 2001 From: hacklab Date: Tue, 20 Oct 2026 13:50:46 +0200 Subject: [PATCH] pruebas en la APK: huecos dobles de las barras, contraste y zonas tactiles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Probado con la APK instalada en el emulador de Android Studio (Pixel 9, Android 16): - La barra de arriba llevaba 65px de mas y la de abajo 24: el contenedor de la app del dev ya se aparta de las barras del sistema y nuestro CSS volvia a sumar safe-area-inset. Ahora --inset-top y --inset-bottom, a 0, en mobile_base.css. - Borrar en una tarjeta: la barra de confirmar se metia en la fila de botones y 'Si, borrar' salia letra a letra. La fila ya puede saltar de linea. - Acampada: .time-chip y .pref-pill del dev quedaban en negro sobre gris oscuro, y la pildora elegida con texto claro sobre el resalte en las paletas oscuras. - Zonas tactiles a 44px: barra de arriba, fichas, pasos de la bienvenida, aviso de bienvenida, pie, casillas con su etiqueta, botones del buzon; enlaces en el texto a 24px. - Acceso a un bloque de Ajustes: el titulo ya no queda bajo la barra de arriba. En la guia y en ARQUITECTURA_APK.md: no usar env(safe-area-inset-*), los tamaños minimos y el fallo del boton atras de la app del dev (la tecla retrocede dos pasos). --- GUIA_DE_DESARROLLO.md | 8 ++++ docs/ARQUITECTURA_APK.md | 17 ++++++++ src/client/assets/styles/hive_acampada.css | 15 ++++++- src/client/assets/styles/mobile_base.css | 15 +++++-- src/client/assets/styles/mobile_ux.css | 48 ++++++++++++++++++---- 5 files changed, 90 insertions(+), 13 deletions(-) diff --git a/GUIA_DE_DESARROLLO.md b/GUIA_DE_DESARROLLO.md index 67a23e7..132b8ad 100644 --- a/GUIA_DE_DESARROLLO.md +++ b/GUIA_DE_DESARROLLO.md @@ -178,6 +178,14 @@ hay que subir la especificidad y poner `!important` también. Ojo con una trampa `Acampada.css` quita el borde a todos los `div`, así que para ponérselo a uno hace falta `.main-column div.la-clase`. +Huecos de las barras del sistema: nada de `env(safe-area-inset-*)`. El contenedor de +la app del dev ya se aparta de la barra de estado y de la de gestos, y si se suma en +el CSS el hueco sale dos veces. Se usan `var(--inset-top)` y `var(--inset-bottom)`, +que valen 0 y están en `mobile_base.css`. + +Zonas táctiles: 44 px como mínimo para botones, fichas y casillas (con su etiqueta); +24 px para los enlaces que van dentro de una línea de texto (nombres, etiquetas). + Letra: Anton para títulos y para el botón negro principal de cada pantalla (`.create-button`). Lo demás, letra del sistema en negrita. diff --git a/docs/ARQUITECTURA_APK.md b/docs/ARQUITECTURA_APK.md index fa79a03..1c5478c 100644 --- a/docs/ARQUITECTURA_APK.md +++ b/docs/ARQUITECTURA_APK.md @@ -106,6 +106,23 @@ Por eso lo nuestro va en `fork_routes.js`, `mobile_ui.js` y las hojas propias, q el dev no importa. +## Barras del sistema y botón atrás + +`onCreate` pone un `OnApplyWindowInsetsListener` que aparta el contenedor de la +WebView de la barra de estado, del recorte de la cámara y de la barra de gestos +(`setPadding` con esos insets), salvo en pantalla completa. Pero devuelve los insets +sin consumir, y la WebView los sigue anunciando como `safe-area-inset-*`: si el CSS +los suma, el hueco sale doble (65 px de más arriba y 24 abajo en un Pixel 9 con +Android 16). Por eso nuestras hojas usan `--inset-top` y `--inset-bottom` a 0. + +El botón atrás pasa por `goBackInWebView()`, que hace `webView.goBack()` o, si no +puede, carga la página anterior de su propia lista (`visitedUrls`). Con el gesto de +atrás se llama una vez. Con la tecla (móviles con tres botones) se llama dos veces, +por `onKeyDown` y por `registerPredictiveBack`, y se retrocede dos pasos: con el menú +abierto, en vez de cerrarlo se va a la pantalla anterior. Es de su código Android; +hay que pedírselo al dev. + + ## Lo que hace nuestra APK encima `android/scripts/sobre_oficial.sh` coge esta APK tal cual y cambia: diff --git a/src/client/assets/styles/hive_acampada.css b/src/client/assets/styles/hive_acampada.css index 59aa5e3..05e415f 100644 --- a/src/client/assets/styles/hive_acampada.css +++ b/src/client/assets/styles/hive_acampada.css @@ -82,7 +82,7 @@ body { background: var(--a26-bg) !important; } border-top: var(--a26-bd) !important; box-shadow: none !important; } -.oasis-bottombar { padding: 6px 4px calc(6px + env(safe-area-inset-bottom, 0px)) !important; gap: 2px !important; } +.oasis-bottombar { padding: 6px 4px calc(6px + var(--inset-bottom)) !important; gap: 2px !important; } .oasis-bottombar .bb-item { gap: 2px !important; } .oasis-bottombar .bb-ico { color: var(--a26-fg) !important; font-size: 21px !important; } .oasis-bottombar .bb-lbl { @@ -505,3 +505,16 @@ body { font-size: 18px; } .tags-header p { font-size: 16px !important; } .card-footer .date-link, .card-footer a.user-link, a.user-link, .date-link { font-size: 15px !important; } input, textarea, select { font-size: 18px !important; min-height: 50px; } + +/* ---------- piezas del dev con fondo oscuro fijo (pruebas del 20/10) ---------- */ +/* style.css pinta .time-chip y .pref-pill en gris casi negro y Acampada pone el texto + en negro: no se leian. Se pasan a los colores del tema */ +.time-chip { background: var(--a26-soft) !important; color: var(--a26-fg) !important; border: var(--a26-bd-fino) !important; } +.pref-pill { background: var(--a26-bg) !important; color: var(--a26-fg) !important; border: var(--a26-bd-fino) !important; border-radius: 10px !important; min-height: 44px; } +/* con especificidad alta: la regla de etiquetas de formulario de mobile_ux.css le + ponia el color del texto normal encima del resalte */ +.main-column label.pref-pill:has(.pref-pill-input:checked) { background: var(--a26-neon) !important; color: var(--a26-on-neon) !important; } +.pref-pill.pref-pill-forced { background: #c0392b !important; border-color: #c0392b !important; color: #fff !important; } +/* el plegable de mensajes anteriores del buzon: gris claro sobre blanco */ +summary.pm-thread-toggle { color: var(--a26-muted) !important; } +.pm-thread-icon { font-size: 12px !important; } diff --git a/src/client/assets/styles/mobile_base.css b/src/client/assets/styles/mobile_base.css index e3c89ba..f3e3e36 100644 --- a/src/client/assets/styles/mobile_base.css +++ b/src/client/assets/styles/mobile_base.css @@ -6,6 +6,15 @@ * carga siempre, antes del skin (Acampada.css o el OasisMobile.css del dev). * Ver GUIA_DE_DESARROLLO.md. */ +/* Huecos de las barras del sistema. La APK es la del dev y su contenedor ya se + * aparta de la barra de estado, del recorte de la camara y de la barra de gestos + * (OasisActivity: setPadding con los insets); aun asi la WebView sigue diciendo + * safe-area-inset-* y, si se suman aqui, el hueco sale dos veces (65px de mas arriba + * y 24px abajo en un Pixel 9 con Android 16). Por eso valen 0. Si algun dia el dev + * dibuja debajo de las barras, se cambian estas dos lineas por env(safe-area-inset-*) + * y ya. Ver docs/ARQUITECTURA_APK.md. */ +:root { --inset-top: 0px; --inset-bottom: 0px; } + html { overflow-x: clip; overflow-y: visible; height: auto; } body { overflow-x: clip; overflow-y: visible; } @@ -19,7 +28,7 @@ body { overflow-x: clip; overflow-y: visible; } gap: 4px; background: #1F1F1F; border-top: 1px solid #333; - padding: 8px 6px calc(8px + env(safe-area-inset-bottom, 0px)); + padding: 8px 6px calc(8px + var(--inset-bottom)); } .oasis-bottombar .bb-item { position: relative; @@ -47,7 +56,7 @@ body { overflow-x: clip; overflow-y: visible; } display: flex; align-items: center; justify-content: center; } -body { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); } +body { padding-bottom: calc(64px + var(--inset-bottom)); } /* topbar FIJA arriba: [logo] [Personal] [Community] [avatar]; el lanzador scrollea por debajo */ .oasis-mobile-topbar { @@ -264,7 +273,7 @@ body { overscroll-behavior: none; } .header .top-bar-left nav, .header .top-bar-right nav { display: none; } -.oasis-mobile-topbar { padding-top: calc(env(safe-area-inset-top, 0px) + 10px); } +.oasis-mobile-topbar { padding-top: calc(var(--inset-top) + 10px); } .oasis-bottombar a.bb-item.current .bb-ico { background: #FFD700; color: #121212; diff --git a/src/client/assets/styles/mobile_ux.css b/src/client/assets/styles/mobile_ux.css index ee19d50..06ce6c1 100644 --- a/src/client/assets/styles/mobile_ux.css +++ b/src/client/assets/styles/mobile_ux.css @@ -122,6 +122,9 @@ .content-action-confirm > summary { list-style: none; cursor: pointer; } .content-action-confirm > summary::-webkit-details-marker { display: none; } .content-action-confirm[open] { flex-basis: 100%; order: 99; } +/* la fila de botones de la tarjeta tiene que poder saltar de linea: si no, la barra + de confirmar se metia en el hueco que quedaba y "Si, borrar" salia letra a letra */ +.main-column .content-actions { flex-wrap: wrap !important; } .content-action-confirm[open] > summary { background: var(--ux-danger) !important; color: #fff !important; border-color: var(--ux-danger) !important; } .content-action-confirm .confirm-bar { flex-basis: 100%; display: flex; align-items: center; justify-content: flex-end; gap: 10px; @@ -133,6 +136,7 @@ background: var(--ux-danger) !important; color: #fff !important; border-color: var(--ux-danger) !important; box-shadow: none !important; min-height: 44px !important; margin: 0 !important; width: auto !important; font-family: var(--ux-text) !important; font-weight: 700 !important; font-size: 15px !important; + flex: 0 0 auto; white-space: nowrap; } /* ---------- lista de tribus: una fila por tribu ---------- */ @@ -234,7 +238,7 @@ .main-column label.module-switch input.switch-input[type="checkbox"]:checked::after { transform: translateX(22px); background: var(--ux-on-accent); } /* Guardar siempre a la vista, encima de la barra de abajo */ .module-save-bar { - position: sticky; bottom: calc(76px + env(safe-area-inset-bottom, 0px)); z-index: 5; + position: sticky; bottom: calc(76px + var(--inset-bottom)); z-index: 5; padding: 10px 0; background: var(--ux-bg); } .module-save-bar .create-button { width: 100% !important; margin: 0 !important; } @@ -449,7 +453,7 @@ body .main-content { min-height: calc(100dvh - 300px); } .main-column .pm-card .pm-info-table tr:nth-child(1) { flex: 1 1 0 !important; } .main-column .pm-card .pm-info-table tr:has(.pm-unread-chip) { order: 3; flex-basis: 100% !important; } .main-column .pm-card .pm-actions { display: inline-flex !important; width: auto !important; margin: 8px 8px 0 0 !important; } -.main-column .pm-card .pm-actions button { min-height: 40px !important; padding: 4px 14px !important; font-size: 14px !important; box-shadow: none !important; width: auto !important; } +.main-column .pm-card .pm-actions button { min-height: 44px !important; padding: 4px 14px !important; font-size: 14px !important; box-shadow: none !important; width: auto !important; } .main-column table.search-filters-table { height: auto !important; min-height: 0 !important; margin: 0 !important; } .main-column .peers-conn-actions > form:last-child:nth-child(odd) { grid-column: 1 / -1; } .main-column .search-filters-row { height: auto !important; } @@ -461,7 +465,7 @@ body .main-content { min-height: calc(100dvh - 300px); } /* salia centrado en una fila propia arriba de cada pagina (unos 60px); va en la barra de arriba, junto al avatar */ form.oasis-phone-state { - position: fixed !important; top: calc(env(safe-area-inset-top, 0px) + 14px); right: 62px; z-index: 101; /* encima de la barra de arriba (100), debajo de la hoja del menu (1000) */ + position: fixed !important; top: calc(var(--inset-top) + 14px); right: 62px; z-index: 101; /* encima de la barra de arriba (100), debajo de la hoja del menu (1000) */ margin: 0 !important; padding: 0 !important; width: auto !important; } form.oasis-phone-state .oasis-phone-state-btn { @@ -532,7 +536,7 @@ body > .welcome-banner { order: -1; margin-top: 10px !important; } .oasis-bottombar .menu-toggle:checked ~ .menu-sheet { 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; - padding: 8px 14px calc(18px + env(safe-area-inset-bottom, 0px)); + padding: 8px 14px calc(18px + var(--inset-bottom)); background: var(--ux-bg); color: var(--ux-fg); border-top: 3px solid var(--ux-line); border-radius: 22px 22px 0 0; box-shadow: 0 -6px 24px rgba(0, 0, 0, .25); @@ -554,9 +558,9 @@ body > .welcome-banner { order: -1; margin-top: 10px !important; } /* cinco pestañas: que quepan a 360px */ .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; } } -.oasis-bottombar .menu-toggle:checked ~ div.menu-sheet { background: var(--ux-bg) !important; bottom: calc(66px + env(safe-area-inset-bottom, 0px)); border-radius: 22px 22px 0 0 !important; border: 0 !important; border-top: 3px solid var(--ux-line) !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: 3px solid var(--ux-line) !important; } .oasis-bottombar div.menu-sheet-head { background: var(--ux-bg) !important; border: 0 !important; border-bottom: 2px solid var(--ux-line) !important; } -.oasis-bottombar .menu-toggle:checked ~ .menu-sheet-backdrop { bottom: calc(66px + env(safe-area-inset-bottom, 0px)); } +.oasis-bottombar .menu-toggle:checked ~ .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 (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; } @@ -596,7 +600,7 @@ body:has(#oasis-menu-toggle:checked) form.oasis-phone-state { display: none !imp .main-column button.ux-pick-card.is-current { background: var(--ux-accent) !important; color: var(--ux-on-accent) !important; } .main-column .ux-pick-shot { display: block; flex: 0 0 76px; width: 76px; height: auto; border-radius: 8px; margin: 0 12px 0 0; border: 1px solid rgba(0, 0, 0, .2); } .main-column .ux-pick-label { flex: 1 1 auto; min-width: 0; text-align: left; font-size: 16px; font-weight: 700; line-height: 1.2; } -.main-column .ux-pick-now { flex: 0 0 auto; margin-left: 8px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; } +.main-column .ux-pick-now { flex: 0 0 auto; margin-left: 8px; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; } /* perfil de uso: sin miniatura, nombre y una linea de para que sirve */ .main-column .ux-pick-text { flex: 1 1 auto; min-width: 0; display: block; text-align: left; } .main-column .ux-pick-text .ux-pick-label { display: block; } @@ -613,8 +617,8 @@ body:has(#oasis-menu-toggle:checked) form.oasis-phone-state { display: none !imp /* ---------- 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 - bloque; el bloque deja aire arriba para que el titulo no quede pegado al borde */ -.main-column section[id] { scroll-margin-top: 76px; } + 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 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 { display: flex !important; flex-direction: column; align-items: center; justify-content: flex-start; text-align: center; @@ -664,6 +668,32 @@ body:has(#oasis-menu-toggle:checked) form.oasis-phone-state { display: none !imp .main-column form.color-custom-form .create-button { width: 100% !important; margin-top: 6px !important; } .main-column .color-pick .welcome-action { margin-top: 4px !important; } +/* ---------- 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 + (42), fichas de filtro (38), pasos de la bienvenida (33) y casillas del dev (16) */ +body .oasis-mobile-topbar .omt-logo img, body .oasis-mobile-topbar .omt-avatar img { width: 44px !important; height: 44px !important; } +.main-column :is(.mode-buttons, .mode-buttons-row, .filter-group, .filters, .tribe-mode-buttons) .filter-btn, +.main-column .mode-buttons-row button.filter-btn, .main-column .filters button.filter-btn { min-height: 44px !important; } +.main-column details.welcome-step > summary { min-height: 44px; display: flex; flex-wrap: wrap; align-items: center; } +.main-column a.activity-chip, .main-column .activity-chip { min-height: 44px !important; } +.welcome-banner .welcome-banner-start, .welcome-banner .welcome-banner-close-btn { min-height: 44px !important; min-width: 44px !important; } +.oasis-footer-mobile a.footer-sync { display: inline-flex !important; align-items: center; min-height: 44px; } +.main-column a.identity-legacy { display: inline-flex !important; align-items: center; min-height: 44px; } +.main-column label.lan-checkbox-label { min-height: 44px; display: flex !important; align-items: center; } +/* marcado del dev: plegables de opiniones, enlaces de comentarios, titulos de tarjeta + y el buzon. Los nombres y etiquetas dentro del texto se quedan en 24px (WCAG 2.2) */ +.main-column summary.opinions-summary { min-height: 44px; display: flex; align-items: center; } +.main-column a.comments-summary-link, .main-column a.card-value, .main-column a.pm-title-link { display: inline-flex !important; align-items: center; min-height: 44px; } +.main-column .tribe-card-title > a { display: inline-block; padding: 6px 0; min-height: 44px; box-sizing: border-box; } +.main-column a.user-link, .main-column a.tag-link { display: inline-block; min-height: 24px; line-height: 24px; } +.main-column .message-text a { display: inline-block; min-height: 24px; line-height: 24px; } +.main-column summary.pm-thread-toggle { min-height: 44px; display: flex; align-items: center; } +.main-column form label:has(> input[type="radio"]) { min-height: 44px; display: flex !important; align-items: center; } +.main-column input[type="checkbox"]:not(.switch-input):not(.pref-pill-input), .main-column input[type="radio"] { width: 24px !important; height: 24px !important; } +@supports not (inset: 0) { + .main-column .mode-buttons-row .filter-btn, .main-column .filters .filter-btn, .main-column .filter-group .filter-btn { min-height: 44px !important; } +} + /* ---------- tabletas y pantallas anchas ---------- */ /* a 800dp todo se estiraba: lineas larguisimas y la hoja del menu con cinco iconos repartidos en 800px. Contenido a 720px como mucho, centrado; la hoja, igual */