capa encima: fuera lo que miraba las respuestas del dev
Se quita wrapUpstream de fork_routes.js: el aviso de seccion apagada en Modulos, ?saved=1 al guardar y la vuelta a Ajustes tras guardar perfil o saludo. Dependian de las redirecciones del dev y cualquier cambio suyo los rompia sin avisar. Ajustes: Identidad enseña nombre y avatar y lleva a /profile/edit; Saludo lleva a /feed/create, las dos pantallas del dev. Modulos guarda con /save-modules y vuelve a donde decide el dev. mobile_layer.js refresca nombre y avatar al abrir Ajustes en vez de vigilar los POST.
This commit is contained in:
parent
150f6faf82
commit
188bd74195
6 changed files with 58 additions and 164 deletions
|
|
@ -4,61 +4,22 @@
|
|||
// Va en la cadena justo delante de las rutas del dev (backend.js lo monta con una
|
||||
// sola linea). Lo que no atiende pasa al del dev con next(). Aqui viven:
|
||||
// - mobile_layer.js: lanzador, filtro y avatar de la barra de arriba
|
||||
// - wrapUpstream: mira lo que contesta el dev (seccion apagada, guardar modulos,
|
||||
// vuelta a Ajustes desde los formularios de la bienvenida)
|
||||
// - las rutas propias: tema, colores y Modulos en el movil, barra de abajo, identidades
|
||||
//
|
||||
// No se toca lo que contesta el dev (ni sus redirecciones ni su HTML): si hace falta
|
||||
// otra cosa, ruta propia aqui o enlace a la pantalla del dev. Ver GUIA_DE_DESARROLLO.md.
|
||||
//
|
||||
// backend.js es del dev y cambia en 34 de cada 39 versiones: nada de esto va alli.
|
||||
// Ver GUIA_DE_DESARROLLO.md.
|
||||
|
||||
const koaRouter = require("../server/node_modules/@koa/router");
|
||||
const { koaBody } = require("../server/node_modules/koa-body");
|
||||
const compose = require("../server/node_modules/koa-compose");
|
||||
const { isLocalPath } = require("./request_guards");
|
||||
const { ALL_MODULES } = require("../models/workflows_model");
|
||||
const { mobileModulesView, STEMS } = require("../views/mobile_modules_view");
|
||||
const { mobileModulesView } = require("../views/mobile_modules_view");
|
||||
require("../models/fork_workflows").register();
|
||||
|
||||
const isMobile = () => process.env.OASIS_MOBILE === '1';
|
||||
|
||||
// Seccion apagada: upstream responde con una redireccion a /modules sin decir de
|
||||
// donde venia. Este envoltorio la ve pasar y anota que modulo era, para que la
|
||||
// pantalla de Modulos del movil lo diga y ofrezca activarlo. La app es de una
|
||||
// persona, asi que basta con recordar el ultimo unos segundos.
|
||||
const SEGMENT_MOD = { tribe: 'tribes', vote: 'votes', document: 'docs', documents: 'docs', blog: 'blogs', event: 'events',
|
||||
task: 'tasks', calendar: 'calendars', image: 'images', video: 'videos', audio: 'audios', bookmark: 'bookmarks',
|
||||
file: 'files', poll: 'polls', report: 'reports', project: 'projects', shop: 'shops', job: 'jobs', campaign: 'campaigns',
|
||||
podcast: 'podcasts', room: 'rooms', map: 'maps', transfer: 'transfers', pad: 'pads', chat: 'chats', torrent: 'torrents' };
|
||||
const modOfPath = (p) => {
|
||||
const seg = String(p || '').split('/')[1] || '';
|
||||
const mod = STEMS[seg] ? seg : SEGMENT_MOD[seg];
|
||||
return mod && ALL_MODULES.includes(mod) ? mod : null;
|
||||
};
|
||||
let lastBlocked = null;
|
||||
const takeBlocked = () => {
|
||||
const b = lastBlocked && Date.now() - lastBlocked.at < 15000 ? lastBlocked : null;
|
||||
lastBlocked = null;
|
||||
return b;
|
||||
};
|
||||
const wrapUpstream = async (ctx, next) => {
|
||||
await next();
|
||||
if (!isMobile() || ctx.status < 300 || ctx.status >= 400) return;
|
||||
const to = String(ctx.response.get('Location') || '');
|
||||
// identidad y saludo desde Ajustes usan las rutas de la bienvenida (las del dev);
|
||||
// estas vuelven a /welcome y aqui se cambia por el bloque de Ajustes de donde se vino
|
||||
if (ctx.method === 'POST' && /^\/welcome\/(profile|greeting)$/.test(ctx.path) && /^(https?:\/\/[^/]+)?\/welcome$/.test(to)) {
|
||||
const back = String((ctx.request.body || {}).returnTo || '');
|
||||
if (/^\/settings(#[a-z-]+)?$/.test(back)) ctx.redirect(back);
|
||||
return;
|
||||
}
|
||||
// guardar en Modulos: volver con el aviso de guardado
|
||||
if (ctx.method === 'POST' && ctx.path === '/save-modules') { ctx.redirect('/modules?saved=1'); return; }
|
||||
if (ctx.method === 'GET' && ctx.path !== '/modules' && /^(https?:\/\/[^/]+)?\/modules$/.test(to)) {
|
||||
const mod = modOfPath(ctx.path);
|
||||
if (mod) lastBlocked = { mod, path: ctx.path, at: Date.now() };
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = ({ checkMod, getViewerId, getConfig, saveConfig, isLoopbackRequest, sendErrorPage, about }) => {
|
||||
const mobileLayer = require('./mobile_layer')({ getViewerId, about });
|
||||
|
||||
|
|
@ -101,18 +62,7 @@ const mobileLayer = require('./mobile_layer')({ getViewerId, about });
|
|||
// Modulos en el movil: la vista propia (mobile_modules_view.js); en escritorio, la de upstream
|
||||
.get('/modules', async (ctx, next) => {
|
||||
if (!isMobile()) return next();
|
||||
ctx.body = mobileModulesView({ blocked: takeBlocked(), saved: ctx.query.saved === '1' });
|
||||
})
|
||||
// activar un solo modulo desde el aviso de Modulos y volver a donde se queria ir
|
||||
.post('/modules/enable', koaBody(), async (ctx) => {
|
||||
if (!isLoopbackRequest(ctx)) { ctx.status = 403; ctx.body = ''; return; }
|
||||
const mod = String((ctx.request.body || {}).mod || '').replace(/Mod$/, '');
|
||||
if (!ALL_MODULES.includes(mod)) { ctx.redirect('/modules'); return; }
|
||||
const cfg = getConfig();
|
||||
cfg.modules[`${mod}Mod`] = 'on';
|
||||
saveConfig(cfg);
|
||||
const back = String((ctx.request.body || {}).returnTo || '');
|
||||
ctx.redirect(isLocalPath(back) ? back : `/${mod}`);
|
||||
ctx.body = mobileModulesView();
|
||||
})
|
||||
.get("/settings/bottombar", async (ctx) => {
|
||||
ctx.body = require("../views/main_views").bottomBarPickerView();
|
||||
|
|
@ -177,5 +127,5 @@ const mobileLayer = require('./mobile_layer')({ getViewerId, about });
|
|||
setTimeout(() => process.exit(0), 500);
|
||||
});
|
||||
|
||||
return compose([mobileLayer, wrapUpstream, forkRouter.routes()]);
|
||||
return compose([mobileLayer, forkRouter.routes()]);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -33,13 +33,13 @@ module.exports = ({ getViewerId, about }) => {
|
|||
|
||||
return async (ctx, next) => {
|
||||
if (!isMobile() || !isPage(ctx.path)) return next();
|
||||
// al guardar nombre o avatar, la siguiente pagina ya los lee nuevos
|
||||
if (ctx.method === 'POST' && /^\/(welcome\/profile|profile\/edit)$/.test(ctx.path)) { await next(); avatarAt = 0; return; }
|
||||
global.__OASIS_HIVE_FILTER__ = (ctx.path === '/activity' && (ctx.query.hive === 'personal' || ctx.query.hive === 'community')) ? ctx.query.hive : '';
|
||||
// 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)
|
||||
global.__OASIS_SHOW_HIVE__ = false;
|
||||
if (!avatarAt) await refreshAvatar();
|
||||
// en Ajustes el nombre y el avatar se leen al momento (se acaban de cambiar en
|
||||
// /profile/edit, la pantalla del dev); en el resto, como mucho cada minuto
|
||||
if (!avatarAt || ctx.path === '/settings') await refreshAvatar();
|
||||
else if (Date.now() - avatarAt > 60000) refreshAvatar();
|
||||
return next();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -238,19 +238,6 @@
|
|||
padding: 10px 0; background: var(--ux-bg);
|
||||
}
|
||||
.module-save-bar .create-button { width: 100% !important; margin: 0 !important; }
|
||||
.module-saved {
|
||||
padding: 10px 14px !important; margin: 0 0 14px !important; font-weight: 700;
|
||||
border-left: 4px solid var(--ux-ok) !important; background: var(--ux-soft) !important; border-radius: 0 10px 10px 0;
|
||||
}
|
||||
/* la seccion apagada a la que se queria entrar */
|
||||
.main-column div.module-blocked {
|
||||
display: grid; grid-template-columns: 48px 1fr; gap: 12px; align-items: center;
|
||||
padding: 14px; margin: 0 0 20px; border: 3px solid var(--ux-line); border-radius: var(--ux-radius); background: var(--ux-soft);
|
||||
}
|
||||
.module-blocked-ico { width: 48px; height: 48px; padding: 10px; border-radius: 12px; background: var(--ux-bg); }
|
||||
.module-blocked-text { margin: 0 !important; font-weight: 700; font-size: 17px; }
|
||||
.module-blocked form { grid-column: 1 / -1; margin: 0 !important; }
|
||||
.module-blocked .create-button { width: 100% !important; margin: 0 !important; }
|
||||
|
||||
/* ---------- Ajustes: idiomas como fichas de un toque ---------- */
|
||||
.lang-pick { display: grid !important; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 12px; }
|
||||
|
|
@ -643,7 +630,10 @@ body:has(#oasis-menu-toggle:checked) form.oasis-phone-state { display: none !imp
|
|||
.main-column .quick-tile:active .quick-now { color: inherit !important; }
|
||||
.main-column div.quick-links { display: block !important; margin: 0 !important; padding: 0 !important; }
|
||||
.main-column div.quick-links a { display: block !important; text-align: center; margin: 0 0 10px !important; }
|
||||
.main-column section#identity .filter-btn { display: inline-block; margin-top: 12px !important; }
|
||||
.main-column div.quick-identity { display: flex !important; align-items: center; margin: 0 0 14px !important; padding: 0 !important; }
|
||||
.main-column .quick-identity-avatar { width: 56px; height: 56px; border-radius: 50%; margin-right: 12px; border: 2px solid var(--ux-line); object-fit: cover; }
|
||||
.main-column .quick-identity-name { font-size: 18px; font-weight: 700; }
|
||||
.main-column section#identity a.create-button, .main-column section#greeting a.create-button { display: block !important; text-align: center; }
|
||||
|
||||
/* ---------- colores ---------- */
|
||||
/* paletas de un toque, dos por fila, con su muestra (fondo, texto y acento); debajo,
|
||||
|
|
|
|||
|
|
@ -30,10 +30,11 @@ module.exports = {
|
|||
quick_colors: "Colours",
|
||||
quick_community: "Community",
|
||||
quick_greeting: "Greeting",
|
||||
quickProfileMore: "Description and more",
|
||||
quickJoinPub: "Join a pub",
|
||||
quickSeePeers: "Who you sync with",
|
||||
quickGreetingPlaceholder: "Say hello to the community",
|
||||
quickNoName: "No name yet",
|
||||
quickEditProfile: "Change name and picture",
|
||||
quickWriteGreeting: "Write a greeting",
|
||||
welcomeHintColors: "Background, text and highlight colour of the app.",
|
||||
colorsHint: "Tap a palette and it is applied.",
|
||||
colorsSkinNote: "Colours go with the Acampada look; choosing one switches to it.",
|
||||
|
|
@ -90,10 +91,7 @@ module.exports = {
|
|||
tribeMapUrlLabel: "Map link (optional)",
|
||||
tribeHintPrivacy: "Private: only members see it, and it is encrypted. Public: the whole network sees it.",
|
||||
tribeHintMode: "Open: any member can invite people. Strict: only whoever created it can invite.",
|
||||
moduleBlockedText: "{name} is turned off.",
|
||||
moduleBlockedAction: "Turn on {name}",
|
||||
modulesOnCount: "{on} of {total} sections on",
|
||||
modulesSaved: "Saved.",
|
||||
// skins y workflows en el movil (settings_view.js)
|
||||
skinIntroMobile: "Pick how Oasis looks on your phone. It applies as soon as you tap it.",
|
||||
workflowsDescriptionMobile: "A workflow sets which modules are on. On the phone your skin stays as it is.",
|
||||
|
|
@ -154,10 +152,11 @@ module.exports = {
|
|||
quick_colors: "Colores",
|
||||
quick_community: "Comunidad",
|
||||
quick_greeting: "Saludo",
|
||||
quickProfileMore: "Descripción y más",
|
||||
quickJoinPub: "Unirme a un pub",
|
||||
quickSeePeers: "Con quién sincronizas",
|
||||
quickGreetingPlaceholder: "Saluda a la comunidad",
|
||||
quickNoName: "Aún sin nombre",
|
||||
quickEditProfile: "Cambiar nombre y foto",
|
||||
quickWriteGreeting: "Escribir el saludo",
|
||||
welcomeHintColors: "Fondo, texto y color de resalte de la app.",
|
||||
colorsHint: "Toca una paleta y se aplica.",
|
||||
colorsSkinNote: "Los colores van con el aspecto Acampada; al elegir uno se pasa a ese aspecto.",
|
||||
|
|
@ -214,10 +213,7 @@ module.exports = {
|
|||
tribeMapUrlLabel: "Enlace del mapa (opcional)",
|
||||
tribeHintPrivacy: "Privada: solo la ven sus miembros y va cifrada. Pública: la ve toda la red.",
|
||||
tribeHintMode: "Abierta: cualquier miembro puede invitar. Estricta: solo invita quien la creó.",
|
||||
moduleBlockedText: "{name} está desactivado.",
|
||||
moduleBlockedAction: "Activar {name}",
|
||||
modulesOnCount: "{on} de {total} secciones activas",
|
||||
modulesSaved: "Guardado.",
|
||||
// skins y workflows en el movil (settings_view.js)
|
||||
skinIntroMobile: "Elige cómo se ve Oasis en tu móvil. Se aplica al tocarlo.",
|
||||
workflowsDescriptionMobile: "Un workflow fija qué módulos están activos. En el móvil tu skin se queda como está.",
|
||||
|
|
@ -284,10 +280,11 @@ module.exports = {
|
|||
quick_colors: "Couleurs",
|
||||
quick_community: "Communauté",
|
||||
quick_greeting: "Salut",
|
||||
quickProfileMore: "Description et plus",
|
||||
quickJoinPub: "Rejoindre un pub",
|
||||
quickSeePeers: "Avec qui vous synchronisez",
|
||||
quickGreetingPlaceholder: "Dites bonjour à la communauté",
|
||||
quickNoName: "Pas encore de nom",
|
||||
quickEditProfile: "Changer le nom et la photo",
|
||||
quickWriteGreeting: "Écrire un salut",
|
||||
welcomeHintColors: "Fond, texte et couleur d'accent de l'application.",
|
||||
colorsHint: "Touchez une palette et elle s'applique.",
|
||||
colorsSkinNote: "Les couleurs vont avec l'aspect Acampada ; en choisir une passe à cet aspect.",
|
||||
|
|
@ -344,10 +341,7 @@ module.exports = {
|
|||
tribeMapUrlLabel: "Lien de la carte (facultatif)",
|
||||
tribeHintPrivacy: "Privée : seuls ses membres la voient, et elle est chiffrée. Publique : tout le réseau la voit.",
|
||||
tribeHintMode: "Ouverte : tout membre peut inviter. Stricte : seule la personne qui l'a créée invite.",
|
||||
moduleBlockedText: "{name} est désactivé.",
|
||||
moduleBlockedAction: "Activer {name}",
|
||||
modulesOnCount: "{on} sections actives sur {total}",
|
||||
modulesSaved: "Enregistré.",
|
||||
// skins y workflows en el movil (settings_view.js)
|
||||
skinIntroMobile: "Choisis l'apparence d'Oasis sur ton téléphone. Elle s'applique dès que tu touches.",
|
||||
workflowsDescriptionMobile: "Un workflow fixe les modules actifs. Sur le téléphone, ton thème ne change pas.",
|
||||
|
|
@ -408,10 +402,11 @@ module.exports = {
|
|||
quick_colors: "Koloreak",
|
||||
quick_community: "Komunitatea",
|
||||
quick_greeting: "Agurra",
|
||||
quickProfileMore: "Deskribapena eta gehiago",
|
||||
quickJoinPub: "Pub batean sartu",
|
||||
quickSeePeers: "Norekin sinkronizatzen zaren",
|
||||
quickGreetingPlaceholder: "Agurtu komunitatea",
|
||||
quickNoName: "Oraindik izenik gabe",
|
||||
quickEditProfile: "Izena eta argazkia aldatu",
|
||||
quickWriteGreeting: "Agurra idatzi",
|
||||
welcomeHintColors: "Aplikazioaren hondoa, testua eta nabarmentze-kolorea.",
|
||||
colorsHint: "Ukitu paleta bat eta aplikatzen da.",
|
||||
colorsSkinNote: "Koloreak Acampada itxurarekin doaz; bat aukeratzean itxura horretara pasatzen da.",
|
||||
|
|
@ -468,10 +463,7 @@ module.exports = {
|
|||
tribeMapUrlLabel: "Maparen esteka (aukerakoa)",
|
||||
tribeHintPrivacy: "Pribatua: kideek bakarrik ikusten dute, eta zifratuta dago. Publikoa: sare osoak ikusten du.",
|
||||
tribeHintMode: "Irekia: edozein kidek gonbida dezake. Zorrotza: sortu zuenak bakarrik gonbidatzen du.",
|
||||
moduleBlockedText: "{name} desaktibatuta dago.",
|
||||
moduleBlockedAction: "Aktibatu {name}",
|
||||
modulesOnCount: "{total} ataletatik {on} aktibo",
|
||||
modulesSaved: "Gordeta.",
|
||||
// skins y workflows en el movil (settings_view.js)
|
||||
skinIntroMobile: "Aukeratu nolakoa den Oasis zure mugikorrean. Ukitu bezain laster aplikatzen da.",
|
||||
workflowsDescriptionMobile: "Workflow batek zein modulu dauden aktibo finkatzen du. Mugikorrean zure itxura ez da aldatzen.",
|
||||
|
|
@ -532,10 +524,11 @@ module.exports = {
|
|||
quick_colors: "Farben",
|
||||
quick_community: "Gemeinschaft",
|
||||
quick_greeting: "Gruß",
|
||||
quickProfileMore: "Beschreibung und mehr",
|
||||
quickJoinPub: "Einem Pub beitreten",
|
||||
quickSeePeers: "Mit wem du synchronisierst",
|
||||
quickGreetingPlaceholder: "Sag der Gemeinschaft Hallo",
|
||||
quickNoName: "Noch kein Name",
|
||||
quickEditProfile: "Name und Bild ändern",
|
||||
quickWriteGreeting: "Gruß schreiben",
|
||||
welcomeHintColors: "Hintergrund, Text und Akzentfarbe der App.",
|
||||
colorsHint: "Tippe auf eine Palette und sie wird angewendet.",
|
||||
colorsSkinNote: "Die Farben gehören zum Acampada-Design; mit einer Auswahl wechselst du dorthin.",
|
||||
|
|
@ -592,10 +585,7 @@ module.exports = {
|
|||
tribeMapUrlLabel: "Kartenlink (optional)",
|
||||
tribeHintPrivacy: "Privat: nur Mitglieder sehen sie, und sie ist verschlüsselt. Öffentlich: das ganze Netz sieht sie.",
|
||||
tribeHintMode: "Offen: jedes Mitglied kann einladen. Streng: nur wer sie erstellt hat, lädt ein.",
|
||||
moduleBlockedText: "{name} ist ausgeschaltet.",
|
||||
moduleBlockedAction: "{name} einschalten",
|
||||
modulesOnCount: "{on} von {total} Bereichen aktiv",
|
||||
modulesSaved: "Gespeichert.",
|
||||
// skins y workflows en el movil (settings_view.js)
|
||||
skinIntroMobile: "Wähle, wie Oasis auf deinem Handy aussieht. Es wird beim Antippen übernommen.",
|
||||
workflowsDescriptionMobile: "Ein Workflow legt fest, welche Module aktiv sind. Auf dem Handy bleibt dein Skin, wie er ist.",
|
||||
|
|
@ -656,10 +646,11 @@ module.exports = {
|
|||
quick_colors: "Colori",
|
||||
quick_community: "Comunità",
|
||||
quick_greeting: "Saluto",
|
||||
quickProfileMore: "Descrizione e altro",
|
||||
quickJoinPub: "Entra in un pub",
|
||||
quickSeePeers: "Con chi sincronizzi",
|
||||
quickGreetingPlaceholder: "Saluta la comunità",
|
||||
quickNoName: "Ancora senza nome",
|
||||
quickEditProfile: "Cambia nome e foto",
|
||||
quickWriteGreeting: "Scrivi un saluto",
|
||||
welcomeHintColors: "Sfondo, testo e colore di risalto dell'app.",
|
||||
colorsHint: "Tocca una tavolozza e viene applicata.",
|
||||
colorsSkinNote: "I colori vanno con l'aspetto Acampada; sceglierne uno passa a quell'aspetto.",
|
||||
|
|
@ -716,10 +707,7 @@ module.exports = {
|
|||
tribeMapUrlLabel: "Link della mappa (facoltativo)",
|
||||
tribeHintPrivacy: "Privata: la vedono solo i membri ed è cifrata. Pubblica: la vede tutta la rete.",
|
||||
tribeHintMode: "Aperta: qualsiasi membro può invitare. Rigida: invita solo chi l'ha creata.",
|
||||
moduleBlockedText: "{name} è disattivato.",
|
||||
moduleBlockedAction: "Attiva {name}",
|
||||
modulesOnCount: "{on} sezioni attive su {total}",
|
||||
modulesSaved: "Salvato.",
|
||||
// skins y workflows en el movil (settings_view.js)
|
||||
skinIntroMobile: "Scegli come appare Oasis sul tuo telefono. Si applica appena lo tocchi.",
|
||||
workflowsDescriptionMobile: "Un workflow stabilisce quali moduli sono attivi. Sul telefono la tua skin resta com'è.",
|
||||
|
|
@ -780,10 +768,11 @@ module.exports = {
|
|||
quick_colors: "Cores",
|
||||
quick_community: "Comunidade",
|
||||
quick_greeting: "Saudação",
|
||||
quickProfileMore: "Descrição e mais",
|
||||
quickJoinPub: "Entrar num pub",
|
||||
quickSeePeers: "Com quem sincroniza",
|
||||
quickGreetingPlaceholder: "Diga olá à comunidade",
|
||||
quickNoName: "Ainda sem nome",
|
||||
quickEditProfile: "Mudar nome e foto",
|
||||
quickWriteGreeting: "Escrever a saudação",
|
||||
welcomeHintColors: "Fundo, texto e cor de destaque da app.",
|
||||
colorsHint: "Toque numa paleta e ela aplica-se.",
|
||||
colorsSkinNote: "As cores vão com o aspeto Acampada; escolher uma passa para esse aspeto.",
|
||||
|
|
@ -840,10 +829,7 @@ module.exports = {
|
|||
tribeMapUrlLabel: "Ligação do mapa (opcional)",
|
||||
tribeHintPrivacy: "Privada: só os membros a veem e vai cifrada. Pública: toda a rede a vê.",
|
||||
tribeHintMode: "Aberta: qualquer membro pode convidar. Estrita: só convida quem a criou.",
|
||||
moduleBlockedText: "{name} está desativado.",
|
||||
moduleBlockedAction: "Ativar {name}",
|
||||
modulesOnCount: "{on} de {total} secções ativas",
|
||||
modulesSaved: "Guardado.",
|
||||
// skins y workflows en el movil (settings_view.js)
|
||||
skinIntroMobile: "Escolhe como o Oasis aparece no teu telemóvel. Aplica-se ao tocar.",
|
||||
workflowsDescriptionMobile: "Um workflow define que módulos estão ativos. No telemóvel o teu tema fica como está.",
|
||||
|
|
@ -904,10 +890,11 @@ module.exports = {
|
|||
quick_colors: "颜色",
|
||||
quick_community: "社区",
|
||||
quick_greeting: "问候",
|
||||
quickProfileMore: "简介及更多",
|
||||
quickJoinPub: "加入 pub",
|
||||
quickSeePeers: "与谁同步",
|
||||
quickGreetingPlaceholder: "向社区问好",
|
||||
quickNoName: "还没有名字",
|
||||
quickEditProfile: "更改名字和头像",
|
||||
quickWriteGreeting: "写问候",
|
||||
welcomeHintColors: "应用的背景、文字和强调色。",
|
||||
colorsHint: "点一个配色即可应用。",
|
||||
colorsSkinNote: "颜色配合 Acampada 外观;选择后会切换到该外观。",
|
||||
|
|
@ -964,10 +951,7 @@ module.exports = {
|
|||
tribeMapUrlLabel: "地图链接(可选)",
|
||||
tribeHintPrivacy: "私密:只有成员能看到,并且加密。公开:整个网络都能看到。",
|
||||
tribeHintMode: "开放:任何成员都可以邀请。严格:只有创建者可以邀请。",
|
||||
moduleBlockedText: "{name} 已关闭。",
|
||||
moduleBlockedAction: "开启 {name}",
|
||||
modulesOnCount: "已开启 {on}/{total} 个板块",
|
||||
modulesSaved: "已保存。",
|
||||
// skins y workflows en el movil (settings_view.js)
|
||||
skinIntroMobile: "选择 Oasis 在手机上的外观。点一下就会生效。",
|
||||
workflowsDescriptionMobile: "工作流决定启用哪些模块。在手机上,你的外观保持不变。",
|
||||
|
|
@ -1028,10 +1012,11 @@ module.exports = {
|
|||
quick_colors: "الألوان",
|
||||
quick_community: "المجتمع",
|
||||
quick_greeting: "التحية",
|
||||
quickProfileMore: "الوصف والمزيد",
|
||||
quickJoinPub: "الانضمام إلى pub",
|
||||
quickSeePeers: "مع من تتزامن",
|
||||
quickGreetingPlaceholder: "قل مرحبًا للمجتمع",
|
||||
quickNoName: "لا اسم بعد",
|
||||
quickEditProfile: "تغيير الاسم والصورة",
|
||||
quickWriteGreeting: "كتابة التحية",
|
||||
welcomeHintColors: "لون الخلفية والنص والتمييز في التطبيق.",
|
||||
colorsHint: "المس لوحة ألوان فتُطبَّق.",
|
||||
colorsSkinNote: "الألوان تأتي مع مظهر Acampada؛ اختيار لون ينقلك إليه.",
|
||||
|
|
@ -1088,10 +1073,7 @@ module.exports = {
|
|||
tribeMapUrlLabel: "رابط الخريطة (اختياري)",
|
||||
tribeHintPrivacy: "خاصة: يراها أعضاؤها فقط وهي مشفّرة. عامة: تراها الشبكة كلها.",
|
||||
tribeHintMode: "مفتوحة: يمكن لأي عضو أن يدعو. صارمة: لا يدعو إلا من أنشأها.",
|
||||
moduleBlockedText: "{name} مُعطّل.",
|
||||
moduleBlockedAction: "تفعيل {name}",
|
||||
modulesOnCount: "{on} من {total} أقسام مفعّلة",
|
||||
modulesSaved: "تم الحفظ.",
|
||||
// skins y workflows en el movil (settings_view.js)
|
||||
skinIntroMobile: "اختر مظهر Oasis على هاتفك. يُطبَّق بمجرد اللمس.",
|
||||
workflowsDescriptionMobile: "يحدد سير العمل الوحدات المفعّلة. على الهاتف يبقى مظهرك كما هو.",
|
||||
|
|
@ -1152,10 +1134,11 @@ module.exports = {
|
|||
quick_colors: "रंग",
|
||||
quick_community: "समुदाय",
|
||||
quick_greeting: "अभिवादन",
|
||||
quickProfileMore: "विवरण और अधिक",
|
||||
quickJoinPub: "किसी pub से जुड़ें",
|
||||
quickSeePeers: "आप किसके साथ सिंक करते हैं",
|
||||
quickGreetingPlaceholder: "समुदाय को नमस्ते कहें",
|
||||
quickNoName: "अभी कोई नाम नहीं",
|
||||
quickEditProfile: "नाम और तस्वीर बदलें",
|
||||
quickWriteGreeting: "अभिवादन लिखें",
|
||||
welcomeHintColors: "ऐप का पृष्ठभूमि, टेक्स्ट और हाइलाइट रंग।",
|
||||
colorsHint: "किसी पैलेट पर टैप करें और वह लागू हो जाएगा।",
|
||||
colorsSkinNote: "रंग Acampada रूप के साथ चलते हैं; कोई चुनने पर वही रूप लग जाता है।",
|
||||
|
|
@ -1212,10 +1195,7 @@ module.exports = {
|
|||
tribeMapUrlLabel: "नक्शे का लिंक (वैकल्पिक)",
|
||||
tribeHintPrivacy: "निजी: केवल सदस्य देखते हैं, और यह एन्क्रिप्टेड है। सार्वजनिक: पूरा नेटवर्क देखता है।",
|
||||
tribeHintMode: "खुला: कोई भी सदस्य आमंत्रित कर सकता है। सख़्त: केवल बनाने वाला आमंत्रित करता है।",
|
||||
moduleBlockedText: "{name} बंद है।",
|
||||
moduleBlockedAction: "{name} चालू करें",
|
||||
modulesOnCount: "{total} में से {on} खंड चालू",
|
||||
modulesSaved: "सहेजा गया।",
|
||||
// skins y workflows en el movil (settings_view.js)
|
||||
skinIntroMobile: "चुनें कि आपके फ़ोन पर Oasis कैसा दिखे। छूते ही लागू हो जाता है।",
|
||||
workflowsDescriptionMobile: "वर्कफ़्लो तय करता है कि कौन-से मॉड्यूल चालू हैं। फ़ोन पर आपकी स्किन वैसी ही रहती है।",
|
||||
|
|
@ -1276,10 +1256,11 @@ module.exports = {
|
|||
quick_colors: "Цвета",
|
||||
quick_community: "Сообщество",
|
||||
quick_greeting: "Приветствие",
|
||||
quickProfileMore: "Описание и другое",
|
||||
quickJoinPub: "Войти в pub",
|
||||
quickSeePeers: "С кем вы синхронизируетесь",
|
||||
quickGreetingPlaceholder: "Поздоровайтесь с сообществом",
|
||||
quickNoName: "Пока без имени",
|
||||
quickEditProfile: "Изменить имя и фото",
|
||||
quickWriteGreeting: "Написать приветствие",
|
||||
welcomeHintColors: "Фон, текст и цвет выделения в приложении.",
|
||||
colorsHint: "Нажмите на палитру, и она применится.",
|
||||
colorsSkinNote: "Цвета идут с оформлением Acampada; при выборе включается оно.",
|
||||
|
|
@ -1336,10 +1317,7 @@ module.exports = {
|
|||
tribeMapUrlLabel: "Ссылка на карту (необязательно)",
|
||||
tribeHintPrivacy: "Закрытое: видят только участники, и оно зашифровано. Открытое: видит вся сеть.",
|
||||
tribeHintMode: "Открытое: приглашать может любой участник. Строгое: приглашает только создатель.",
|
||||
moduleBlockedText: "{name} выключен.",
|
||||
moduleBlockedAction: "Включить {name}",
|
||||
modulesOnCount: "Включено {on} из {total} разделов",
|
||||
modulesSaved: "Сохранено.",
|
||||
// skins y workflows en el movil (settings_view.js)
|
||||
skinIntroMobile: "Выберите, как Oasis выглядит на телефоне. Применяется сразу по нажатию.",
|
||||
workflowsDescriptionMobile: "Рабочий процесс задаёт, какие модули включены. На телефоне ваше оформление не меняется.",
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ const MOBILE_UNAVAILABLE = ['ai', 'aiNav', 'dev', 'games', 'logs', 'maps', 'pixe
|
|||
|
||||
const moduleLabel = (i18n, name) => i18n[`modules${STEMS[name]}Label`] || name;
|
||||
|
||||
const mobileModulesView = (opts = {}) => {
|
||||
const mobileModulesView = () => {
|
||||
const { template, i18n, LAUNCHER_GROUPS } = require('./main_views');
|
||||
const config = getConfig().modules || {};
|
||||
const visible = Object.keys(STEMS)
|
||||
|
|
@ -56,17 +56,6 @@ const mobileModulesView = (opts = {}) => {
|
|||
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' },
|
||||
|
|
@ -74,8 +63,6 @@ const mobileModulesView = (opts = {}) => {
|
|||
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' },
|
||||
|
|
|
|||
|
|
@ -6,16 +6,15 @@
|
|||
// rejilla con esos cinco y un sexto, Colores; cada acceso baja a su bloque, y cada
|
||||
// bloque guarda al tocar, igual que en la bienvenida.
|
||||
//
|
||||
// Los formularios de identidad y saludo envian a las rutas del dev (/welcome/profile,
|
||||
// /welcome/greeting) con un returnTo; fork_routes.js cambia su redireccion a
|
||||
// /welcome por la vuelta a Ajustes. Colores es propio: /settings/colors y la hoja
|
||||
// /mobile-colors.css, que va la ultima.
|
||||
// Identidad y saludo llevan a las pantallas del dev que ya lo hacen (/profile/edit y
|
||||
// /feed/create): no se reenvia nada a sus rutas ni se toca lo que contestan. Colores
|
||||
// es propio: /settings/colors y la hoja /mobile-colors.css, que va la ultima.
|
||||
//
|
||||
// Los colores son las variables --a26-* del tema Acampada; por eso al elegir colores
|
||||
// el aspecto pasa a Acampada (OasisMobile.css es del dev y lleva los suyos fijos).
|
||||
|
||||
const crypto = require("crypto");
|
||||
const { a, button, details, div, form, img, input, label, p, section, span, summary, textarea, h2 } = require("../server/node_modules/hyperaxe");
|
||||
const { a, button, details, div, form, img, input, label, p, section, span, summary, h2 } = require("../server/node_modules/hyperaxe");
|
||||
const { iconNode } = require("./mobile_icons");
|
||||
|
||||
const t = () => require("./main_views").i18n;
|
||||
|
|
@ -178,23 +177,17 @@ const quickGrid = (cfg, present) => {
|
|||
|
||||
// ---------- bloques nuevos de Ajustes ----------
|
||||
|
||||
const RETURN = (id) => `/settings#${id}`;
|
||||
|
||||
const identitySection = () => {
|
||||
const i18n = t();
|
||||
const avatar = global.__OASIS_SELF_AVATAR__;
|
||||
const name = global.__OASIS_SELF_NAME__;
|
||||
return section({ id: "identity" },
|
||||
div({ class: "tags-header" }, h2(i18n.quick_identity || i18n.welcomeStepIdentity), p(i18n.welcomeHintIdentity)),
|
||||
form({ method: "POST", action: "/welcome/profile", enctype: "multipart/form-data", class: "welcome-profile-form" },
|
||||
input({ type: "hidden", name: "returnTo", value: RETURN("identity") }),
|
||||
label({ for: "set-name" }, i18n.profileName),
|
||||
input({ type: "text", id: "set-name", name: "name", maxlength: "80", value: global.__OASIS_SELF_NAME__ || "" }),
|
||||
label({ for: "set-image" }, i18n.profileImage),
|
||||
avatar ? img({ class: "welcome-profile-avatar", src: avatar, alt: "" }) : null,
|
||||
input({ type: "file", id: "set-image", name: "image", accept: "image/*" }),
|
||||
button({ type: "submit" }, i18n.welcomeStepProfileAction)
|
||||
div({ class: "quick-identity" },
|
||||
avatar ? img({ class: "quick-identity-avatar", src: avatar, alt: "" }) : null,
|
||||
span({ class: "quick-identity-name" }, name || i18n.quickNoName || "No name yet")
|
||||
),
|
||||
a({ href: "/profile/edit", class: "filter-btn" }, i18n.quickProfileMore || "Description and more")
|
||||
a({ href: "/profile/edit", class: "create-button" }, i18n.quickEditProfile || "Change name and picture")
|
||||
);
|
||||
};
|
||||
|
||||
|
|
@ -202,7 +195,7 @@ const colorsSection = () => {
|
|||
const i18n = t();
|
||||
return section({ id: "colors" },
|
||||
div({ class: "tags-header" }, h2(i18n.quick_colors || "Colours")),
|
||||
colorsPick(RETURN("colors"), false)
|
||||
colorsPick("/settings#colors", false)
|
||||
);
|
||||
};
|
||||
|
||||
|
|
@ -221,11 +214,7 @@ const greetingSection = () => {
|
|||
const i18n = t();
|
||||
return section({ id: "greeting" },
|
||||
div({ class: "tags-header" }, h2(i18n.quick_greeting || i18n.welcomeStepIntro), p(i18n.welcomeHintIntro)),
|
||||
form({ method: "POST", action: "/welcome/greeting", class: "welcome-greeting-form" },
|
||||
input({ type: "hidden", name: "returnTo", value: RETURN("greeting") }),
|
||||
textarea({ name: "text", required: true, minlength: "1", maxlength: "280", rows: 3, placeholder: i18n.quickGreetingPlaceholder || "" }),
|
||||
button({ type: "submit" }, i18n.welcomeStepGreetingAction)
|
||||
)
|
||||
a({ href: "/feed/create", class: "create-button" }, i18n.quickWriteGreeting || "Write a greeting")
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue