docs/FRONTERA_UPSTREAM.md mide como cambia upstream (39 releases de la 1.0.1 a la 1.3.3; backend.js en 34, main_views en 31, OasisMobile.css en 21) y fija que se toca: backend, middleware, modelos, server y traducciones de upstream, no; vistas de upstream, solo una linea de gancho; hojas, vistas, router y modelos propios, si. Fase A, lo del 19/10: - backend.js, workflows_model.js y modules_view.js vuelven a como estaban - seccion apagada, /modules/enable y ?saved=1: en el router propio, que envuelve las redirecciones de upstream en vez de cambiar checkMod - Modulos del movil en views/mobile_modules_view.js, servida por el router propio - workflow propio "acampada" registrado desde models/fork_workflows.js en vez de redefinir "activists" - votaciones, tribus, ajustes, borrar, pie y bienvenida: la logica en views/mobile_ui.js; en cada vista de upstream queda la llamada
103 lines
5.6 KiB
JavaScript
103 lines
5.6 KiB
JavaScript
"use strict";
|
|
// Pantalla de Modulos del movil (la sirve el router propio, karvan_routes.js).
|
|
//
|
|
// Los modulos agrupados como en el lanzador, cada uno una fila que se toca entera con
|
|
// un interruptor, y Guardar siempre a la vista. La tabla de upstream eran 52 filas
|
|
// con casillas de 16px, unas 11 pantallas. Va en un fichero propio para no tocar
|
|
// modules_view.js, que es del dev (docs/FRONTERA_UPSTREAM.md).
|
|
//
|
|
// El formulario envia a la misma ruta de upstream (/save-modules) con los mismos
|
|
// nombres de campo (<modulo>Form), asi que guardar sigue siendo cosa suya.
|
|
|
|
const { button, div, form, h2, h3, input, label, p, section, span } = require("../server/node_modules/hyperaxe");
|
|
const { getConfig } = require('../configs/config-manager.js');
|
|
const { iconNode } = require('./mobile_icons');
|
|
|
|
// clave de i18n de cada modulo (modules<Stem>Label / modules<Stem>Description)
|
|
const STEMS = {
|
|
agenda: 'Agenda', ai: 'AI', aiNav: 'AINav', emergencies: 'Emergencies', mailing: 'Mailing', rooms: 'Rooms',
|
|
phone: 'Phone', logistics: 'Logistics', podcasts: 'Podcasts', campaigns: 'Campaigns', audios: 'Audios', banking: 'Banking',
|
|
bookmarks: 'Bookmarks', calendars: 'Calendars', chats: 'Chats', cipher: 'Cipher', courts: 'Courts', dev: 'Dev',
|
|
docs: 'Docs', events: 'Events', favorites: 'Favorites', blogs: 'Blogs', fediverse: 'Fediverse', feed: 'Feed',
|
|
files: 'Files', forum: 'Forum', games: 'Games', graphos: 'Graphos', housing: 'Housing', images: 'Images',
|
|
industry: 'Industry', invites: 'Invites', jobs: 'Jobs', karvan: 'Karvan', larp: 'Larp', backup: 'Backup',
|
|
logs: 'Logs', maps: 'Map', market: 'Market', melody: 'Melody', opinions: 'Opinions', pads: 'Pads',
|
|
parliament: 'Parliament', pixelia: 'Pixelia', polls: 'Polls', projects: 'Projects', reports: 'Reports', school: 'School',
|
|
shops: 'Shops', tags: 'Tags', tasks: 'Tasks', torrents: 'Torrents', transfers: 'Transfers', trending: 'Trending',
|
|
tribes: 'Tribes', videos: 'Videos', votes: 'Votations', wallet: 'Wallet', wiki: 'Wiki'
|
|
};
|
|
// los que no van en el movil (los apaga tambien /save-modules)
|
|
const MOBILE_UNAVAILABLE = ['ai', 'aiNav', 'dev', 'games', 'logs', 'maps', 'pixelia'];
|
|
|
|
const moduleLabel = (i18n, name) => i18n[`modules${STEMS[name]}Label`] || name;
|
|
|
|
const mobileModulesView = (opts = {}) => {
|
|
const { template, i18n, LAUNCHER_GROUPS } = require('./main_views');
|
|
const config = getConfig().modules || {};
|
|
const visible = Object.keys(STEMS)
|
|
.filter(name => !MOBILE_UNAVAILABLE.includes(name))
|
|
.map(name => ({ name, label: moduleLabel(i18n, name), description: i18n[`modules${STEMS[name]}Description`] || '' }))
|
|
.sort((x, y) => String(x.label).localeCompare(String(y.label), undefined, { sensitivity: 'base' }));
|
|
const isOn = (m) => config[`${m.name}Mod`] === 'on';
|
|
|
|
// grupos del lanzador; Industria va con la economia y lo demas, al final
|
|
const groupOf = {};
|
|
(LAUNCHER_GROUPS || []).forEach(g => g.mods.forEach(m => { if (m.mod) groupOf[m.mod.replace(/Mod$/, '')] = g; }));
|
|
const economy = (LAUNCHER_GROUPS || []).find(g => g.id === 'economy');
|
|
if (economy && !groupOf.industry) groupOf.industry = economy;
|
|
const groups = [];
|
|
const byId = {};
|
|
visible.forEach(mod => {
|
|
const g = groupOf[mod.name] || { id: 'other', titleKey: 'menuTools' };
|
|
if (!byId[g.id]) { byId[g.id] = { g, mods: [] }; groups.push(byId[g.id]); }
|
|
byId[g.id].mods.push(mod);
|
|
});
|
|
const order = (LAUNCHER_GROUPS || []).map(g => g.id);
|
|
const rank = (id) => { const i = order.indexOf(id); return i === -1 ? order.length : i; };
|
|
groups.sort((x, y) => rank(x.g.id) - rank(y.g.id));
|
|
|
|
const blocked = opts.blocked && visible.find(m => m.name === opts.blocked.mod);
|
|
const blockedBox = blocked ? div({ class: 'module-blocked' },
|
|
iconNode('module-blocked-ico', blocked.name),
|
|
p({ class: 'module-blocked-text' }, String(i18n.moduleBlockedText || '{name} is turned off.').replace('{name}', blocked.label)),
|
|
form({ method: 'POST', action: '/modules/enable' },
|
|
input({ type: 'hidden', name: 'mod', value: blocked.name }),
|
|
input({ type: 'hidden', name: 'returnTo', value: opts.blocked.path || `/${blocked.name}` }),
|
|
button({ type: 'submit', class: 'create-button' }, String(i18n.moduleBlockedAction || 'Turn on {name}').replace('{name}', blocked.label))
|
|
)
|
|
) : null;
|
|
|
|
return template(
|
|
i18n.modules,
|
|
section(div({ class: 'tags-header module-header-line' },
|
|
h2(i18n.modulesViewTitle),
|
|
p(String(i18n.modulesOnCount || '{on} of {total} sections on')
|
|
.replace('{on}', visible.filter(isOn).length).replace('{total}', visible.length))
|
|
)),
|
|
blockedBox,
|
|
opts.saved ? p({ class: 'module-saved', role: 'status' }, i18n.modulesSaved || 'Saved.') : null,
|
|
section(
|
|
form({ action: '/save-modules', method: 'post', class: 'module-switches' },
|
|
...groups.map(({ g, mods }) => div({ class: 'module-group' },
|
|
h3({ class: 'module-group-title' }, i18n[g.titleKey] || g.id),
|
|
...mods.map(mod => label({ class: 'module-switch', for: `${mod.name}Mod` },
|
|
iconNode('module-switch-ico', mod.name),
|
|
span({ class: 'module-switch-text' },
|
|
span({ class: 'module-switch-name' }, mod.label),
|
|
span({ class: 'module-switch-desc' }, mod.description)
|
|
),
|
|
input({
|
|
type: 'checkbox', role: 'switch', id: `${mod.name}Mod`, name: `${mod.name}Form`, value: 'on', class: 'switch-input',
|
|
checked: isOn(mod) ? true : undefined
|
|
})
|
|
))
|
|
)),
|
|
div({ class: 'module-save-bar' },
|
|
button({ type: 'submit', class: 'create-button' }, i18n.saveSettings)
|
|
)
|
|
)
|
|
)
|
|
);
|
|
};
|
|
|
|
module.exports = { mobileModulesView, MOBILE_UNAVAILABLE, STEMS };
|