summaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-07 02:04:42 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-07 02:04:42 +0200
commitfbcb3461c5bfc0f9b902287896d655da6f0bfcd0 (patch)
tree18678f7fbd415d6b29d7c4351861364b7a38c7c4 /packages
parent375419c041a4523614b3a1b98fa54fb5acb1b8bf (diff)
downloadmeshbay-fbcb3461c5bfc0f9b902287896d655da6f0bfcd0.tar.gz
fix(client): drop the "No changes to save" hint beside Save
The hint was added alongside the .app-save control, when an inert Save was indistinguishable from an enabled one and the reader had no way to tell "nothing changed" from "this is broken". The control now reads as disabled on its own, so the sentence beside it is noise. Removing it also removes what only existed to carry it: the .app-save-row wrapper, its two style rules, and settings_app.no_changes in all ten locales. test_the_disabled_state_is_visually_distinct sliced the stylesheet on .app-save-row; it now stops at the closing brace of .app-save:disabled. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pvMdvLBG92jyhvD5pD6us
Diffstat (limited to 'packages')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/chat-app-settings.js4
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/de.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/en.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/es.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/it.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/music-app-settings.js4
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/photos-app-settings.js4
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/style.css2
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/video-app-settings.js4
-rw-r--r--packages/meshbay-hub/tests/test_app_settings_plugin.py13
16 files changed, 1 insertions, 40 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/chat-app-settings.js b/packages/meshbay-hub/src/meshbay_hub/static/chat-app-settings.js
index 5a15074..96fc52f 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/chat-app-settings.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/chat-app-settings.js
@@ -45,14 +45,10 @@ function ChatSettings({ roots, dirs, settings, saveDirectories, transport, signF
value=${directory} disabled=${busy || noWritable}
onChange=${setDirectory} />
- <div class="app-save-row">
<button class="app-save" disabled=${busy || !dirty}
onClick=${() => run(() => transport.setChatDirectory(directory, signFn))}>
${busy ? t('settings_app.saving') : t('settings_app.save')}
</button>
- ${!busy && !dirty && html`
- <span class="app-save-why">${t('settings_app.no_changes')}</span>`}
- </div>
<div class="settings-row" style="margin-top:12px">
<${ToggleSwitch} checked=${linkPreview} disabled=${busy}
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 d47762e..d05d3a3 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js
@@ -840,7 +840,6 @@ export default {
'folder_tree.read_only_blocked': 'Nur lesen — kein Schreiben möglich',
'settings_app.save': 'Speichern',
'settings_app.saving': 'Wird gespeichert…',
- 'settings_app.no_changes': 'Keine Änderungen zu speichern',
'settings_app.disabled_hint': 'Schalten Sie diese App ein, um sie zu konfigurieren.',
'settings_app.video_directories_label': 'Video-Ordner',
'settings_app.video_directories_hint': 'Wo die Filme und Serien dieser Gruppe liegen. Nichts außerhalb erscheint im Videos-Tab.',
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 932aad3..6dbb70f 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js
@@ -628,7 +628,6 @@ export default {
'folder_tree.read_only_blocked': 'Read-only — cannot be written to',
'settings_app.save': 'Save',
'settings_app.saving': 'Saving…',
- 'settings_app.no_changes': 'No changes to save',
'settings_app.disabled_hint': 'Turn this app on to configure it.',
'settings_app.video_directories_label': 'Video folders',
'settings_app.video_directories_hint': 'Where this group\'s films and shows live. Nothing outside them appears in the Videos tab.',
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 ca912a4..aa950cc 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js
@@ -836,7 +836,6 @@ export default {
'folder_tree.read_only_blocked': 'Solo lectura: no se puede escribir',
'settings_app.save': 'Guardar',
'settings_app.saving': 'Guardando…',
- 'settings_app.no_changes': 'Sin cambios que guardar',
'settings_app.disabled_hint': 'Activa esta aplicación para configurarla.',
'settings_app.video_directories_label': 'Carpetas de vídeo',
'settings_app.video_directories_hint': 'Dónde están las películas y series de este grupo. Nada fuera de ellas aparece en la pestaña Vídeos.',
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 ccd9e25..daa9f94 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
@@ -854,7 +854,6 @@ export default {
'folder_tree.read_only_blocked': 'Lecture seule — écriture impossible',
'settings_app.save': 'Enregistrer',
'settings_app.saving': 'Enregistrement…',
- 'settings_app.no_changes': 'Aucune modification à enregistrer',
'settings_app.disabled_hint': 'Activez cette application pour la configurer.',
'settings_app.video_directories_label': 'Dossiers vidéo',
'settings_app.video_directories_hint': 'Où vivent les films et séries de ce groupe. Rien en dehors n\'apparaît dans l\'onglet Vidéos.',
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 c1c3d52..364c26c 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js
@@ -850,7 +850,6 @@ export default {
'folder_tree.read_only_blocked': 'Sola lettura: non vi si può scrivere',
'settings_app.save': 'Salva',
'settings_app.saving': 'Salvataggio…',
- 'settings_app.no_changes': 'Nessuna modifica da salvare',
'settings_app.disabled_hint': 'Attiva questa applicazione per configurarla.',
'settings_app.video_directories_label': 'Cartelle video',
'settings_app.video_directories_hint': 'Dove si trovano film e serie di questo gruppo. Nulla al di fuori compare nella scheda Video.',
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 e5392a3..f778fc4 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js
@@ -834,7 +834,6 @@ export default {
'folder_tree.read_only_blocked': '読み取り専用 — 書き込みできません',
'settings_app.save': '保存',
'settings_app.saving': '保存中…',
- 'settings_app.no_changes': '保存する変更はありません',
'settings_app.disabled_hint': 'このアプリを有効にすると設定できます。',
'settings_app.video_directories_label': '動画フォルダー',
'settings_app.video_directories_hint': 'このグループの映画や番組がある場所です。それ以外は動画タブに表示されません。',
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 09e3e8d..6e6842e 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js
@@ -852,7 +852,6 @@ export default {
'folder_tree.read_only_blocked': 'Alleen-lezen — kan niet worden beschreven',
'settings_app.save': 'Opslaan',
'settings_app.saving': 'Opslaan…',
- 'settings_app.no_changes': 'Geen wijzigingen om op te slaan',
'settings_app.disabled_hint': 'Zet deze app aan om hem in te stellen.',
'settings_app.video_directories_label': 'Videomappen',
'settings_app.video_directories_hint': 'Waar de films en series van deze groep staan. Niets daarbuiten verschijnt op het tabblad Video\'s.',
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 34847e1..c8cbd16 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js
@@ -878,7 +878,6 @@ export default {
'folder_tree.read_only_blocked': 'Tylko do odczytu — nie można zapisywać',
'settings_app.save': 'Zapisz',
'settings_app.saving': 'Zapisywanie…',
- 'settings_app.no_changes': 'Brak zmian do zapisania',
'settings_app.disabled_hint': 'Włącz tę aplikację, aby ją skonfigurować.',
'settings_app.video_directories_label': 'Foldery wideo',
'settings_app.video_directories_hint': 'Gdzie znajdują się filmy i seriale tej grupy. Nic poza nimi nie pojawi się w zakładce Wideo.',
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 fc211c9..6eb2242 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
@@ -837,7 +837,6 @@ export default {
'folder_tree.read_only_blocked': 'Somente leitura — não é possível gravar',
'settings_app.save': 'Salvar',
'settings_app.saving': 'Salvando…',
- 'settings_app.no_changes': 'Nenhuma alteração para salvar',
'settings_app.disabled_hint': 'Ative este aplicativo para configurá-lo.',
'settings_app.video_directories_label': 'Pastas de vídeo',
'settings_app.video_directories_hint': 'Onde ficam os filmes e séries deste grupo. Nada fora delas aparece na aba Vídeos.',
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 9db7cc7..044611e 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
@@ -821,7 +821,6 @@ export default {
'folder_tree.read_only_blocked': '只读 — 无法写入',
'settings_app.save': '保存',
'settings_app.saving': '正在保存…',
- 'settings_app.no_changes': '没有需要保存的更改',
'settings_app.disabled_hint': '启用该应用后即可配置。',
'settings_app.video_directories_label': '视频文件夹',
'settings_app.video_directories_hint': '该群组的影片和剧集所在位置。其外的内容不会出现在「视频」标签页。',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/music-app-settings.js b/packages/meshbay-hub/src/meshbay_hub/static/music-app-settings.js
index a3b02d9..8ce2ab6 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/music-app-settings.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/music-app-settings.js
@@ -38,14 +38,10 @@ function MusicSettings({ roots, dirs, settings, saveDirectories, transport, sign
value=${directories} disabled=${busy}
onChange=${setDirectories} />
- <div class="app-save-row">
<button class="app-save" disabled=${busy || !dirsDirty}
onClick=${() => run(() => saveDirectories(directories))}>
${busy ? t('settings_app.saving') : t('settings_app.save')}
</button>
- ${!busy && !dirsDirty && html`
- <span class="app-save-why">${t('settings_app.no_changes')}</span>`}
- </div>
<h4 class="app-settings-sub">${t('settings_node.musicbrainz_title')}</h4>
<p class="settings-hint">${t('settings_node.musicbrainz_hint')}</p>
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/photos-app-settings.js b/packages/meshbay-hub/src/meshbay_hub/static/photos-app-settings.js
index a241eea..8656fa5 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/photos-app-settings.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/photos-app-settings.js
@@ -32,14 +32,10 @@ function PhotoSettings({ roots, dirs, settings, saveDirectories }) {
value=${directories} disabled=${busy}
onChange=${setDirectories} />
- <div class="app-save-row">
<button class="app-save" disabled=${busy || !dirty}
onClick=${() => run(() => saveDirectories(directories))}>
${busy ? t('settings_app.saving') : t('settings_app.save')}
</button>
- ${!busy && !dirty && html`
- <span class="app-save-why">${t('settings_app.no_changes')}</span>`}
- </div>
${msg && html`<p class="settings-hint">${msg}</p>`}
</div>
`;
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/style.css b/packages/meshbay-hub/src/meshbay_hub/static/style.css
index bf4e8e1..d1d5732 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/style.css
+++ b/packages/meshbay-hub/src/meshbay_hub/static/style.css
@@ -1298,8 +1298,6 @@ button:disabled { opacity: 0.5; cursor: not-allowed; }
}
/* Why it is inert, beside it — a disabled control that explains itself is the
difference between "nothing changed" and "this is broken". */
-.app-save-row { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
-.app-save-why { font-size: 0.82em; color: var(--text-dim); }
.app-settings-sub {
margin: 18px 0 4px; font-size: 0.9em; font-weight: 600;
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/video-app-settings.js b/packages/meshbay-hub/src/meshbay_hub/static/video-app-settings.js
index 86e47ec..5c79bc5 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/video-app-settings.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/video-app-settings.js
@@ -56,14 +56,10 @@ function VideoSettings({ roots, dirs, settings, saveDirectories, transport, sign
value=${directories} disabled=${busy}
onChange=${setDirectories} />
- <div class="app-save-row">
<button class="app-save" disabled=${busy || !dirsDirty}
onClick=${() => run(() => saveDirectories(directories))}>
${busy ? t('settings_app.saving') : t('settings_app.save')}
</button>
- ${!busy && !dirsDirty && html`
- <span class="app-save-why">${t('settings_app.no_changes')}</span>`}
- </div>
<h4 class="app-settings-sub">${t('settings_node.tmdb_title')}</h4>
<p class="settings-hint">${t('settings_node.tmdb_hint')}</p>
diff --git a/packages/meshbay-hub/tests/test_app_settings_plugin.py b/packages/meshbay-hub/tests/test_app_settings_plugin.py
index 8a095af..b8afc23 100644
--- a/packages/meshbay-hub/tests/test_app_settings_plugin.py
+++ b/packages/meshbay-hub/tests/test_app_settings_plugin.py
@@ -347,21 +347,10 @@ def test_save_is_a_button_and_not_dim_text(pane):
f"{pane}'s Save is still styled as dim text")
-@pytest.mark.parametrize("pane", sorted(PANE_FLAGS))
-def test_an_inert_save_says_why(pane):
- """
- A disabled control that explains itself is the difference between "nothing
- changed" and "this is broken". Without it the reader has to know what the
- pane counts as a change.
- """
- source = (STATIC / pane).read_text(encoding="utf-8")
- assert "app-save-why" in source and "settings_app.no_changes" in source
-
-
def test_the_disabled_state_is_visually_distinct():
css = (STATIC / "style.css").read_text(encoding="utf-8")
rule = css[css.index(".app-save {"):]
- rule = rule[:rule.index(".app-save-row")]
+ rule = rule[:rule.index("}", rule.index(".app-save:disabled")) + 1]
assert "var(--accent)" in rule, "an enabled Save has no fill"
disabled = rule[rule.index(".app-save:disabled"):]
assert "background: none" in disabled and "--text-dim" in disabled, (