[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:
s1to 2026-08-04 11:07:48 +02:00
parent 871cccbe17
commit c088d176c1
4 changed files with 79 additions and 218 deletions

View file

@ -83,14 +83,12 @@ body { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }
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;
}
#nav-right-toggle:checked ~ .header .oasis-menu-btn[for="nav-right-toggle"] {
background: #FFD700; color: #121212; border-color: #FFD700;
}
:root {
--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;
@ -192,12 +190,34 @@ a, button, label, .tap, .oasis-menu-btn, .bb-item, .oasis-nav-header, .oasis-nav
}
body { overscroll-behavior: none; }
.main-content, .main-column, .header,
.sidebar-left, .sidebar-right { overflow: visible; }
.main-content, .main-column, .header { overflow: visible; }
.sidebar-left, .sidebar-right { display: none; }
#nav-left-toggle:checked ~ .main-content .sidebar-left { display: block; }
#nav-right-toggle:checked ~ .main-content .sidebar-right { display: block; }
/* === Usabilidad 0.9.1: los tabs All/Personal/Community filtran el hive + desplegable FILTER === */
.hive-filter-radio { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; margin: 0; }
/* 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 h3, .bb-manage-add h3 {

View file

@ -387,6 +387,19 @@ module.exports = {
menuEconomy: "Economy",
menuMedia: "Media",
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",
subtopic: "Subtopic",
json: "JSON",

View file

@ -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 opinionCategories = require('../backend/opinion_categories');
@ -1994,6 +1994,10 @@ exports.activityView = (actions, filter, userId, q = '', extras = {}) => {
p(desc)
),
renderHiveNav(),
input({ type: 'checkbox', id: 'activity-filter-toggle', class: 'hive-filter-radio' }),
label({ for: 'activity-filter-toggle', class: 'activity-filter-btn' },
span(i18n.filter || 'Filter'), span({ class: 'activity-filter-caret' }, '▾')),
div({ class: 'activity-filter-panel' },
div({ class: 'activity-filter-grid' },
...[
activityTypes.slice(0, 3),
@ -2017,7 +2021,8 @@ exports.activityView = (actions, filter, userId, q = '', extras = {}) => {
? div({ class: 'activity-sub-filter' },
sub.filters.map(f => a({ href: `${sub.url}?filter=${encodeURIComponent(f)}`, class: 'filter-btn' }, String(f).toUpperCase()))
)
: null,
: null
),
section({ class: 'feed-container' }, renderActionCards(filteredActions, userId, actions, spreadMap))
)
);

View file

@ -1239,7 +1239,8 @@ const renderHiveNav = () => {
{ id: 'fediverse', emoji: '⌬', title: i18n.fediverse, mods: [
{ 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));
const modHex = (m) => a({ class: 'hex-mod', href: m.href },
span({ class: 'hx-ico' }, m.glyph), span({ class: 'hx-lbl' }, i18n[m.labelKey] || ''));
@ -1248,7 +1249,7 @@ const renderHiveNav = () => {
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; }
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))
));
return div({ class: 'hive-nav' }, ...radios, grid, ...panels);
@ -1284,17 +1285,17 @@ const template = (titlePrefix, ...elements) => {
})
),
body(
input({ type: "checkbox", id: "nav-left-toggle", class: "oasis-nav-side-toggle" }),
input({ type: "checkbox", id: "nav-right-toggle", class: "oasis-nav-side-toggle" }),
input({ type: "radio", name: "hive-filter", id: "hive-filter-all", class: "hive-filter-radio", checked: true }),
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(
{ class: uxMode === "ainav" ? "header ainav-only" : "header" },
renderMobileTopbar(),
div(
{ class: "oasis-mobile-menus" },
label({ for: "nav-left-toggle", class: "oasis-menu-btn" },
span({ class: "oasis-menu-ico" }, "☰"), span(i18n.menuPersonal || "Personal")),
label({ for: "nav-right-toggle", class: "oasis-menu-btn" },
span({ class: "oasis-menu-ico" }, "☰"), span(i18n.menuCommunity || "Community"))
label({ for: "hive-filter-all", class: "oasis-menu-btn" }, span(i18n.menuAll || "All")),
label({ for: "hive-filter-personal", class: "oasis-menu-btn" }, span(i18n.menuPersonal || "Personal")),
label({ for: "hive-filter-community", class: "oasis-menu-btn" }, span(i18n.menuCommunity || "Community"))
),
(() => {
const aiNavOn = getConfig().modules.aiNavMod === 'on';
@ -1349,185 +1350,7 @@ const template = (titlePrefix, ...elements) => {
})(),
div(
{ class: uxMode === "ainav" ? "main-content ainav-only" : "main-content" },
uxMode === "ainav" ? null : div(
{ 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()
)
)
)
)
main({ id: "content", class: "main-column" }, elements)
),
renderBottomBar(),
renderFooter()