interfaz: lanzador de modulos en lugar de los hexagonos
La portada ordena los modulos por secciones en una rejilla de iconos, como el cajon de apps del movil. Solo salen los modulos activos y las secciones que tienen alguno; Personal y Social de la topbar parten el lanzador en dos. Fuera los enlaces que ya no existen en 1.3.1 (/legacy, /public/latest/*) y dentro los modulos nuevos: wiki, rooms, emergencias, mailing, campanas... 1.3.1 trae en mobile.css su propio chrome movil (cabecera fija y cajones); se apaga desde el tema para que no se monte encima del de la rama.
This commit is contained in:
parent
a11a730c26
commit
5a04113330
2 changed files with 152 additions and 166 deletions
|
|
@ -42,7 +42,7 @@ body { overflow-x: clip; overflow-y: visible; }
|
|||
|
||||
body { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }
|
||||
|
||||
/* topbar FIJA arriba: [logo] [Personal] [Community] [avatar]; el hive scrollea por debajo */
|
||||
/* topbar FIJA arriba: [logo] [Personal] [Community] [avatar]; el lanzador scrollea por debajo */
|
||||
.oasis-mobile-topbar {
|
||||
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
|
|
@ -80,8 +80,8 @@ body { padding-top: 84px; background: #121212; }
|
|||
|
||||
/* ANULAR el "card" global de style.css `div{background:#222;border-radius:10px;box-shadow;padding:20px;margin-bottom:20px}`
|
||||
en nuestro chrome móvil propio: era el 2º color (caja mas clara) detras de los botones,
|
||||
la caja redondeada de la topbar y el fondo #222 detras de los hexagonos. */
|
||||
.header, .hive-nav, .hive-grid, .hive-cats, .hive-row,
|
||||
la caja redondeada de la topbar y el fondo #222 detras del lanzador. */
|
||||
.header, .launcher, .ln-group, .ln-grid,
|
||||
.oasis-mobile-topbar, .oasis-mobile-topbar .omt-menus {
|
||||
background-color: transparent; box-shadow: none; border-radius: 0;
|
||||
}
|
||||
|
|
@ -209,7 +209,7 @@ body { overscroll-behavior: none; }
|
|||
|
||||
.main-content, .main-column, .header { overflow: visible; }
|
||||
|
||||
/* === Usabilidad 0.9.1: Personal/Community filtran el hive server-side (enlaces ?hive=) + desplegable FILTER === */
|
||||
/* === Usabilidad 0.9.1: Personal/Community filtran el lanzador server-side (enlaces ?hive=) + desplegable FILTER === */
|
||||
|
||||
/* desplegable FILTER de la ristra de filtros de Activity (oculto por defecto) */
|
||||
.activity-filter-toggle { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; margin: 0; }
|
||||
|
|
@ -252,77 +252,36 @@ body { overscroll-behavior: none; }
|
|||
margin-top: 16px; min-height: 48px; line-height: 48px;
|
||||
}
|
||||
|
||||
.hive-nav { --hx: min(64px, calc((100vw - 40px) / 4)); --hxm: min(58px, calc((100vw - 36px) / 5)); margin: 8px 0 16px; overflow: visible; background: transparent; padding: 0; border: 0; box-shadow: none; }
|
||||
.hive-radio { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
|
||||
.hive-grid { display: flex; flex-direction: column; align-items: center; overflow: visible; background: transparent; padding: 0; margin: 0; box-shadow: none; }
|
||||
.hive-row { display: flex; justify-content: center; gap: 3px; overflow: visible; background: transparent; padding: 0; margin: 0; box-shadow: none; }
|
||||
.hive-cats .hive-row + .hive-row { margin-top: calc(var(--hx) * -0.30); }
|
||||
.hex-cat, .hex-mod {
|
||||
position: relative;
|
||||
-webkit-clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
|
||||
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
|
||||
display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
|
||||
text-decoration: none; cursor: pointer; box-sizing: border-box;
|
||||
background: #FFD700;
|
||||
filter: drop-shadow(0 1px 2px rgba(0,0,0,.6));
|
||||
/* Lanzador de modulos de la home (sustituye a los hexagonos): secciones con un
|
||||
rotulo discreto y una rejilla de baldosas, como el cajon de apps del movil */
|
||||
.launcher { margin: 6px 0 20px; padding: 0; border: 0; }
|
||||
.ln-group { margin: 0; padding: 0; border: 0; }
|
||||
.ln-group + .ln-group { margin-top: 20px; }
|
||||
.ln-title {
|
||||
margin: 0 2px 10px; padding: 0; border: 0;
|
||||
font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
|
||||
color: var(--c-muted);
|
||||
}
|
||||
.hex-cat::before, .hex-mod::before {
|
||||
content: ''; position: absolute; inset: 1.5px; z-index: 0;
|
||||
-webkit-clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
|
||||
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
|
||||
background: #161616;
|
||||
.ln-grid {
|
||||
display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 14px 8px; margin: 0; padding: 0;
|
||||
}
|
||||
.ln-app {
|
||||
display: flex; flex-direction: column; align-items: center; gap: 6px;
|
||||
min-width: 0; text-decoration: none; -webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.ln-ico {
|
||||
width: 54px; height: 54px; box-sizing: border-box;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
border-radius: 16px; background: #1c1c1c; border: 1px solid #333;
|
||||
color: #FFD700; font-size: 22px; line-height: 1;
|
||||
transition: background-color .12s, border-color .12s;
|
||||
}
|
||||
.ln-app:active .ln-ico, .ln-app:focus-visible .ln-ico { background: #2a2412; border-color: #FFD700; }
|
||||
.ln-lbl {
|
||||
max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||||
font-size: 11px; line-height: 1.2; text-align: center; color: #e6e6e6;
|
||||
}
|
||||
.hex-cat { width: var(--hx); height: calc(var(--hx) * 1.15); }
|
||||
.hex-mod { width: var(--hxm); height: calc(var(--hxm) * 1.15); }
|
||||
.hex-cat .hx-ico, .hex-mod .hx-ico { color: #FFD700; line-height: 1; position: relative; z-index: 1; }
|
||||
.hex-cat .hx-ico { font-size: 17px; }
|
||||
.hex-mod .hx-ico { font-size: 16px; }
|
||||
.hex-cat .hx-lbl, .hex-mod .hx-lbl { color: #FFD700; text-align: center; line-height: 1; font-weight: bold; overflow: hidden; position: relative; z-index: 1; }
|
||||
.hex-cat .hx-lbl { font-size: 8px; max-width: 88%; }
|
||||
.hex-mod .hx-lbl { font-size: 8px; max-width: 92%; }
|
||||
.hex-cat:active::before, .hex-mod:active::before { background: #242424; }
|
||||
#hive-personal:checked ~ .hive-grid .hex-cat[for="hive-personal"],
|
||||
#hive-governance:checked ~ .hive-grid .hex-cat[for="hive-governance"],
|
||||
#hive-office:checked ~ .hive-grid .hex-cat[for="hive-office"],
|
||||
#hive-economy:checked ~ .hive-grid .hex-cat[for="hive-economy"],
|
||||
#hive-tools:checked ~ .hive-grid .hex-cat[for="hive-tools"],
|
||||
#hive-network:checked ~ .hive-grid .hex-cat[for="hive-network"],
|
||||
#hive-blogs:checked ~ .hive-grid .hex-cat[for="hive-blogs"],
|
||||
#hive-creative:checked ~ .hive-grid .hex-cat[for="hive-creative"],
|
||||
#hive-media:checked ~ .hive-grid .hex-cat[for="hive-media"],
|
||||
#hive-fediverse:checked ~ .hive-grid .hex-cat[for="hive-fediverse"] { background: #FFD700; }
|
||||
#hive-personal:checked ~ .hive-grid .hex-cat[for="hive-personal"]::before,
|
||||
#hive-governance:checked ~ .hive-grid .hex-cat[for="hive-governance"]::before,
|
||||
#hive-office:checked ~ .hive-grid .hex-cat[for="hive-office"]::before,
|
||||
#hive-economy:checked ~ .hive-grid .hex-cat[for="hive-economy"]::before,
|
||||
#hive-tools:checked ~ .hive-grid .hex-cat[for="hive-tools"]::before,
|
||||
#hive-network:checked ~ .hive-grid .hex-cat[for="hive-network"]::before,
|
||||
#hive-blogs:checked ~ .hive-grid .hex-cat[for="hive-blogs"]::before,
|
||||
#hive-creative:checked ~ .hive-grid .hex-cat[for="hive-creative"]::before,
|
||||
#hive-media:checked ~ .hive-grid .hex-cat[for="hive-media"]::before,
|
||||
#hive-fediverse:checked ~ .hive-grid .hex-cat[for="hive-fediverse"]::before { background: #FFD700; }
|
||||
#hive-personal:checked ~ .hive-grid .hex-cat[for="hive-personal"] :is(.hx-ico,.hx-lbl),
|
||||
#hive-governance:checked ~ .hive-grid .hex-cat[for="hive-governance"] :is(.hx-ico,.hx-lbl),
|
||||
#hive-office:checked ~ .hive-grid .hex-cat[for="hive-office"] :is(.hx-ico,.hx-lbl),
|
||||
#hive-economy:checked ~ .hive-grid .hex-cat[for="hive-economy"] :is(.hx-ico,.hx-lbl),
|
||||
#hive-tools:checked ~ .hive-grid .hex-cat[for="hive-tools"] :is(.hx-ico,.hx-lbl),
|
||||
#hive-network:checked ~ .hive-grid .hex-cat[for="hive-network"] :is(.hx-ico,.hx-lbl),
|
||||
#hive-blogs:checked ~ .hive-grid .hex-cat[for="hive-blogs"] :is(.hx-ico,.hx-lbl),
|
||||
#hive-creative:checked ~ .hive-grid .hex-cat[for="hive-creative"] :is(.hx-ico,.hx-lbl),
|
||||
#hive-media:checked ~ .hive-grid .hex-cat[for="hive-media"] :is(.hx-ico,.hx-lbl),
|
||||
#hive-fediverse:checked ~ .hive-grid .hex-cat[for="hive-fediverse"] :is(.hx-ico,.hx-lbl) { color: #121212; }
|
||||
.hive-panel { display: none; margin: 12px auto 0; max-width: 340px; background: #101010; border: 1px solid #242424; border-radius: 16px; padding: 12px 8px; overflow: visible; box-shadow: none; }
|
||||
#hive-personal:checked ~ #hive-panel-personal,
|
||||
#hive-governance:checked ~ #hive-panel-governance,
|
||||
#hive-office:checked ~ #hive-panel-office,
|
||||
#hive-economy:checked ~ #hive-panel-economy,
|
||||
#hive-tools:checked ~ #hive-panel-tools,
|
||||
#hive-network:checked ~ #hive-panel-network,
|
||||
#hive-blogs:checked ~ #hive-panel-blogs,
|
||||
#hive-creative:checked ~ #hive-panel-creative,
|
||||
#hive-media:checked ~ #hive-panel-media,
|
||||
#hive-fediverse:checked ~ #hive-panel-fediverse { display: block; }
|
||||
.hive-mods { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px; margin: 0; padding: 0; background: transparent; overflow: visible; }
|
||||
|
||||
.header .top-bar-left nav,
|
||||
.header .top-bar-right nav { display: none; }
|
||||
|
|
@ -909,33 +868,6 @@ button, input[type="submit"], input[type="button"],
|
|||
padding: 8px 12px; font-size: 13px; margin: 0 0 6px;
|
||||
}
|
||||
|
||||
/* --- #3: al desplegar una categoría, sus módulos son BOTONES CUADRADOS redondeados (no hexágonos),
|
||||
en rejilla 2×2 (2 y 2) y grandes: cada cuadrado llena su columna --- */
|
||||
.hive-mods {
|
||||
display: grid; grid-template-columns: repeat(2, 1fr);
|
||||
justify-items: stretch; align-content: center;
|
||||
gap: 12px; padding: 8px 4px;
|
||||
}
|
||||
.hex-mod {
|
||||
clip-path: none; -webkit-clip-path: none;
|
||||
width: 100%; height: auto; aspect-ratio: 1 / 1; min-height: 120px;
|
||||
border-radius: 18px; padding: 8px; gap: 7px;
|
||||
}
|
||||
.hex-mod::before { clip-path: none; -webkit-clip-path: none; inset: 2px; border-radius: 16px; }
|
||||
.hex-mod .hx-ico { font-size: 36px; }
|
||||
.hex-mod .hx-lbl { font-size: 12.5px; max-width: 94%; }
|
||||
/* si el nº de módulos es IMPAR, el último (solo en su fila) se CENTRA en vez de pegarse a la izquierda;
|
||||
abarca las 2 columnas pero conserva el ancho de una sola (gap 12 → mitad 6) */
|
||||
.hex-mod:last-child:nth-child(odd) {
|
||||
grid-column: 1 / -1; justify-self: center; width: calc(50% - 6px);
|
||||
}
|
||||
|
||||
/* --- #2: el hexágono "Personal" muestra tu avatar (diferencia del filtro "Personal" del header) --- */
|
||||
.hex-cat .hx-avatar {
|
||||
width: 58%; height: 58%; border-radius: 50%; object-fit: cover;
|
||||
position: relative; z-index: 1; border: 1px solid rgba(255,215,0,.6);
|
||||
}
|
||||
|
||||
/* --- #1: chat estilo Signal — compose ABAJO + mensajes arriba (el reply deja de "saltar") --- */
|
||||
.tribe-main.chat-full-width { display: flex; flex-direction: column-reverse; }
|
||||
#chatbox { scroll-margin-top: 8px; scroll-margin-bottom: 8px; }
|
||||
|
|
@ -1032,17 +964,17 @@ button, input[type="submit"], input[type="button"],
|
|||
========================================================================== */
|
||||
|
||||
/* --- fuente única en todo el UI móvil (quitar el lío monospace/sans) --- */
|
||||
.oasis-mobile-topbar, .oasis-mobile-menus, .hive-nav, .oasis-bottombar, .main-column,
|
||||
.oasis-mobile-topbar, .oasis-mobile-menus, .launcher, .oasis-bottombar, .main-column,
|
||||
.oasis-mobile-topbar input, .main-column input, .main-column textarea, .main-column select, button {
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
}
|
||||
|
||||
/* (topbar sin barra de búsqueda: vuelve el título "OASIS" — CSS .omt-title más arriba) */
|
||||
|
||||
/* --- hive ahora global en el header (debajo de los 2 botones) --- */
|
||||
.header .hive-nav { margin: 34px auto 10px; }
|
||||
/* --- el lanzador va en el header (debajo de los 2 botones), solo en la home --- */
|
||||
.header .launcher { width: 100%; max-width: 440px; box-sizing: border-box; margin: 34px auto 10px; padding: 0 14px; }
|
||||
|
||||
/* holgura bajo la topbar fija (el hive va en el header, solo en la home) */
|
||||
/* holgura bajo la topbar fija */
|
||||
body { padding-top: 84px; }
|
||||
|
||||
/* ==========================================================================
|
||||
|
|
@ -1113,3 +1045,22 @@ body { padding-top: 84px; }
|
|||
.kc-btn-start { font-weight: 600; }
|
||||
.kc-btn-stop { background: #241414; border-color: #5a2a2a; }
|
||||
.kc-status { font-size: 12px; color: #FFDD44; margin-top: 6px; min-height: 14px; }
|
||||
|
||||
/* ==========================================================================
|
||||
1.3.x: upstream trae en mobile.css su propio chrome movil (cabecera fija, cajones
|
||||
laterales y botones Personal/Community que los abren). La rama ya tiene el suyo
|
||||
(topbar, lanzador y barra inferior), asi que aqui se apaga el de upstream sin
|
||||
tocar mobile.css. Va con !important porque las reglas que anula lo llevan.
|
||||
========================================================================== */
|
||||
.oasis-nav-side-toggle ~ .header {
|
||||
position: static !important;
|
||||
display: flex !important; flex-direction: column !important; flex-wrap: nowrap !important;
|
||||
align-items: stretch !important;
|
||||
min-height: 0 !important; padding: 0 !important; gap: 0 !important;
|
||||
z-index: auto !important;
|
||||
}
|
||||
body:has(.oasis-nav-side-toggle) { padding-top: 84px !important; }
|
||||
.oasis-nav-side-toggle ~ .header .oasis-mobile-menus,
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-left nav,
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-right nav,
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-left a.logo-icon { display: none !important; }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict";
|
||||
// Navegacion propia de la rama experimental para movil: topbar, barra inferior
|
||||
// personalizable y rejilla de hexagonos.
|
||||
// personalizable y lanzador de modulos.
|
||||
//
|
||||
// Vive fuera de main_views.js a proposito: upstream reescribe ese fichero en cada
|
||||
// release (de 0.9.1 a 0.9.5 movio +256/-502 lineas) y esta interfaz se perdia en
|
||||
|
|
@ -12,7 +12,7 @@ const { getConfig } = require("../configs/config-manager.js");
|
|||
const sharedState = require("../configs/shared-state");
|
||||
|
||||
module.exports = ({ i18n }) => {
|
||||
// === Oasis UX (portado de 0.8.7_UX): topbar + bottombar + hive ===
|
||||
// === Oasis UX (portado de 0.8.7_UX): topbar + bottombar + lanzador ===
|
||||
// topbar fija arriba: [logo] [Personal] [Community] [avatar] en una línea (sin título OASIS)
|
||||
const renderMobileTopbar = () => {
|
||||
// solo en movil: en escritorio manda la cabecera de upstream
|
||||
|
|
@ -39,6 +39,8 @@ module.exports = ({ i18n }) => {
|
|||
{ key: 'tribes', href: '/tribes', glyph: 'ꖥ', labelKey: 'tribesTitle', mod: 'tribesMod' },
|
||||
{ key: 'chats', href: '/chats', glyph: 'ꖒ', labelKey: 'chatsTitle', mod: 'chatsMod' },
|
||||
{ key: 'karvan', href: '/karvan', glyph: '⧗', labelKey: 'karvanTitle', mod: 'karvanMod' },
|
||||
{ key: 'rooms', href: '/rooms', glyph: 'ꕢ', labelKey: 'roomsTitle', mod: 'roomsMod' },
|
||||
{ key: 'wiki', href: '/wiki', glyph: 'ꖿ', labelKey: 'wikiTitle', mod: 'wikiMod' },
|
||||
{ key: 'polls', href: '/polls', glyph: 'ꖙ', labelKey: 'pollsTitle', mod: 'pollsMod' },
|
||||
{ key: 'blogs', href: '/blogs', glyph: 'ꔫ', labelKey: 'blogTitle', mod: 'blogsMod' },
|
||||
{ key: 'data', href: '/data', glyph: 'ꘑ', labelKey: 'dataTitle', mod: 'dataMod' },
|
||||
|
|
@ -119,71 +121,104 @@ module.exports = ({ i18n }) => {
|
|||
);
|
||||
};
|
||||
|
||||
// Lanzador de modulos de la home: secciones con una rejilla de iconos, como el
|
||||
// cajon de apps del movil. Solo salen los modulos activos y las secciones que
|
||||
// tienen alguno, asi que con un workflow corto (activistas) cabe en una pantalla.
|
||||
const GROUPS = [
|
||||
{ id: 'community', titleKey: 'menuNetwork', side: 'community', mods: [
|
||||
{ href: '/activity', glyph: 'ꔙ', labelKey: 'activityTitle', mod: null },
|
||||
{ href: '/feed', glyph: 'ꕿ', labelKey: 'feedTitle', mod: 'feedMod' },
|
||||
{ href: '/chats', glyph: 'ꖒ', labelKey: 'chatsTitle', mod: 'chatsMod' },
|
||||
{ href: '/karvan', glyph: '⧗', labelKey: 'karvanTitle', mod: 'karvanMod' },
|
||||
{ href: '/rooms', glyph: 'ꕢ', labelKey: 'roomsTitle', mod: 'roomsMod' },
|
||||
{ href: '/forum', glyph: 'ꕒ', labelKey: 'forumTitle', mod: 'forumMod' },
|
||||
{ href: '/pads', glyph: 'ꔗ', labelKey: 'padsTitle', mod: 'padsMod' },
|
||||
{ href: '/wiki', glyph: 'ꖿ', labelKey: 'wikiTitle', mod: 'wikiMod' },
|
||||
{ href: '/blogs', glyph: 'ꔫ', labelKey: 'blogTitle', mod: 'blogsMod' },
|
||||
{ href: '/opinions', glyph: 'ꔍ', labelKey: 'opinionsTitle', mod: 'opinionsMod' },
|
||||
{ href: '/mentions', glyph: '✺', labelKey: 'mentions', mod: null },
|
||||
{ href: '/tags', glyph: 'ꖶ', labelKey: 'tagsLabel', mod: 'tagsMod' },
|
||||
{ href: '/trending', glyph: 'ꗝ', labelKey: 'trendingLabel', mod: 'trendingMod' },
|
||||
{ href: '/maps', glyph: 'ꔌ', labelKey: 'mapsLabel', mod: 'mapsMod' },
|
||||
{ href: '/graphos', glyph: '⌬', labelKey: 'modulesGraphosLabel', mod: 'graphosMod' },
|
||||
{ href: '/inhabitants', glyph: 'ꖘ', labelKey: 'inhabitantsLabel', mod: null },
|
||||
{ href: '/fediverse', glyph: 'ꗵ', labelKey: 'fediverseTimeline', mod: 'fediverseMod' } ] },
|
||||
{ id: 'media', titleKey: 'menuMedia', side: 'community', mods: [
|
||||
{ href: '/images', glyph: 'ꕥ', labelKey: 'imagesLabel', mod: 'imagesMod' },
|
||||
{ href: '/videos', glyph: 'ꗟ', labelKey: 'videosLabel', mod: 'videosMod' },
|
||||
{ href: '/audios', glyph: 'ꔿ', labelKey: 'audiosLabel', mod: 'audiosMod' },
|
||||
{ href: '/podcasts', glyph: '◉', labelKey: 'podcastsTitle', mod: 'podcastsMod' },
|
||||
{ href: '/documents', glyph: 'ꕨ', labelKey: 'docsLabel', mod: 'docsMod' },
|
||||
{ href: '/files', glyph: 'ꖃ', labelKey: 'filesTitle', mod: 'filesMod' },
|
||||
{ href: '/bookmarks', glyph: 'ꔪ', labelKey: 'bookmarksLabel', mod: 'bookmarksMod' },
|
||||
{ href: '/torrents', glyph: 'ꖅ', labelKey: 'torrentsLabel', mod: 'torrentsMod' } ] },
|
||||
{ id: 'creative', titleKey: 'menuCreative', side: 'community', mods: [
|
||||
{ href: '/games', glyph: 'ꕇ', labelKey: 'gamesTitle', mod: 'gamesMod' },
|
||||
{ href: '/pixelia', glyph: 'ꔘ', labelKey: 'pixeliaTitle', mod: 'pixeliaMod' },
|
||||
{ href: '/melody', glyph: '♪', labelKey: 'melodyTitle', mod: 'melodyMod' } ] },
|
||||
{ id: 'office', titleKey: 'menuOffice', side: 'personal', mods: [
|
||||
{ href: '/events', glyph: 'ꕆ', labelKey: 'eventsLabel', mod: 'eventsMod' },
|
||||
{ href: '/calendars', glyph: 'ꖯ', labelKey: 'calendarsTitle', mod: 'calendarsMod' },
|
||||
{ href: '/tasks', glyph: 'ꖧ', labelKey: 'tasksTitle', mod: 'tasksMod' },
|
||||
{ href: '/campaigns', glyph: '⚑', labelKey: 'campaignsTitle', mod: 'campaignsMod' },
|
||||
{ href: '/mailing', glyph: '✉', labelKey: 'mailingTitle', mod: 'mailingMod' },
|
||||
{ href: '/votes', glyph: 'ꔰ', labelKey: 'votationsTitle', mod: 'votesMod' },
|
||||
{ href: '/polls', glyph: 'ꖙ', labelKey: 'pollsTitle', mod: 'pollsMod' },
|
||||
{ href: '/reports', glyph: 'ꕤ', labelKey: 'reportsTitle', mod: 'reportsMod' } ] },
|
||||
{ id: 'governance', titleKey: 'menuGovernance', side: 'personal', mods: [
|
||||
{ href: '/tribes', glyph: 'ꖥ', labelKey: 'tribesTitle', mod: 'tribesMod' },
|
||||
{ href: '/emergencies', glyph: '✚', labelKey: 'emergenciesTitle', mod: 'emergenciesMod' },
|
||||
{ href: '/school', glyph: 'ꗳ', labelKey: 'schoolTitle', mod: 'schoolMod' },
|
||||
{ href: '/larp', glyph: '✦', labelKey: 'larpTitle', mod: 'larpMod' },
|
||||
{ href: '/parliament', glyph: 'ꗞ', labelKey: 'parliamentTitle', mod: 'parliamentMod' },
|
||||
{ href: '/courts', glyph: 'ꖻ', labelKey: 'courtsTitle', mod: 'courtsMod' } ] },
|
||||
{ id: 'economy', titleKey: 'menuEconomy', side: 'personal', mods: [
|
||||
{ href: '/market', glyph: 'ꕻ', labelKey: 'marketTitle', mod: 'marketMod' },
|
||||
{ href: '/shops', glyph: 'ꔜ', labelKey: 'shopsTitle', mod: 'shopsMod' },
|
||||
{ href: '/jobs', glyph: 'ꗒ', labelKey: 'jobsTitle', mod: 'jobsMod' },
|
||||
{ href: '/projects', glyph: 'ꕧ', labelKey: 'projectsTitle', mod: 'projectsMod' },
|
||||
{ href: '/housing', glyph: '⌂', labelKey: 'housingTitle', mod: 'housingMod' },
|
||||
{ href: '/logistics', glyph: '⇄', labelKey: 'logisticsTitle', mod: 'logisticsMod' },
|
||||
{ href: '/banking', glyph: 'ꗴ', labelKey: 'bankingTitle', mod: 'bankingMod' },
|
||||
{ href: '/transfers', glyph: 'ꘉ', labelKey: 'transfersTitle', mod: 'transfersMod' } ] },
|
||||
{ id: 'personal', titleKey: 'menuPersonal', side: 'personal', mods: [
|
||||
{ href: '/profile', glyph: '⚉', labelKey: 'profile', mod: null },
|
||||
{ href: '/agenda', glyph: 'ꗤ', labelKey: 'agendaTitle', mod: 'agendaMod' },
|
||||
{ href: '/favorites', glyph: 'ꘝ', labelKey: 'favoritesTitle', mod: 'favoritesMod' },
|
||||
{ href: '/phone', glyph: '☏', labelKey: 'phoneTitle', mod: 'phoneMod' },
|
||||
{ href: '/cv', glyph: 'ꕛ', labelKey: 'cvTitle', mod: null },
|
||||
{ href: '/wallet', glyph: '❄', labelKey: 'wallet', mod: 'walletMod' },
|
||||
{ href: '/logs', glyph: 'ꗯ', labelKey: 'logsTitle', mod: 'logsMod' } ] },
|
||||
{ id: 'tools', titleKey: 'menuTools', side: 'personal', mods: [
|
||||
{ href: '/invites', glyph: 'ꔹ', labelKey: 'invites', mod: 'invitesMod' },
|
||||
{ href: '/backup', glyph: 'ꖤ', labelKey: 'backupTitle', mod: 'backupMod' },
|
||||
{ href: '/cipher', glyph: 'ꗄ', labelKey: 'cipher', mod: 'cipherMod' },
|
||||
{ href: '/ai', glyph: 'ꘜ', labelKey: 'ai', mod: 'aiMod' },
|
||||
{ href: '/stats', glyph: 'ꕷ', labelKey: 'statistics', mod: null },
|
||||
{ href: '/blockexplorer', glyph: 'ꖸ', labelKey: 'blockchain', mod: null },
|
||||
{ href: '/modules', glyph: 'ꗣ', labelKey: 'modules', mod: null },
|
||||
{ href: '/settings', glyph: '⚙', labelKey: 'settings', mod: null } ] },
|
||||
];
|
||||
|
||||
const renderHiveNav = () => {
|
||||
if (process.env.OASIS_MOBILE !== '1') return "";
|
||||
const cfg = getConfig();
|
||||
const modOn = (m) => !m || cfg.modules[m] === 'on' || cfg.modules[m] === undefined;
|
||||
const CATS = [
|
||||
{ id: 'personal', emoji: '⚉', title: i18n.menuPersonal, mods: [
|
||||
{ href: '/profile', glyph: '⚉', labelKey: 'profile', mod: null }, { href: '/cv', glyph: 'ꕛ', labelKey: 'cvTitle', mod: null },
|
||||
{ href: '/agenda', glyph: 'ꗤ', labelKey: 'agendaTitle', mod: 'agendaMod' }, { href: '/favorites', glyph: 'ꘝ', labelKey: 'favoritesTitle', mod: 'favoritesMod' },
|
||||
{ href: '/logs', glyph: 'ꗯ', labelKey: 'logsTitle', mod: 'logsMod' }, { href: '/wallet', glyph: '❄', labelKey: 'wallet', mod: 'walletMod' },
|
||||
{ href: '/modules', glyph: 'ꗣ', labelKey: 'modules', mod: null }, { href: '/settings', glyph: '⚙', labelKey: 'settings', mod: null } ] },
|
||||
{ id: 'governance', emoji: '⚖', title: i18n.menuGovernance, mods: [
|
||||
{ href: '/inhabitants', glyph: 'ꖘ', labelKey: 'inhabitantsLabel', mod: null }, { href: '/tribes', glyph: 'ꖥ', labelKey: 'tribesTitle', mod: 'tribesMod' },
|
||||
{ href: '/larp', glyph: '✦', labelKey: 'larpTitle', mod: 'larpMod' }, { href: '/parliament', glyph: 'ꗞ', labelKey: 'parliamentTitle', mod: 'parliamentMod' },
|
||||
{ href: '/courts', glyph: 'ꖻ', labelKey: 'courtsTitle', mod: 'courtsMod' } ] },
|
||||
{ id: 'office', emoji: '⌂', title: i18n.menuOffice, mods: [
|
||||
{ href: '/votes', glyph: 'ꔰ', labelKey: 'votationsTitle', mod: 'votesMod' }, { href: '/polls', glyph: 'ꖙ', labelKey: 'pollsTitle', mod: 'pollsMod' }, { href: '/events', glyph: 'ꕆ', labelKey: 'eventsLabel', mod: 'eventsMod' },
|
||||
{ href: '/calendars', glyph: 'ꖯ', labelKey: 'calendarsTitle', mod: 'calendarsMod' }, { href: '/tasks', glyph: 'ꖧ', labelKey: 'tasksTitle', mod: 'tasksMod' },
|
||||
{ href: '/reports', glyph: 'ꕥ', labelKey: 'reportsTitle', mod: 'reportsMod' } ] },
|
||||
{ id: 'economy', emoji: '¤', title: i18n.menuEconomy, mods: [
|
||||
{ href: '/banking', glyph: 'ꗴ', labelKey: 'bankingTitle', mod: 'bankingMod' }, { href: '/market', glyph: 'ꕻ', labelKey: 'marketTitle', mod: 'marketMod' },
|
||||
{ href: '/projects', glyph: 'ꕧ', labelKey: 'projectsTitle', mod: 'projectsMod' }, { href: '/jobs', glyph: 'ꗒ', labelKey: 'jobsTitle', mod: 'jobsMod' },
|
||||
{ href: '/shops', glyph: 'ꔜ', labelKey: 'shopsTitle', mod: 'shopsMod' }, { href: '/transfers', glyph: 'ꘉ', labelKey: 'transfersTitle', mod: 'transfersMod' } ] },
|
||||
{ id: 'tools', emoji: '⚒', title: i18n.menuTools, mods: [
|
||||
{ href: '/ai', glyph: 'ꘜ', labelKey: 'ai', mod: 'aiMod' }, { href: '/blockexplorer', glyph: 'ꖸ', labelKey: 'blockchain', mod: null },
|
||||
{ href: '/cipher', glyph: 'ꗄ', labelKey: 'cipher', mod: 'cipherMod' }, { href: '/invites', glyph: 'ꔹ', labelKey: 'invites', mod: 'invitesMod' },
|
||||
{ href: '/legacy', glyph: 'ꖤ', labelKey: 'legacy', mod: 'legacyMod' }, { href: '/stats', glyph: 'ꕷ', labelKey: 'statistics', mod: null },
|
||||
{ href: '/data', glyph: 'ꘑ', labelKey: 'dataTitle', mod: 'dataMod' } ] },
|
||||
{ id: 'network', emoji: '☍', title: i18n.menuNetwork, mods: [
|
||||
{ href: '/activity', glyph: 'ꔙ', labelKey: 'activityTitle', mod: null }, { href: '/tags', glyph: 'ꖶ', labelKey: 'tagsLabel', mod: 'tagsMod' },
|
||||
{ href: '/trending', glyph: 'ꗝ', labelKey: 'trendingLabel', mod: 'trendingMod' }, { href: '/opinions', glyph: 'ꔍ', labelKey: 'opinionsTitle', mod: 'opinionsMod' },
|
||||
{ href: '/pads', glyph: 'ꔗ', labelKey: 'padsTitle', mod: 'padsMod' }, { href: '/forum', glyph: 'ꕒ', labelKey: 'forumTitle', mod: 'forumMod' },
|
||||
{ href: '/maps', glyph: 'ꔌ', labelKey: 'mapsLabel', mod: 'mapsMod' }, { href: '/chats', glyph: 'ꖒ', labelKey: 'chatsTitle', mod: 'chatsMod' },
|
||||
{ href: '/karvan', glyph: '⧗', labelKey: 'karvanTitle', mod: 'karvanMod' } ] },
|
||||
{ id: 'blogs', emoji: '✦', title: i18n.menuBlogs, mods: [
|
||||
{ href: '/blogs', glyph: 'ꔫ', labelKey: 'blogTitle', mod: 'blogsMod' }, { href: '/mentions', glyph: '✺', labelKey: 'mentions', mod: null }, { href: '/public/latest', glyph: '☄', labelKey: 'latest', mod: 'latestMod' },
|
||||
{ href: '/public/latest/threads', glyph: '♺', labelKey: 'threads', mod: 'threadsMod' }, { href: '/public/latest/topics', glyph: 'ϟ', labelKey: 'topics', mod: 'topicsMod' },
|
||||
{ href: '/public/latest/summaries', glyph: '※', labelKey: 'summaries', mod: 'summariesMod' }, { href: '/public/popular/day', glyph: '⌘', labelKey: 'popular', mod: 'popularMod' },
|
||||
{ href: '/public/latest/extended', glyph: '∞', labelKey: 'multiverse', mod: 'multiverseMod' } ] },
|
||||
{ id: 'creative', emoji: '✎', title: i18n.menuCreative, mods: [
|
||||
{ href: '/feed', glyph: 'ꕿ', labelKey: 'feedTitle', mod: 'feedMod' }, { href: '/games', glyph: 'ꕇ', labelKey: 'gamesTitle', mod: 'gamesMod' },
|
||||
{ href: '/pixelia', glyph: 'ꔘ', labelKey: 'pixeliaTitle', mod: 'pixeliaMod' }, { href: '/melody', glyph: '♪', labelKey: 'melodyTitle', mod: 'melodyMod' } ] },
|
||||
{ id: 'media', emoji: '▤', title: i18n.menuMedia, mods: [
|
||||
{ href: '/audios', glyph: 'ꔿ', labelKey: 'audiosLabel', mod: 'audiosMod' }, { href: '/bookmarks', glyph: 'ꔪ', labelKey: 'bookmarksLabel', mod: 'bookmarksMod' },
|
||||
{ href: '/documents', glyph: 'ꕨ', labelKey: 'docsLabel', mod: 'docsMod' }, { href: '/images', glyph: 'ꕥ', labelKey: 'imagesLabel', mod: 'imagesMod' },
|
||||
{ href: '/torrents', glyph: 'ꖅ', labelKey: 'torrentsLabel', mod: 'torrentsMod' }, { href: '/videos', glyph: 'ꗟ', labelKey: 'videosLabel', mod: 'videosMod' } ] },
|
||||
{ id: 'fediverse', emoji: '⌬', title: i18n.fediverse, mods: [
|
||||
{ href: '/fediverse', glyph: 'ꗵ', labelKey: 'fediverseTimeline', mod: 'fediverseMod' } ] },
|
||||
];
|
||||
// filtro server-side (lo pone el middleware desde ?hive=): personal = CATS[0..4], community = CATS[5..9], vacío = las 10
|
||||
// Personal/Social de la topbar (lo pone el middleware desde ?hive=) parte el lanzador en dos
|
||||
const hiveFilter = (typeof global !== "undefined" && global.__OASIS_HIVE_FILTER__) || "";
|
||||
const shown = hiveFilter === "personal" ? CATS.slice(0, 5) : hiveFilter === "community" ? CATS.slice(5) : CATS;
|
||||
const rowSizes = shown.length <= 5 ? [3, 2] : [3, 4, 3];
|
||||
const catHex = (c) => label({ for: `hive-${c.id}`, class: 'hex-cat' },
|
||||
span({ class: 'hx-ico' }, c.emoji), span({ class: 'hx-lbl' }, c.title));
|
||||
const modHex = (m) => a({ class: 'hex-mod', href: m.href },
|
||||
span({ class: 'hx-ico' }, m.glyph), span({ class: 'hx-lbl' }, i18n[m.labelKey] || ''));
|
||||
const radios = shown.map(c => input({ type: 'radio', name: 'hive-cat', id: `hive-${c.id}`, class: 'hive-radio' }));
|
||||
const catRows = [];
|
||||
let idx = 0;
|
||||
for (const size of rowSizes) { catRows.push(div({ class: 'hive-row' }, ...shown.slice(idx, idx + size).map(catHex))); idx += size; }
|
||||
const grid = div({ class: 'hive-grid hive-cats' }, ...catRows);
|
||||
const panels = shown.map(c => div({ class: 'hive-panel', id: `hive-panel-${c.id}` },
|
||||
div({ class: 'hive-mods' }, ...c.mods.filter(m => modOn(m.mod)).map(modHex))
|
||||
));
|
||||
return div({ class: 'hive-nav' }, ...radios, grid, ...panels);
|
||||
const app = (m) => a({ class: 'ln-app', href: m.href },
|
||||
span({ class: 'ln-ico', 'aria-hidden': 'true' }, m.glyph),
|
||||
span({ class: 'ln-lbl' }, i18n[m.labelKey] || m.href.slice(1)));
|
||||
const groups = GROUPS
|
||||
.filter(g => !hiveFilter || g.side === hiveFilter)
|
||||
.map(g => ({ g, mods: g.mods.filter(m => modOn(m.mod)) }))
|
||||
.filter(x => x.mods.length);
|
||||
return nav({ class: 'launcher', 'aria-label': i18n.modules || 'Modules' },
|
||||
...groups.map(({ g, mods }) => div({ class: 'ln-group' },
|
||||
h3({ class: 'ln-title' }, i18n[g.titleKey] || g.id),
|
||||
div({ class: 'ln-grid' }, ...mods.map(app))
|
||||
))
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue