From eba2e6b14484c124f3c87ff95cd7ee640833e5d3 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Fri, 28 Aug 2026 15:35:20 +0200 Subject: feat(hub): cross-group search with reuse of existing views MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Search page fetches indexes from all groups, then renders consolidated entries through the existing FilesPanel, VideoApp, and MusicApp components — no reimplemented views. Groups appear as top-level directories in the file browser; video/music entries use a synthetic root with per-entry transport refs for thumbnails and metadata across groups. Music player lifted to app.js with getConnection(groupId) for cross-group playback. Connection pool (max 3, LRU eviction) manages lazy WebRTC connections. All 10 locales updated with search keys. Co-Authored-By: Claude Opus 4.6 --- .../meshbay-hub/src/meshbay_hub/static/hub-client.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'packages/meshbay-hub/src/meshbay_hub/static/hub-client.js') diff --git a/packages/meshbay-hub/src/meshbay_hub/static/hub-client.js b/packages/meshbay-hub/src/meshbay_hub/static/hub-client.js index 176d22b..16dce9f 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/hub-client.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/hub-client.js @@ -35,12 +35,13 @@ function openDB() { }); } -async function cacheGroupIndex(groupId, groupName, groupOwner, entries) { +async function cacheGroupIndex(groupId, groupName, groupOwner, entries, roots) { try { const db = await openDB(); const tx = db.transaction(IDB_STORE, 'readwrite'); tx.objectStore(IDB_STORE).put({ - groupId, groupName, groupOwner, entries, cachedAt: Date.now(), + groupId, groupName, groupOwner, entries, roots: roots || {}, + cachedAt: Date.now(), }); await new Promise((r, rej) => { tx.oncomplete = r; tx.onerror = rej; }); db.close(); @@ -69,6 +70,16 @@ async function getAllCachedIndexes() { } catch { return []; } } +async function clearAllCachedIndexes() { + try { + const db = await openDB(); + const tx = db.transaction(IDB_STORE, 'readwrite'); + tx.objectStore(IDB_STORE).clear(); + await new Promise((r, rej) => { tx.oncomplete = r; tx.onerror = rej; }); + db.close(); + } catch { /* best-effort */ } +} + // ── Auth persistence ───────────────────────────────────────────────────────── // The key that opens a node's keypair bundle, derived once at sign-in, and a @@ -262,7 +273,7 @@ async function hubFetch(path, { method = 'GET', body, token, _retried } = {}) { export { HUB, navigate, session, - cacheGroupIndex, getCachedGroupIndex, getAllCachedIndexes, + cacheGroupIndex, getCachedGroupIndex, getAllCachedIndexes, clearAllCachedIndexes, _storeBundleKey, _loadBundleKey, _clearKeyDB, loadAuth, saveAuth, setAuth, setAuthChangeListener, tokenLifeLeft, refreshAccessToken, ensureFreshToken, hubFetch, -- cgit v1.2.3