mirror of
https://github.com/Quad4-Software/MeshChatX.git
synced 2026-08-18 09:49:09 -04:00
feat: improve SettingsPage styles with deep-scoping and add libseccomp to Docker setup scripts
This commit is contained in:
parent
f89f91e267
commit
835667dba3
6 changed files with 80 additions and 27 deletions
BIN
meshchatx.rsm
BIN
meshchatx.rsm
Binary file not shown.
|
|
@ -5265,70 +5265,74 @@ export default {
|
|||
|
||||
<style scoped>
|
||||
@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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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) ;;
|
||||
|
|
|
|||
|
|
@ -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"/);
|
||||
|
|
|
|||
|
|
@ -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: '<button type="button" class="toggle-stub" />',
|
||||
},
|
||||
MaterialDesignIcon: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
const toggles = wrapper.findAll("label.setting-toggle");
|
||||
expect(toggles.length).toBeGreaterThanOrEqual(4);
|
||||
expect(toggles[0].find(".setting-toggle__title").text()).toContain("ui_glass_enabled");
|
||||
expect(toggles[0].find(".setting-toggle__description").text()).toContain("ui_glass_enabled_description");
|
||||
});
|
||||
|
||||
it("emits theme and field events without mutating config prop", async () => {
|
||||
const config = {
|
||||
theme: "light",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue