diff --git a/src/backend/fork_routes.js b/src/backend/fork_routes.js index 21471d7..208febb 100644 --- a/src/backend/fork_routes.js +++ b/src/backend/fork_routes.js @@ -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()]); }; diff --git a/src/backend/mobile_layer.js b/src/backend/mobile_layer.js index 0976852..e33da94 100644 --- a/src/backend/mobile_layer.js +++ b/src/backend/mobile_layer.js @@ -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(); }; diff --git a/src/client/assets/styles/mobile_ux.css b/src/client/assets/styles/mobile_ux.css index eb2a903..ee19d50 100644 --- a/src/client/assets/styles/mobile_ux.css +++ b/src/client/assets/styles/mobile_ux.css @@ -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, diff --git a/src/client/assets/translations/i18n_fork.js b/src/client/assets/translations/i18n_fork.js index 9e51ab1..4378fd5 100644 --- a/src/client/assets/translations/i18n_fork.js +++ b/src/client/assets/translations/i18n_fork.js @@ -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: "Рабочий процесс задаёт, какие модули включены. На телефоне ваше оформление не меняется.", diff --git a/src/views/mobile_modules_view.js b/src/views/mobile_modules_view.js index ed51f39..a58f568 100644 --- a/src/views/mobile_modules_view.js +++ b/src/views/mobile_modules_view.js @@ -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' }, diff --git a/src/views/mobile_settings.js b/src/views/mobile_settings.js index bd9f486..b15ccca 100644 --- a/src/views/mobile_settings.js +++ b/src/views/mobile_settings.js @@ -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") ); };