From 835667dba3f7f3e1145417190ae518cef0f7527e Mon Sep 17 00:00:00 2001 From: Ivan Date: Fri, 24 Jul 2026 11:39:59 -0500 Subject: [PATCH] feat: improve SettingsPage styles with deep-scoping and add libseccomp to Docker setup scripts --- meshchatx.rsm | Bin 181042 -> 181042 bytes .../components/settings/SettingsPage.vue | 54 ++++++++++-------- scripts/docker/runtime-setup-chainguard.sh | 2 +- scripts/docker/runtime-setup.sh | 2 +- tests/frontend/behaviorContracts.test.js | 14 +++++ tests/frontend/settingsSections.test.js | 35 ++++++++++++ 6 files changed, 80 insertions(+), 27 deletions(-) diff --git a/meshchatx.rsm b/meshchatx.rsm index 5b31af2ad4547dba8e743da708bd3ebf2745da2c..baeaba349e8ade11577dfd8dc47666cb73c1228d 100644 GIT binary patch delta 486 zcmWlTJ!q6c5J2;tD3O$DM1z_%iXiUa%^U=oi)YZx6g>%CfZ#@3=`t$1KgVR4xY%jl`+FrQ);@iNz zde6bLt%>g4x6l6yjo|FG+vv6}P58Rnqo2ecSjtiq$i9uOpa$1Oi z0E{mVBB<=qCJMT!=&~}1-lwFr%T8$~mfZe*xZ2zPHCT=G7I#;>I<)~%RK#&8h(#eV zhv3*G3)z}typC+Z2}ABhPCt$#O=r zT1bP(5XpOGxi}wv_AZH#4ayOFA22$W;!VS_FcOILwpXeXwY3~E2hP@H$;McxO>i7l z^dO2@g3b_pcUprb3SlZ|XtLIwDL<;dXLYW3-B-RM*Rv&yjqF6eBeQi8XTO=gN> z3q;gNB&fAZt^|WD-efHZWCpkHw7$&D1|z9>s|_}FCruy#mxUETX)Y+!=wt%eWRrtv XHM4R^NZLzwy`yWbgM @reference "../../style.css"; -.settings-section { +/* + * Shared settings chrome is used by extracted section components. + * :deep is required so scoped styles still reach their markup. + */ +:deep(.settings-section) { @apply w-full border-b border-gray-200/60 dark:border-zinc-800/60 py-6 sm:py-8 flex flex-col break-inside-avoid; } -.settings-section--hero { +:deep(.settings-section--hero) { @apply border-b border-gray-200/60 dark:border-zinc-800/60 py-6 sm:py-8; } -.settings-section__header { +:deep(.settings-section__header) { @apply flex items-center justify-between gap-3 pb-4 border-b border-gray-100/60 dark:border-zinc-800/60; } -.settings-section__header h2 { +:deep(.settings-section__header h2) { @apply text-lg font-semibold text-gray-900 dark:text-white; } -.settings-section__header p { +:deep(.settings-section__header p) { @apply text-sm text-gray-600 dark:text-gray-400; } -.settings-section__eyebrow { +:deep(.settings-section__eyebrow) { @apply text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400; } -.settings-section__body { +:deep(.settings-section__body) { @apply pt-4 text-gray-900 dark:text-gray-100; } -.input-field { +:deep(.input-field) { @apply bg-gray-50/90 dark:bg-zinc-800/80 border border-gray-200 dark:border-zinc-700 text-sm rounded-2xl focus:ring-2 focus:ring-blue-400 focus:border-blue-400 dark:focus:ring-blue-500 dark:focus:border-blue-500 block w-full p-2.5 text-gray-900 dark:text-gray-100 transition; } -.btn-maintenance { +:deep(.btn-maintenance) { @apply w-full px-4 py-3 rounded-2xl border transition flex items-center justify-between; } -.setting-toggle { - @apply relative flex flex-row-reverse items-center gap-3 rounded-2xl border border-gray-200 dark:border-zinc-800 bg-white/70 dark:bg-zinc-900/70 px-3 py-3; +:deep(.setting-toggle) { + @apply relative flex flex-row-reverse items-start gap-3 rounded-2xl border border-gray-200 dark:border-zinc-800 bg-white/70 dark:bg-zinc-900/70 px-3 py-3; } -.setting-toggle > :deep(label) { +:deep(.setting-toggle > label) { @apply shrink-0 self-center; } -.setting-toggle :deep(.sr-only) { +:deep(.setting-toggle .sr-only) { @apply absolute w-px h-px p-0 -m-px overflow-hidden whitespace-nowrap border-0; } -.setting-toggle__label { +:deep(.setting-toggle__label) { @apply flex-1 min-w-0 flex flex-col gap-0.5; } -.setting-toggle__title { - @apply text-sm font-semibold text-gray-900 dark:text-white break-words; +:deep(.setting-toggle__title) { + @apply text-sm font-semibold text-gray-900 dark:text-white break-words leading-snug; } -.setting-toggle__description { - @apply text-sm text-gray-600 dark:text-gray-300 break-words; +:deep(.setting-toggle__description) { + @apply text-xs sm:text-sm text-gray-600 dark:text-gray-300 break-words leading-snug; } -.setting-toggle__hint { +:deep(.setting-toggle__hint) { @apply text-xs text-gray-500 dark:text-gray-400 break-words; } -.info-callout { +:deep(.info-callout) { @apply rounded-2xl border border-blue-100 dark:border-blue-900/40 bg-blue-50/60 dark:bg-blue-900/20 px-3 py-3 text-blue-900 dark:text-blue-100; } -.monospace-field { +:deep(.monospace-field) { font-family: "Roboto Mono", monospace; } -.address-card { +:deep(.address-card) { @apply relative border border-gray-200/70 dark:border-zinc-800/80 py-3 px-3 sm:rounded-xl sm:bg-black/2 dark:sm:bg-white/2 space-y-2; } -.address-card__label { +:deep(.address-card__label) { @apply text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400; } -.address-card__value { +:deep(.address-card__value) { @apply text-sm text-gray-900 dark:text-white wrap-break-word pr-16; } -.address-card__action { +:deep(.address-card__action) { @apply absolute top-3 right-3 inline-flex items-center gap-1 rounded-full border border-gray-200 dark:border-zinc-700 px-3 py-1 text-xs font-semibold text-gray-700 dark:text-gray-100 bg-white/70 dark:bg-zinc-900/60 hover:border-blue-400 dark:hover:border-blue-500 transition; } .fade-enter-active, diff --git a/scripts/docker/runtime-setup-chainguard.sh b/scripts/docker/runtime-setup-chainguard.sh index 609c96c6..1d60679e 100755 --- a/scripts/docker/runtime-setup-chainguard.sh +++ b/scripts/docker/runtime-setup-chainguard.sh @@ -3,7 +3,7 @@ # Chainguard/Wolfi final-stage packages, pip bootstrap, and meshchat user. set -eu -apk add --no-cache opus libffi shadow +apk add --no-cache opus libffi shadow libseccomp pip install --no-cache-dir --upgrade "pip>=26.0" "setuptools" "jaraco.context>=6.1.0" rm -rf /root/.cache/pip diff --git a/scripts/docker/runtime-setup.sh b/scripts/docker/runtime-setup.sh index a716b5e0..b85c6884 100755 --- a/scripts/docker/runtime-setup.sh +++ b/scripts/docker/runtime-setup.sh @@ -7,7 +7,7 @@ set -eu VARIANT="${1:-${VARIANT:-standard}}" apk upgrade --no-cache -apk add --no-cache opusfile libffi espeak-ng su-exec +apk add --no-cache opusfile libffi espeak-ng su-exec libseccomp case "${VARIANT}" in standard) ;; diff --git a/tests/frontend/behaviorContracts.test.js b/tests/frontend/behaviorContracts.test.js index e4afda3c..82c5944f 100644 --- a/tests/frontend/behaviorContracts.test.js +++ b/tests/frontend/behaviorContracts.test.js @@ -105,6 +105,20 @@ describe("behavior contracts: user-visible wiring must stay connected", () => { expect(util).toContain("LOCAL_BACKEND_URL"); }); + it("SettingsPage deep-scopes shared toggle styles for extracted sections", () => { + const src = readSource("meshchatx/src/frontend/components/settings/SettingsPage.vue"); + expect(src).toContain(":deep(.setting-toggle)"); + expect(src).toContain(":deep(.setting-toggle__label)"); + expect(src).toContain(":deep(.setting-toggle__title)"); + }); + + it("Docker runtime images install libseccomp for Seccomp-BPF", () => { + const alpine = readSource("scripts/docker/runtime-setup.sh"); + const chainguard = readSource("scripts/docker/runtime-setup-chainguard.sh"); + expect(alpine).toMatch(/apk add[^\n]*libseccomp/); + expect(chainguard).toMatch(/apk add[^\n]*libseccomp/); + }); + it("Android backup of app data is disabled", () => { const src = readSource("android/app/src/main/AndroidManifest.xml"); expect(src).toMatch(/android:allowBackup\s*=\s*"false"/); diff --git a/tests/frontend/settingsSections.test.js b/tests/frontend/settingsSections.test.js index 989a25a3..45976b3c 100644 --- a/tests/frontend/settingsSections.test.js +++ b/tests/frontend/settingsSections.test.js @@ -104,6 +104,41 @@ describe("TelephonySettingsSection", () => { }); describe("AppearanceSettingsSection", () => { + it("renders glass and split-view toggles as stacked setting rows", () => { + const wrapper = mount(AppearanceSettingsSection, { + props: { + visible: true, + config: { + theme: "dark", + messages_sidebar_position: "left", + message_font_size: 14, + message_icon_size: 28, + ui_transparency: 0, + ui_glass_enabled: true, + messages_multi_pane_enabled: true, + nomad_tabs_enabled: true, + rrc_enabled: true, + rrc_unread_badges_enabled: true, + }, + detailedOutboundSendStatus: false, + messageIconPreviewStyle: { width: "28px", height: "28px" }, + }, + global: { + mocks: { $t: (key) => key }, + stubs: { + Toggle: { + template: '