aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-08-29 17:35:20 +0200
committerChristophe Besson <cbesson@gmail.com>2026-08-29 17:35:20 +0200
commita36661b4c2a24199922d60be1bcb6ed597b433a5 (patch)
tree4552b64f3da6e760510ff24e86bf0cdce8033385
parent78eef92bfa3513a81ac64d4377f8300c533aaa6c (diff)
downloadmeshbay-a36661b4c2a24199922d60be1bcb6ed597b433a5.tar.gz
feat(hub): drop the Search page title, add a Files refresh button
1. The "Search Files" <h2> is removed from the search page — it duplicated the nav and cost a line of vertical space on mobile. `search.title` is dropped from all ten locales (its only use). 2. A monochrome refresh button sits left of the Files breadcrumb home icon. It calls `onRefreshIndex` (re-fetch the group index from the node — the file list is a view over a cached copy with no other way to pull a fresh one), spins while in flight, and only renders where an `onRefreshIndex` is wired (the real group view, not the cross-group search results). New `refresh` icon; `group.refresh_index` in all ten locales. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018BMLQjqFGCize2KtNBT79v
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/files-app.js19
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/icon.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/de.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/en.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/es.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/it.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/search-page.js2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/style.css9
14 files changed, 39 insertions, 13 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 3d51e67..d2f0727 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/files-app.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/files-app.js
@@ -27,7 +27,7 @@ function FilesPanel({
groupId, transportRef, gekRef, status,
entries, nodeDirs, nodeRoots, setEntries, setNodeDirs, setNodeRoots, applyIndex,
isNodeAdmin, operatorPaired, mayUpload, userId, setError, onPreview,
- showGroup, readOnly, getTransport,
+ showGroup, readOnly, getTransport, onRefreshIndex,
}) {
const [selecting, setSelecting] = useState(false);
const [selected, setSelected] = useState(() => new Set());
@@ -35,6 +35,16 @@ function FilesPanel({
const [sortAsc, setSortAsc] = useState(true);
const [filter, setFilter] = useState('');
const [currentPath, setCurrentPath] = useState('');
+ const [refreshing, setRefreshing] = useState(false);
+
+ // Force a re-fetch of the group index from the node — the client's file
+ // list is a view over a cached copy, and there is no other way to pull a
+ // fresh one on demand.
+ const doRefresh = useCallback(async () => {
+ if (refreshing || !onRefreshIndex) return;
+ setRefreshing(true);
+ try { await onRefreshIndex(); } finally { setRefreshing(false); }
+ }, [refreshing, onRefreshIndex]);
// A directory from the group just left rarely exists in the one just
// entered (e.g. "outputs" in one group, absent in another) — Files would
@@ -329,6 +339,13 @@ function FilesPanel({
</div>
<div class="breadcrumbs">
+ ${onRefreshIndex && html`
+ <button class="crumb crumb-refresh ${refreshing ? 'spinning' : ''}"
+ onClick=${doRefresh} disabled=${refreshing}
+ title=${t('group.refresh_index')}>
+ <${Icon} name="refresh" />
+ </button>
+ `}
<a class="crumb" onClick=${() => setCurrentPath('')}>
<${Icon} name="home" />
</a>
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/icon.js b/packages/meshbay-hub/src/meshbay_hub/static/icon.js
index 029c669..cc28110 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/icon.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/icon.js
@@ -52,6 +52,8 @@ const ICON_PATHS = {
'folder-plus': ['M3.5 6.6a1 1 0 0 1 1-1h4.2l2 2.4h7.8a1 1 0 0 1 1 1v9.4a1 1 0 0 1-1 1h-14a1 1 0 0 1-1-1z',
'M12 11.4v5', 'M9.5 13.9h5'],
plus: ['M12 5v14', 'M5 12h14'],
+ refresh: ['M20 11a8 8 0 0 0-15.3-2', 'M4 5v4h4',
+ 'M4 13a8 8 0 0 0 15.3 2', 'M20 19v-4h-4'],
clip: ['M20.5 11.8l-8.4 8.4a5.4 5.4 0 0 1-7.6-7.6l8.8-8.8a3.6 3.6 0 0 1 5.1 5.1l-8.8 8.8a1.8 1.8 0 0 1-2.5-2.5l8.1-8.1'],
pencil: ['M4 20h4l10.5-10.5a2.1 2.1 0 0 0-3-3L5 17v3',
'M14.5 6.5l3 3'],
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js
index c4ee388..7017736 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js
@@ -94,6 +94,7 @@ export default {
'members.apps_need_one': "Mindestens eine Anwendung muss aktiviert bleiben.",
'members.danger_delete_hint': "Die Gruppe verschwindet für alle Mitglieder. Das lässt sich nicht rückgängig machen.",
'group.filter': 'Dateien filtern …',
+ 'group.refresh_index': 'Liste aktualisieren',
'group.col_name': 'Name',
'group.col_size': 'Größe',
'group.col_type': 'Typ',
@@ -524,7 +525,6 @@ export default {
// Status
// Search
- 'search.title': 'Dateien suchen',
'search.placeholder': 'In allen Gruppen suchen …',
'search.no_results': 'Keine Datei entspricht Ihrer Suche.',
'search.col_group': 'Gruppe',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js
index 16ae3ab..50f9ac5 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js
@@ -95,6 +95,7 @@ export default {
'members.apps_need_one': "At least one application must stay enabled.",
'members.danger_delete_hint': "This removes the group for every member. It cannot be undone.",
'group.filter': 'Filter files...',
+ 'group.refresh_index': 'Refresh file list',
'group.col_name': 'Name',
'group.col_size': 'Size',
'group.col_type': 'Type',
@@ -601,7 +602,6 @@ export default {
// Status
// Search
- 'search.title': 'Search Files',
'search.placeholder': 'Search across all groups...',
'search.no_results': 'No files match your search.',
'search.col_group': 'Group',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js
index 88b222d..2aa4599 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js
@@ -92,6 +92,7 @@ export default {
'members.apps_need_one': "Al menos una aplicación debe permanecer activada.",
'members.danger_delete_hint': "El grupo desaparece para todos sus miembros. No se puede deshacer.",
'group.filter': 'Filtrar archivos...',
+ 'group.refresh_index': 'Actualizar la lista',
'group.col_name': 'Nombre',
'group.col_size': 'Tamaño',
'group.col_type': 'Tipo',
@@ -520,7 +521,6 @@ export default {
// Status
// Search
- 'search.title': 'Buscar archivos',
'search.placeholder': 'Buscar en todos los grupos...',
'search.no_results': 'Ningún archivo coincide con su búsqueda.',
'search.col_group': 'Grupo',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
index b08cf28..4750349 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
@@ -93,6 +93,7 @@ export default {
'members.apps_need_one': "Au moins une application doit rester activée.",
'members.danger_delete_hint': "Le groupe disparaît pour tous ses membres. C’est irréversible.",
'group.filter': 'Filtrer les fichiers...',
+ 'group.refresh_index': 'Actualiser la liste',
'group.col_name': 'Nom',
'group.col_size': 'Taille',
'group.col_type': 'Type',
@@ -524,7 +525,6 @@ export default {
// Status
// Search
- 'search.title': 'Rechercher des fichiers',
'search.placeholder': 'Rechercher dans tous les groupes...',
'search.no_results': 'Aucun fichier ne correspond à votre recherche.',
'search.col_group': 'Groupe',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js
index f1e8467..12e0c77 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js
@@ -93,6 +93,7 @@ export default {
'members.apps_need_one': "Almeno un'applicazione deve restare attiva.",
'members.danger_delete_hint': "Il gruppo scompare per tutti i membri. Non è reversibile.",
'group.filter': 'Filtra i file...',
+ 'group.refresh_index': 'Aggiorna l\'elenco',
'group.col_name': 'Nome',
'group.col_size': 'Dimensione',
'group.col_type': 'Tipo',
@@ -522,7 +523,6 @@ export default {
// Status
// Search
- 'search.title': 'Cerca file',
'search.placeholder': 'Cerca in tutti i gruppi...',
'search.no_results': 'Nessun file corrisponde alla sua ricerca.',
'search.col_group': 'Gruppo',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js
index 95cc040..7f4a0c2 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js
@@ -91,6 +91,7 @@ export default {
'members.apps_need_one': "少なくとも1つのアプリケーションを有効にしておく必要があります。",
'members.danger_delete_hint': "グループはすべてのメンバーから消えます。元に戻せません。",
'group.filter': 'ファイルを絞り込み…',
+ 'group.refresh_index': '一覧を更新',
'group.col_name': '名前',
'group.col_size': 'サイズ',
'group.col_type': '種類',
@@ -511,7 +512,6 @@ export default {
// Status
// Search
- 'search.title': 'ファイルを検索',
'search.placeholder': 'すべてのグループから検索…',
'search.no_results': '検索条件に一致するファイルはありません。',
'search.col_group': 'グループ',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js
index 076aa15..5ea6371 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js
@@ -94,6 +94,7 @@ export default {
'members.apps_need_one': "Er moet minstens één toepassing ingeschakeld blijven.",
'members.danger_delete_hint': "De groep verdwijnt voor alle leden. Dit kan niet ongedaan worden gemaakt.",
'group.filter': 'Bestanden filteren...',
+ 'group.refresh_index': 'Lijst vernieuwen',
'group.col_name': 'Naam',
'group.col_size': 'Grootte',
'group.col_type': 'Type',
@@ -524,7 +525,6 @@ export default {
// Status
// Search
- 'search.title': 'Bestanden zoeken',
'search.placeholder': 'In alle groepen zoeken...',
'search.no_results': 'Geen bestand voldoet aan uw zoekopdracht.',
'search.col_group': 'Groep',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js
index 00ef59e..6aa6cd1 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js
@@ -98,6 +98,7 @@ export default {
'members.apps_need_one': "Co najmniej jedna aplikacja musi pozostać włączona.",
'members.danger_delete_hint': "Grupa zniknie dla wszystkich członków. Tego nie można cofnąć.",
'group.filter': 'Filtruj pliki...',
+ 'group.refresh_index': 'Odśwież listę',
'group.col_name': 'Nazwa',
'group.col_size': 'Rozmiar',
'group.col_type': 'Typ',
@@ -541,7 +542,6 @@ export default {
// Status
// Search
- 'search.title': 'Wyszukiwanie plików',
'search.placeholder': 'Szukaj we wszystkich grupach...',
'search.no_results': 'Żaden plik nie pasuje do zapytania.',
'search.col_group': 'Grupa',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js
index 7d9173e..2cff7a6 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js
@@ -94,6 +94,7 @@ export default {
'members.apps_need_one': "Pelo menos um aplicativo deve permanecer ativado.",
'members.danger_delete_hint': "O grupo desaparece para todos os membros. Não há como desfazer.",
'group.filter': 'Filtrar arquivos...',
+ 'group.refresh_index': 'Atualizar a lista',
'group.col_name': 'Nome',
'group.col_size': 'Tamanho',
'group.col_type': 'Tipo',
@@ -521,7 +522,6 @@ export default {
// Status
// Search
- 'search.title': 'Pesquisar arquivos',
'search.placeholder': 'Pesquisar em todos os grupos...',
'search.no_results': 'Nenhum arquivo corresponde à sua pesquisa.',
'search.col_group': 'Grupo',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js
index 74d729e..704204d 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js
@@ -91,6 +91,7 @@ export default {
'members.apps_need_one': "至少需要保留一个已启用的应用。",
'members.danger_delete_hint': "该群组将对所有成员消失,且无法恢复。",
'group.filter': '筛选文件…',
+ 'group.refresh_index': '刷新列表',
'group.col_name': '名称',
'group.col_size': '大小',
'group.col_type': '类型',
@@ -497,7 +498,6 @@ export default {
// Status
// Search
- 'search.title': '搜索文件',
'search.placeholder': '在所有群组中搜索…',
'search.no_results': '没有文件符合您的搜索。',
'search.col_group': '群组',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/search-page.js b/packages/meshbay-hub/src/meshbay_hub/static/search-page.js
index e61dcd8..e36532f 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/search-page.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/search-page.js
@@ -480,8 +480,6 @@ function SearchPage({ token, username, userId, groups, onPlayQueue, userPrefs })
return html`
<div>
- <h2>${t('search.title')}</h2>
-
<div class="search-bar">
<${Icon} name="search" />
<input type="text"
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/style.css b/packages/meshbay-hub/src/meshbay_hub/static/style.css
index 8e714f3..2a2bd8a 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/style.css
+++ b/packages/meshbay-hub/src/meshbay_hub/static/style.css
@@ -886,6 +886,15 @@ button:disabled { opacity: 0.5; cursor: not-allowed; }
}
.crumb:hover { background: var(--bg-raised); text-decoration: none; }
.crumb-sep { color: var(--text-dim); }
+.crumb-refresh {
+ background: none;
+ border: 0;
+ font: inherit;
+ color: var(--text-secondary);
+}
+.crumb-refresh:hover:not(:disabled) { color: var(--text); }
+.crumb-refresh:disabled { cursor: default; }
+.crumb-refresh.spinning .icon { animation: spin 0.8s linear infinite; }
/* ── File table ──────────────────────────────────────────────────────────── */