From 459fc93e98f23e326c2fa77fe86ba74c2bae77f0 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Tue, 15 Sep 2026 17:01:06 +0200 Subject: feat(hub): Videos and Music list their cards a page at a time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous/next arrows in the pinned toolbar, on group pages and in Search. Page size is an account preference (Settings → Defaults), 50 by default, 10 to 200 in steps of 10. Co-Authored-By: Claude Opus 5 --- .../src/meshbay_hub/static/settings-page.js | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'packages/meshbay-hub/src/meshbay_hub/static/settings-page.js') diff --git a/packages/meshbay-hub/src/meshbay_hub/static/settings-page.js b/packages/meshbay-hub/src/meshbay_hub/static/settings-page.js index c6a73da..51d99cd 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/settings-page.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/settings-page.js @@ -6,6 +6,12 @@ import * as downloads from './downloads.js'; import * as platform from './platform.js'; import { hubFetch } from './hub-client.js'; import { APPS } from './apps.js'; +import { + PAGE_SIZE_PREF, PAGE_SIZE_DEFAULT, PAGE_SIZE_STEP, PAGE_SIZE_MAX, pageSizeFrom, +} from './pager.js'; + +const PAGE_SIZES = Array.from( + { length: PAGE_SIZE_MAX / PAGE_SIZE_STEP }, (_, i) => (i + 1) * PAGE_SIZE_STEP); export function SettingsPage({ user, theme, onThemeChange, groups, onPrefsChange }) { const [locale, setLoc] = useState(getLocale); @@ -19,6 +25,7 @@ export function SettingsPage({ user, theme, onThemeChange, groups, onPrefsChange // e.g. to ride out the WebRTC screen-lock reconnect gap without waiting // on the automatic recovery at all. const [keepScreenOnAudio, setKeepScreenOnAudio] = useState(false); + const [pageSize, setPageSize] = useState(PAGE_SIZE_DEFAULT); const onLocaleChange = useCallback((e) => { const code = e.target.value; @@ -37,6 +44,7 @@ export function SettingsPage({ user, theme, onThemeChange, groups, onPrefsChange if (prefs.notifications_disabled === 'true') setGlobalMute(true); if (prefs.default_tab) setDefaultTab(prefs.default_tab); if (prefs.music_keep_screen_on === 'true') setKeepScreenOnAudio(true); + setPageSize(pageSizeFrom(prefs)); }) .catch(() => {}); }, [user.token]); @@ -97,6 +105,18 @@ export function SettingsPage({ user, theme, onThemeChange, groups, onPrefsChange } catch { setDefaultTab(defaultTab); } }, [defaultTab, user.token, onPrefsChange]); + const changePageSize = useCallback(async (e) => { + const val = String(e.target.value); + setPageSize(Number(val)); + try { + await hubFetch(`/v1/users/me/preferences/${PAGE_SIZE_PREF}`, { + method: 'PUT', token: user.token, + body: { value: val }, + }); + if (onPrefsChange) onPrefsChange({ [PAGE_SIZE_PREF]: val }); + } catch { setPageSize(pageSize); } + }, [pageSize, user.token, onPrefsChange]); + const [dlMode, setDlMode] = useState(() => downloads.getMode()); const [dlDir, setDlDir] = useState(null); const [dlError, setDlError] = useState(''); @@ -248,6 +268,14 @@ export function SettingsPage({ user, theme, onThemeChange, groups, onPrefsChange

${t('settings.default_tab_hint')}

+
+ ${t('settings.media_page_size')} + +
+

${t('settings.media_page_size_hint')}

${t('settings.music_keep_screen_on')}