[0.9.1] Mobile usability: filter hexagons by tab, collapse activity filters
- Personal/Community/All header tabs now filter the home hexagon nav (default All shows the 10; Personal/Community show their 5) via the CSS radio-hack. Removed the square-accordion sidebars (.sidebar-left/.sidebar-right) they replaced. - Wrap the dense activity filter strip (RECENT/ALL/MINE/…) in a collapsible FILTER dropdown, hidden by default, keeping the hexagons visible above. - Add the missing English i18n keys (menuCommunity, menuAll, filter, bb*).
This commit is contained in:
parent
871cccbe17
commit
c088d176c1
4 changed files with 79 additions and 218 deletions
|
|
@ -83,14 +83,12 @@ body { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }
|
||||||
font-weight: bold; letter-spacing: 1px; cursor: pointer;
|
font-weight: bold; letter-spacing: 1px; cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav-left-toggle:checked ~ .header .oasis-menu-btn[for="nav-left-toggle"] {
|
#hive-filter-all:checked ~ .header .oasis-menu-btn[for="hive-filter-all"],
|
||||||
|
#hive-filter-personal:checked ~ .header .oasis-menu-btn[for="hive-filter-personal"],
|
||||||
|
#hive-filter-community:checked ~ .header .oasis-menu-btn[for="hive-filter-community"] {
|
||||||
background: #FFA500; color: #121212; border-color: #FFA500;
|
background: #FFA500; color: #121212; border-color: #FFA500;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav-right-toggle:checked ~ .header .oasis-menu-btn[for="nav-right-toggle"] {
|
|
||||||
background: #FFD700; color: #121212; border-color: #FFD700;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--space-1: 4px; --space-2: 8px; --space-3: 16px; --space-4: 24px; --space-5: 32px;
|
--space-1: 4px; --space-2: 8px; --space-3: 16px; --space-4: 24px; --space-5: 32px;
|
||||||
--fs-caption: 12px; --fs-body: 14px; --fs-body-lg: 16px; --fs-title: 20px;
|
--fs-caption: 12px; --fs-body: 14px; --fs-body-lg: 16px; --fs-title: 20px;
|
||||||
|
|
@ -192,12 +190,34 @@ a, button, label, .tap, .oasis-menu-btn, .bb-item, .oasis-nav-header, .oasis-nav
|
||||||
}
|
}
|
||||||
body { overscroll-behavior: none; }
|
body { overscroll-behavior: none; }
|
||||||
|
|
||||||
.main-content, .main-column, .header,
|
.main-content, .main-column, .header { overflow: visible; }
|
||||||
.sidebar-left, .sidebar-right { overflow: visible; }
|
|
||||||
|
|
||||||
.sidebar-left, .sidebar-right { display: none; }
|
/* === Usabilidad 0.9.1: los tabs All/Personal/Community filtran el hive + desplegable FILTER === */
|
||||||
#nav-left-toggle:checked ~ .main-content .sidebar-left { display: block; }
|
.hive-filter-radio { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; margin: 0; }
|
||||||
#nav-right-toggle:checked ~ .main-content .sidebar-right { display: block; }
|
|
||||||
|
/* filtro por mitades: Personal oculta la mitad community, Community oculta la personal (All = todo) */
|
||||||
|
#hive-filter-personal:checked ~ .main-content .hive-nav .hex-cat.hive-half-c { display: none; }
|
||||||
|
#hive-filter-community:checked ~ .main-content .hive-nav .hex-cat.hive-half-p { display: none; }
|
||||||
|
/* también el panel de la mitad oculta si venía abierto (#content sube la especificidad para ganar al reveal de 2 IDs, sin !important) */
|
||||||
|
#hive-filter-personal:checked ~ .main-content #content .hive-panel.hive-half-c { display: none; }
|
||||||
|
#hive-filter-community:checked ~ .main-content #content .hive-panel.hive-half-p { display: none; }
|
||||||
|
|
||||||
|
/* desplegable FILTER de la ristra de filtros de Activity (oculto por defecto) */
|
||||||
|
.activity-filter-btn {
|
||||||
|
display: flex; align-items: center; justify-content: center; gap: 8px;
|
||||||
|
width: 100%; min-height: 44px; margin: 4px 0 8px; padding: 10px 12px;
|
||||||
|
border: 1.5px solid #333; border-radius: 10px;
|
||||||
|
background: #121212; color: #ccc;
|
||||||
|
font-weight: bold; letter-spacing: 1px; text-transform: uppercase; cursor: pointer;
|
||||||
|
}
|
||||||
|
.activity-filter-caret { transition: transform 150ms ease; }
|
||||||
|
#activity-filter-toggle:checked ~ .activity-filter-btn { background: #FFA500; color: #121212; border-color: #FFA500; }
|
||||||
|
#activity-filter-toggle:checked ~ .activity-filter-btn .activity-filter-caret { transform: rotate(180deg); }
|
||||||
|
.activity-filter-panel { display: none; }
|
||||||
|
#activity-filter-toggle:checked ~ .activity-filter-panel { display: block; }
|
||||||
|
.activity-filter-panel .activity-filter-grid { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin-top: 8px; }
|
||||||
|
.activity-filter-panel .activity-filter-col { display: contents; }
|
||||||
|
.activity-filter-panel form { margin: 0; }
|
||||||
|
|
||||||
.bb-manage { margin: 8px 0 16px; }
|
.bb-manage { margin: 8px 0 16px; }
|
||||||
.bb-manage h3, .bb-manage-add h3 {
|
.bb-manage h3, .bb-manage-add h3 {
|
||||||
|
|
|
||||||
|
|
@ -387,6 +387,19 @@ module.exports = {
|
||||||
menuEconomy: "Economy",
|
menuEconomy: "Economy",
|
||||||
menuMedia: "Media",
|
menuMedia: "Media",
|
||||||
menuTools: "Tools",
|
menuTools: "Tools",
|
||||||
|
menuCommunity: "Community",
|
||||||
|
menuAll: "All",
|
||||||
|
filter: "Filter",
|
||||||
|
bbAdd: "Add",
|
||||||
|
bbManage: "Edit",
|
||||||
|
bbRemove: "Remove",
|
||||||
|
bbQuickActions: "Quick actions",
|
||||||
|
bbYourBar: "Your bar",
|
||||||
|
bbFull: "Maximum reached",
|
||||||
|
bbDone: "Done",
|
||||||
|
bbPickTitle: "Customize the bar",
|
||||||
|
bbPickDesc: "Choose up to 4 shortcuts for the bottom bar.",
|
||||||
|
bbPickNone: "None",
|
||||||
comment: "Comment",
|
comment: "Comment",
|
||||||
subtopic: "Subtopic",
|
subtopic: "Subtopic",
|
||||||
json: "JSON",
|
json: "JSON",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const { div, h2, p, section, button, form, a, input, img, textarea, br, span, video: videoHyperaxe, audio: audioHyperaxe, table, tr, td, th, details, summary } = require("../server/node_modules/hyperaxe");
|
const { div, h2, p, section, button, form, a, input, label, img, textarea, br, span, video: videoHyperaxe, audio: audioHyperaxe, table, tr, td, th, details, summary } = require("../server/node_modules/hyperaxe");
|
||||||
const { template, i18n, userLink, userLinkLabel, renderSpreadButton, renderContentActions, renderHiveNav } = require('./main_views');
|
const { template, i18n, userLink, userLinkLabel, renderSpreadButton, renderContentActions, renderHiveNav } = require('./main_views');
|
||||||
const opinionCategories = require('../backend/opinion_categories');
|
const opinionCategories = require('../backend/opinion_categories');
|
||||||
|
|
||||||
|
|
@ -1994,30 +1994,35 @@ exports.activityView = (actions, filter, userId, q = '', extras = {}) => {
|
||||||
p(desc)
|
p(desc)
|
||||||
),
|
),
|
||||||
renderHiveNav(),
|
renderHiveNav(),
|
||||||
div({ class: 'activity-filter-grid' },
|
input({ type: 'checkbox', id: 'activity-filter-toggle', class: 'hive-filter-radio' }),
|
||||||
...[
|
label({ for: 'activity-filter-toggle', class: 'activity-filter-btn' },
|
||||||
activityTypes.slice(0, 3),
|
span(i18n.filter || 'Filter'), span({ class: 'activity-filter-caret' }, '▾')),
|
||||||
activityTypes.slice(3, 8),
|
div({ class: 'activity-filter-panel' },
|
||||||
activityTypes.slice(8, 13),
|
div({ class: 'activity-filter-grid' },
|
||||||
activityTypes.slice(13, 19),
|
...[
|
||||||
activityTypes.slice(19, 26),
|
activityTypes.slice(0, 3),
|
||||||
activityTypes.slice(26)
|
activityTypes.slice(3, 8),
|
||||||
].map(col =>
|
activityTypes.slice(8, 13),
|
||||||
div({ class: 'activity-filter-col' },
|
activityTypes.slice(13, 19),
|
||||||
col.map(({ type, label }) =>
|
activityTypes.slice(19, 26),
|
||||||
form({ method: 'GET', action: '/activity' },
|
activityTypes.slice(26)
|
||||||
input({ type: 'hidden', name: 'filter', value: type }),
|
].map(col =>
|
||||||
button({ type: 'submit', class: filter === type ? 'filter-btn active' : 'filter-btn' }, label)
|
div({ class: 'activity-filter-col' },
|
||||||
|
col.map(({ type, label }) =>
|
||||||
|
form({ method: 'GET', action: '/activity' },
|
||||||
|
input({ type: 'hidden', name: 'filter', value: type }),
|
||||||
|
button({ type: 'submit', class: filter === type ? 'filter-btn active' : 'filter-btn' }, label)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
),
|
||||||
|
sub
|
||||||
|
? div({ class: 'activity-sub-filter' },
|
||||||
|
sub.filters.map(f => a({ href: `${sub.url}?filter=${encodeURIComponent(f)}`, class: 'filter-btn' }, String(f).toUpperCase()))
|
||||||
|
)
|
||||||
|
: null
|
||||||
),
|
),
|
||||||
sub
|
|
||||||
? div({ class: 'activity-sub-filter' },
|
|
||||||
sub.filters.map(f => a({ href: `${sub.url}?filter=${encodeURIComponent(f)}`, class: 'filter-btn' }, String(f).toUpperCase()))
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
section({ class: 'feed-container' }, renderActionCards(filteredActions, userId, actions, spreadMap))
|
section({ class: 'feed-container' }, renderActionCards(filteredActions, userId, actions, spreadMap))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1239,7 +1239,8 @@ const renderHiveNav = () => {
|
||||||
{ id: 'fediverse', emoji: '⌬', title: i18n.fediverse, mods: [
|
{ id: 'fediverse', emoji: '⌬', title: i18n.fediverse, mods: [
|
||||||
{ href: '/fediverse', glyph: 'ꗵ', labelKey: 'fediverseTimeline', mod: 'fediverseMod' } ] },
|
{ href: '/fediverse', glyph: 'ꗵ', labelKey: 'fediverseTimeline', mod: 'fediverseMod' } ] },
|
||||||
];
|
];
|
||||||
const catHex = (c) => label({ for: `hive-${c.id}`, class: 'hex-cat' },
|
const half = (c) => (CATS.indexOf(c) < 5 ? 'hive-half-p' : 'hive-half-c');
|
||||||
|
const catHex = (c) => label({ for: `hive-${c.id}`, class: `hex-cat ${half(c)}` },
|
||||||
span({ class: 'hx-ico' }, c.emoji), span({ class: 'hx-lbl' }, c.title));
|
span({ class: 'hx-ico' }, c.emoji), span({ class: 'hx-lbl' }, c.title));
|
||||||
const modHex = (m) => a({ class: 'hex-mod', href: m.href },
|
const modHex = (m) => a({ class: 'hex-mod', href: m.href },
|
||||||
span({ class: 'hx-ico' }, m.glyph), span({ class: 'hx-lbl' }, i18n[m.labelKey] || ''));
|
span({ class: 'hx-ico' }, m.glyph), span({ class: 'hx-lbl' }, i18n[m.labelKey] || ''));
|
||||||
|
|
@ -1248,7 +1249,7 @@ const renderHiveNav = () => {
|
||||||
let idx = 0;
|
let idx = 0;
|
||||||
for (const size of [3, 4, 3]) { catRows.push(div({ class: 'hive-row' }, ...CATS.slice(idx, idx + size).map(catHex))); idx += size; }
|
for (const size of [3, 4, 3]) { catRows.push(div({ class: 'hive-row' }, ...CATS.slice(idx, idx + size).map(catHex))); idx += size; }
|
||||||
const grid = div({ class: 'hive-grid hive-cats' }, ...catRows);
|
const grid = div({ class: 'hive-grid hive-cats' }, ...catRows);
|
||||||
const panels = CATS.map(c => div({ class: 'hive-panel', id: `hive-panel-${c.id}` },
|
const panels = CATS.map(c => div({ class: `hive-panel ${half(c)}`, id: `hive-panel-${c.id}` },
|
||||||
div({ class: 'hive-mods' }, ...c.mods.filter(m => modOn(m.mod)).map(modHex))
|
div({ class: 'hive-mods' }, ...c.mods.filter(m => modOn(m.mod)).map(modHex))
|
||||||
));
|
));
|
||||||
return div({ class: 'hive-nav' }, ...radios, grid, ...panels);
|
return div({ class: 'hive-nav' }, ...radios, grid, ...panels);
|
||||||
|
|
@ -1284,17 +1285,17 @@ const template = (titlePrefix, ...elements) => {
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
body(
|
body(
|
||||||
input({ type: "checkbox", id: "nav-left-toggle", class: "oasis-nav-side-toggle" }),
|
input({ type: "radio", name: "hive-filter", id: "hive-filter-all", class: "hive-filter-radio", checked: true }),
|
||||||
input({ type: "checkbox", id: "nav-right-toggle", class: "oasis-nav-side-toggle" }),
|
input({ type: "radio", name: "hive-filter", id: "hive-filter-personal", class: "hive-filter-radio" }),
|
||||||
|
input({ type: "radio", name: "hive-filter", id: "hive-filter-community", class: "hive-filter-radio" }),
|
||||||
div(
|
div(
|
||||||
{ class: uxMode === "ainav" ? "header ainav-only" : "header" },
|
{ class: uxMode === "ainav" ? "header ainav-only" : "header" },
|
||||||
renderMobileTopbar(),
|
renderMobileTopbar(),
|
||||||
div(
|
div(
|
||||||
{ class: "oasis-mobile-menus" },
|
{ class: "oasis-mobile-menus" },
|
||||||
label({ for: "nav-left-toggle", class: "oasis-menu-btn" },
|
label({ for: "hive-filter-all", class: "oasis-menu-btn" }, span(i18n.menuAll || "All")),
|
||||||
span({ class: "oasis-menu-ico" }, "☰"), span(i18n.menuPersonal || "Personal")),
|
label({ for: "hive-filter-personal", class: "oasis-menu-btn" }, span(i18n.menuPersonal || "Personal")),
|
||||||
label({ for: "nav-right-toggle", class: "oasis-menu-btn" },
|
label({ for: "hive-filter-community", class: "oasis-menu-btn" }, span(i18n.menuCommunity || "Community"))
|
||||||
span({ class: "oasis-menu-ico" }, "☰"), span(i18n.menuCommunity || "Community"))
|
|
||||||
),
|
),
|
||||||
(() => {
|
(() => {
|
||||||
const aiNavOn = getConfig().modules.aiNavMod === 'on';
|
const aiNavOn = getConfig().modules.aiNavMod === 'on';
|
||||||
|
|
@ -1349,185 +1350,7 @@ const template = (titlePrefix, ...elements) => {
|
||||||
})(),
|
})(),
|
||||||
div(
|
div(
|
||||||
{ class: uxMode === "ainav" ? "main-content ainav-only" : "main-content" },
|
{ class: uxMode === "ainav" ? "main-content ainav-only" : "main-content" },
|
||||||
uxMode === "ainav" ? null : div(
|
main({ id: "content", class: "main-column" }, elements)
|
||||||
{ class: "sidebar-left" },
|
|
||||||
nav(
|
|
||||||
ul(
|
|
||||||
navGroup(
|
|
||||||
{
|
|
||||||
id: "personal",
|
|
||||||
emoji: "⚉",
|
|
||||||
title: i18n.menuPersonal
|
|
||||||
},
|
|
||||||
navLink({
|
|
||||||
href: "/profile",
|
|
||||||
emoji: "⚉",
|
|
||||||
text: i18n.profile
|
|
||||||
}),
|
|
||||||
navLink({
|
|
||||||
href: "/cv",
|
|
||||||
emoji: "ꕛ",
|
|
||||||
text: i18n.cvTitle
|
|
||||||
}),
|
|
||||||
renderAgendaLink(),
|
|
||||||
renderFavoritesLink(),
|
|
||||||
renderLogsLink(),
|
|
||||||
renderWalletLink(),
|
|
||||||
navLink({
|
|
||||||
href: "/modules",
|
|
||||||
emoji: "ꗣ",
|
|
||||||
text: i18n.modules
|
|
||||||
}),
|
|
||||||
navLink({
|
|
||||||
href: "/settings",
|
|
||||||
emoji: "⚙",
|
|
||||||
text: i18n.settings
|
|
||||||
})
|
|
||||||
),
|
|
||||||
navGroup(
|
|
||||||
{
|
|
||||||
id: "governance",
|
|
||||||
emoji: "⚖",
|
|
||||||
title: i18n.menuGovernance
|
|
||||||
},
|
|
||||||
navLink({
|
|
||||||
href: "/inhabitants",
|
|
||||||
emoji: "ꖘ",
|
|
||||||
text: i18n.inhabitantsLabel
|
|
||||||
}),
|
|
||||||
renderTribesLink(),
|
|
||||||
renderLarpLink(),
|
|
||||||
renderParliamentLink(),
|
|
||||||
renderCourtsLink()
|
|
||||||
),
|
|
||||||
navGroup(
|
|
||||||
{
|
|
||||||
id: "office",
|
|
||||||
emoji: "⌂",
|
|
||||||
title: i18n.menuOffice
|
|
||||||
},
|
|
||||||
renderVotationsLink(),
|
|
||||||
renderEventsLink(),
|
|
||||||
renderCalendarsLink(),
|
|
||||||
renderTasksLink(),
|
|
||||||
renderReportsLink()
|
|
||||||
),
|
|
||||||
navGroup(
|
|
||||||
{
|
|
||||||
id: "economy",
|
|
||||||
emoji: "¤",
|
|
||||||
title: i18n.menuEconomy
|
|
||||||
},
|
|
||||||
renderBankingLink(),
|
|
||||||
renderMarketLink(),
|
|
||||||
renderProjectsLink(),
|
|
||||||
renderIndustryLink(),
|
|
||||||
renderJobsLink(),
|
|
||||||
renderShopsLink(),
|
|
||||||
renderTransfersLink()
|
|
||||||
),
|
|
||||||
navGroup(
|
|
||||||
{
|
|
||||||
id: "tools",
|
|
||||||
emoji: "⚒",
|
|
||||||
title: i18n.menuTools
|
|
||||||
},
|
|
||||||
renderAILink(),
|
|
||||||
navLink({
|
|
||||||
href: "/blockexplorer",
|
|
||||||
emoji: "ꖸ",
|
|
||||||
text: i18n.blockchain
|
|
||||||
}),
|
|
||||||
renderDevLink(),
|
|
||||||
renderCipherLink(),
|
|
||||||
renderInvitesLink(),
|
|
||||||
renderLegacyLink(),
|
|
||||||
navLink({
|
|
||||||
href: "/stats",
|
|
||||||
emoji: "ꕷ",
|
|
||||||
text: i18n.statistics
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
main({ id: "content", class: "main-column" }, elements),
|
|
||||||
uxMode === "ainav" ? null : div(
|
|
||||||
{ class: "sidebar-right" },
|
|
||||||
nav(
|
|
||||||
ul(
|
|
||||||
navGroup(
|
|
||||||
{
|
|
||||||
id: "network",
|
|
||||||
emoji: "☍",
|
|
||||||
title: i18n.menuNetwork
|
|
||||||
},
|
|
||||||
navLink({
|
|
||||||
href: "/activity",
|
|
||||||
emoji: "ꔙ",
|
|
||||||
text: i18n.activityTitle
|
|
||||||
}),
|
|
||||||
renderTagsLink(),
|
|
||||||
renderTrendingLink(),
|
|
||||||
renderOpinionsLink(),
|
|
||||||
renderPadsLink(),
|
|
||||||
renderForumLink(),
|
|
||||||
renderMapsLink(),
|
|
||||||
renderChatsLink()
|
|
||||||
),
|
|
||||||
navGroup(
|
|
||||||
{
|
|
||||||
id: "blogs",
|
|
||||||
emoji: "✦",
|
|
||||||
title: i18n.menuBlogs
|
|
||||||
},
|
|
||||||
navLink({
|
|
||||||
href: "/mentions",
|
|
||||||
emoji: "✺",
|
|
||||||
text: i18n.mentions
|
|
||||||
}),
|
|
||||||
renderLatestLink(),
|
|
||||||
renderThreadsLink(),
|
|
||||||
renderTopicsLink(),
|
|
||||||
renderSummariesLink(),
|
|
||||||
renderPopularLink(),
|
|
||||||
renderMultiverseLink()
|
|
||||||
),
|
|
||||||
navGroup(
|
|
||||||
{
|
|
||||||
id: "creative",
|
|
||||||
emoji: "✎",
|
|
||||||
title: i18n.menuCreative
|
|
||||||
},
|
|
||||||
renderFeedLink(),
|
|
||||||
renderGamesLink(),
|
|
||||||
renderPixeliaLink(),
|
|
||||||
renderMelodyLink()
|
|
||||||
),
|
|
||||||
navGroup(
|
|
||||||
{
|
|
||||||
id: "media",
|
|
||||||
emoji: "▤",
|
|
||||||
title: i18n.menuMedia
|
|
||||||
},
|
|
||||||
renderAudiosLink(),
|
|
||||||
renderBookmarksLink(),
|
|
||||||
renderDocsLink(),
|
|
||||||
renderImagesLink(),
|
|
||||||
renderTorrentsLink(),
|
|
||||||
renderVideosLink()
|
|
||||||
),
|
|
||||||
navGroup(
|
|
||||||
{
|
|
||||||
id: "fediverse",
|
|
||||||
emoji: "⌬",
|
|
||||||
title: i18n.fediverse
|
|
||||||
},
|
|
||||||
renderMastodonLink()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
renderBottomBar(),
|
renderBottomBar(),
|
||||||
renderFooter()
|
renderFooter()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue