skins: elegir el aspecto en el movil con tarjetas de un toque

En Ajustes del movil, Tema y Flujos de trabajo dejan de ser desplegables:
cada skin es una tarjeta con su miniatura y cada workflow un boton grande,
y se aplican al tocarlos. Solo se ofrecen los skins que tienen maqueta de
movil (Acampada y Oasis Mobile); el servidor rechaza un tema de escritorio,
que dejaba la app sin maqueta. La bienvenida tambien ofrece elegir skin.

Aplicar un workflow ya no cambia el skin: se queda el que haya elegido cada
cual.

OasisMobile.css se carga con su propio <link> versionado antes de
Acampada.css, en vez de con @import: el @import sin ?v= se quedaba en la
cache del WebView y tras actualizar se veia la maqueta vieja.
This commit is contained in:
oasis-bot 2026-10-19 02:17:12 +02:00
parent ac921c9d56
commit 0baf85faa9
9 changed files with 103 additions and 17 deletions

View file

@ -2,7 +2,7 @@ const { form, button, div, h2, h3, p, section, select, option, input, br, a, lab
const fs = require('fs');
const path = require('path');
const { getConfig } = require('../configs/config-manager.js');
const { template, selectedLanguage, i18n, setLanguage, INBOX_BOT_ORDER, inboxBotLabel, THEMES, userLink } = require('./main_views');
const { template, selectedLanguage, i18n, setLanguage, INBOX_BOT_ORDER, inboxBotLabel, THEMES, MOBILE_THEMES, userLink } = require('./main_views');
const i18nBase = require("../client/assets/translations/i18n");
const moment = require("../server/node_modules/moment");
const { WORKFLOWS, currentWorkflow } = require('../models/workflows_model');
@ -58,7 +58,26 @@ const settingsView = (params) => {
const modOn = (name) => (currentConfig.modules || {})[`${name}Mod`] === 'on';
const isMobile = process.env.OASIS_MOBILE === '1';
const workflowSection = section({ id: "workflows" },
// movil: skins y workflows como tarjetas que se aplican al tocarlas (un boton
// de envio por opcion); el desplegable de escritorio quedaba enterrado y dejaba
// poner temas de escritorio, que en el movil se quedan sin maqueta
const skinPicker = () => section({ id: "theme" },
div({ class: "tags-header" }, h2(i18n.theme), p(i18n.skinIntroMobile)),
form({ action: "/settings/theme", method: "post", class: "skin-pick" },
...MOBILE_THEMES.map(([value, name]) => button({ type: "submit", name: "theme", value, class: theme === value ? "skin-card is-current" : "skin-card" },
img({ src: `/assets/images/theme-${value.toLowerCase()}.png`, alt: "", class: "skin-shot" }),
span({ class: "skin-name" }, name)))
)
);
const workflowPicker = () => section({ id: "workflows" },
div({ class: "tags-header" }, h2(i18n.workflowsTitle), p(i18n.workflowsDescriptionMobile)),
form({ action: "/settings/workflow", method: "POST", class: "workflow-pick" },
...WORKFLOWS.map(w => button({ type: "submit", name: "workflow", value: w.key, class: activeWorkflow === w.key ? "workflow-card is-current" : "workflow-card" },
i18n[`workflow_${w.key}`] || w.key))
)
);
const workflowSection = isMobile ? workflowPicker() : section({ id: "workflows" },
div({ class: "tags-header" },
h2(i18n.workflowsTitle),
p(i18n.workflowsDescription),
@ -181,7 +200,7 @@ const settingsView = (params) => {
)
)
),
section({ id: "theme" },
isMobile ? skinPicker() : section({ id: "theme" },
div({ class: "tags-header" },
h2(i18n.theme),
p(i18n.themeIntro),