fix(mobile): filtros con flex-wrap CSS puro, sin JS ni flechas

Vuelta al enfoque más simple:
- mobile.css: .activity-filter-grid, .mode-buttons y similares
  usan flex-wrap:wrap. Todos los botones visibles en varias filas,
  sin scroll del dedo, sin paginación.
- .activity-filter-col con display:contents para aplanar columnas.
- mobile-ui.js vaciado (no-op): ya no hace falta JS.
- main_views.js: quitada la inyección inline.

Razón: el JS no se ejecutaba en el WebView (cache + CSP) por
mucho que se intentaba. CSS puro es más simple y robusto.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
SITO 2026-05-09 00:51:42 +02:00
parent 79c58d7144
commit 75bb97b204
3 changed files with 19 additions and 222 deletions

View file

@ -399,51 +399,47 @@ textarea, input, select {
font-size: 16px !important;
}
/* ---- Filtros: scroll horizontal en vez de columna vertical ---- */
/* ---- Filtros: wrap multilinea, todos los botones visibles ---- */
.mode-buttons,
.mode-buttons-cols,
.mode-buttons-row,
.filter-group,
.filters,
.inhabitant-action,
.tribe-mode-buttons {
.tribe-mode-buttons,
.activity-filter-grid {
display: flex !important;
flex-direction: row !important;
flex-wrap: nowrap !important;
overflow-x: auto !important;
overflow-y: hidden !important;
-webkit-overflow-scrolling: touch !important;
flex-wrap: wrap !important;
gap: 6px !important;
padding-bottom: 4px !important;
scrollbar-width: none !important;
width: 100% !important;
overflow: visible !important;
}
.mode-buttons::-webkit-scrollbar,
.mode-buttons-cols::-webkit-scrollbar,
.mode-buttons-row::-webkit-scrollbar,
.filter-group::-webkit-scrollbar,
.filters::-webkit-scrollbar,
.inhabitant-action::-webkit-scrollbar {
display: none !important;
/* En el activity-filter-grid las columnas (.activity-filter-col) se aplanan */
.activity-filter-grid .activity-filter-col {
display: contents !important;
}
.mode-buttons form,
.mode-buttons-cols form,
.mode-buttons-row form,
.filter-group form,
.filters form {
flex-shrink: 0 !important;
width: auto !important;
.filters form,
.activity-filter-grid form {
flex: 0 0 auto !important;
margin: 0 !important;
}
.mode-buttons .filter-btn,
.mode-buttons button,
.filter-group .filter-btn {
.filter-group .filter-btn,
.activity-filter-grid .filter-btn {
width: auto !important;
white-space: nowrap !important;
padding: 8px 14px !important;
min-height: 40px !important;
font-size: 0.85rem !important;
}
/* ---- Columnas de filtros del blockexplorer ---- */
@ -736,110 +732,3 @@ pre, code {
overflow-x: hidden !important;
}
/* ============================================================
MODE-BUTTONS MOBILE ENHANCEMENT (mobile-ui.js)
Scroll horizontal con flechas + expand/collapse
============================================================ */
/* Wrapper: flechas + clip alineados en fila */
.mode-buttons-wrap {
display: flex !important;
align-items: center !important;
gap: 6px !important;
width: 100% !important;
margin-top: 12px !important;
}
/* Clip: oculta lo que no cabe, sin scroll de dedo */
.mode-buttons-clip {
flex: 1 1 0 !important;
min-width: 0 !important;
overflow: hidden !important;
position: relative !important;
}
/* Grid/buttons dentro del clip: una sola fila, ancho del contenido */
.mode-buttons-clip > .mode-buttons,
.mode-buttons-clip > .activity-filter-grid {
display: flex !important;
flex-direction: row !important;
flex-wrap: nowrap !important;
width: max-content !important;
max-width: none !important;
overflow: visible !important;
margin: 0 !important;
padding: 0 !important;
gap: 6px !important;
transition: transform 0.25s ease !important;
will-change: transform !important;
}
/* Flechas de paginación */
.mode-btn-arrow {
flex-shrink: 0 !important;
width: 36px !important;
height: 40px !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
border-radius: 8px !important;
font-size: 1.7rem !important;
font-weight: 700 !important;
line-height: 1 !important;
cursor: pointer !important;
padding: 0 !important;
transition: opacity 0.15s !important;
user-select: none !important;
}
/* Botón "Ver todos / Ver menos" */
.mode-expand-btn {
display: block !important;
width: 100% !important;
margin-top: 6px !important;
padding: 7px 12px !important;
border-radius: 8px !important;
font-size: 0.82rem !important;
font-weight: 600 !important;
text-align: center !important;
cursor: pointer !important;
letter-spacing: 0.02em !important;
}
/* ============================================================
ACTIVITY FILTER GRID (activity_view.js)
En móvil: aplanar las 6 columnas a una fila scrollable
============================================================ */
.activity-filter-grid {
display: flex !important;
flex-direction: row !important;
flex-wrap: nowrap !important;
overflow-x: auto !important;
overflow-y: hidden !important;
-webkit-overflow-scrolling: touch !important;
gap: 6px !important;
padding-bottom: 4px !important;
scrollbar-width: none !important;
width: 100% !important;
margin-top: 0 !important;
}
.activity-filter-grid::-webkit-scrollbar { display: none !important; }
.activity-filter-grid .activity-filter-col {
display: contents !important;
}
.activity-filter-grid form {
flex-shrink: 0 !important;
width: auto !important;
margin: 0 !important;
}
.activity-filter-grid .filter-btn {
width: auto !important;
white-space: nowrap !important;
padding: 8px 14px !important;
min-height: 40px !important;
font-size: 0.85rem !important;
}

View file

@ -1,78 +1,3 @@
(function () {
function setup() {
if (window.innerWidth > 768) return;
document.querySelectorAll('.mode-buttons:not([data-ms]), .activity-filter-grid:not([data-ms])').forEach(function (cnt) {
cnt.dataset.ms = '1';
var items = cnt.querySelectorAll('form, button.filter-btn, a.filter-btn');
if (items.length < 3) return;
// Build pager: [arrow-left] [clip > cnt] [arrow-right]
var wrap = document.createElement('div');
wrap.className = 'mode-buttons-wrap';
cnt.parentNode.insertBefore(wrap, cnt);
var clip = document.createElement('div');
clip.className = 'mode-buttons-clip';
wrap.appendChild(clip);
clip.appendChild(cnt);
var la = document.createElement('button');
la.type = 'button';
la.className = 'mode-btn-arrow mode-btn-arrow-left';
la.innerHTML = '&#8249;';
la.setAttribute('aria-label', 'Anterior');
wrap.insertBefore(la, clip);
var ra = document.createElement('button');
ra.type = 'button';
ra.className = 'mode-btn-arrow mode-btn-arrow-right';
ra.innerHTML = '&#8250;';
ra.setAttribute('aria-label', 'Siguiente');
wrap.appendChild(ra);
var offset = 0;
function step() {
var btn = cnt.querySelector('button.filter-btn, a.filter-btn, form');
var w = btn ? btn.getBoundingClientRect().width : 90;
if (!w || w < 40) w = 90;
return Math.round((w + 6) * 2);
}
function maxOffset() {
return Math.max(0, cnt.scrollWidth - clip.clientWidth);
}
function apply() {
var max = maxOffset();
if (offset > max) offset = max;
if (offset < 0) offset = 0;
cnt.style.transform = 'translateX(' + (-offset) + 'px)';
var atStart = offset <= 0;
var atEnd = offset >= max - 1;
la.style.opacity = atStart ? '0.25' : '1';
la.style.pointerEvents = atStart ? 'none' : 'auto';
ra.style.opacity = atEnd ? '0.25' : '1';
ra.style.pointerEvents = atEnd ? 'none' : 'auto';
}
la.addEventListener('click', function (e) {
e.preventDefault();
offset -= step();
apply();
});
ra.addEventListener('click', function (e) {
e.preventDefault();
offset += step();
apply();
});
setTimeout(apply, 120);
window.addEventListener('resize', apply);
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', setup);
} else {
setup();
}
})();
// mobile-ui.js: ya no se usa.
// La paginación de filtros móvil se hizo en CSS puro con flex-wrap.
// Ver mobile.css → reglas .activity-filter-grid / .mode-buttons.

View file

@ -1055,25 +1055,8 @@ const template = (titlePrefix, ...elements) => {
renderFooter()
)
);
return doctypeString + nodes.outerHTML.replace(
'</body>',
'<script>' + getMobileUiInline() + '</script></body>'
);
return doctypeString + nodes.outerHTML;
};
let _mobileUiCached = null;
function getMobileUiInline() {
if (_mobileUiCached !== null) return _mobileUiCached;
try {
const fs = require('fs');
const path = require('path');
_mobileUiCached = fs.readFileSync(
path.join(__dirname, '..', 'client', 'public', 'js', 'mobile-ui.js'),
'utf8'
);
} catch (e) { _mobileUiCached = ''; }
return _mobileUiCached;
}
// menu END
exports.template = template;