diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-08-28 15:35:20 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-08-28 15:35:58 +0200 |
| commit | eba2e6b14484c124f3c87ff95cd7ee640833e5d3 (patch) | |
| tree | ba109b719c879df3ea40090e4fd6ff80b403a3a5 /packages/meshbay-hub/src/meshbay_hub/static/files-app.js | |
| parent | e6917349c47cc4b7e04e1ecfab27c5291a5fe522 (diff) | |
| download | meshbay-eba2e6b14484c124f3c87ff95cd7ee640833e5d3.tar.gz | |
feat(hub): cross-group search with reuse of existing views
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 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/files-app.js')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/files-app.js | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/files-app.js b/packages/meshbay-hub/src/meshbay_hub/static/files-app.js index c4b221e..daf13af 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/files-app.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/files-app.js @@ -27,6 +27,7 @@ function FilesPanel({ groupId, transportRef, gekRef, status, entries, nodeDirs, nodeRoots, setEntries, setNodeDirs, setNodeRoots, applyIndex, isNodeAdmin, operatorPaired, mayUpload, userId, setError, onPreview, + showGroup, readOnly, }) { const [selecting, setSelecting] = useState(false); const [selected, setSelected] = useState(() => new Set()); @@ -331,19 +332,19 @@ function FilesPanel({ </div> <div class="toolbar-group right"> - <div class="tb-search"> + ${!readOnly && html`<div class="tb-search"> <${Icon} name="search" /> <input type="text" placeholder="${t('group.filter')}" value=${filter} onInput=${e => setFilter(e.target.value)} /> - </div> - <button class="tb-btn ${selecting ? 'active' : ''}" + </div>`} + ${!readOnly && html`<button class="tb-btn ${selecting ? 'active' : ''}" onClick=${() => { setSelecting(v => !v); setSelected(new Set()); }}> <${Icon} name=${selecting ? 'check' : 'checkbox'} /> ${selecting ? t('group.select_done') : t('group.select')} - </button> + </button>`} ${selecting && html`<div class="tb-actions">${actionItems}</div>`} </div> </div> @@ -358,6 +359,7 @@ function FilesPanel({ <th class="sortable" onClick=${() => toggleSort('size')}> ${t('group.col_size')} ${sortKey === 'size' ? (sortAsc ? '▲' : '▼') : ''} </th> + ${showGroup && html`<th>${t('search.col_group')}</th>`} <th class="sortable th-type" onClick=${() => toggleSort('type')}> ${t('group.col_type')} ${sortKey === 'type' ? (sortAsc ? '▲' : '▼') : ''} </th> @@ -386,6 +388,7 @@ function FilesPanel({ <span class="root-offline"> ${t('group.root_unavailable')}</span> ` : ''}</td> <td class="file-size">${inside.length ? formatSize(bytes) : ''}</td> + ${showGroup && html`<td></td>`} <td class="td-type"></td> <td class="td-date"></td> </tr> @@ -411,12 +414,15 @@ function FilesPanel({ onClick=${() => { setFilter(''); setCurrentPath(e.path); }}>${e.path}</a>`} </td> <td class="file-size">${formatSize(e.size)}</td> + ${showGroup && html`<td> + <a href="#/group/${e.groupId}" class="badge">${e.groupName || ''}</a> + </td>`} <td class="file-type td-type">${e.type}</td> <td class="file-date td-date">${formatDate(e.added_at)}</td> </tr> `)} ${sorted.length === 0 && subdirs.length === 0 && html` - <tr><td colspan=${selecting ? 6 : 5} class="file-empty"> + <tr><td colspan=${(selecting ? 6 : 5) + (showGroup ? 1 : 0)} class="file-empty"> ${filter ? t('group.empty_filter') : t('group.empty_dir')} </td></tr> `} |