Fix wave: scroll-lock without layout shift; every models write mirrors the stored record
Fix 1 (owner: "lock must not shift"): the settings dialog's scroll-lock no longer toggles the content column to overflow-hidden (which hid the scrollbar and shifted everything right). The column KEEPS overflow-y-auto — scrollbar and widths stay exactly as they are — and while any MenuShell is open, non-passive wheel + touchmove listeners on the column preventDefault so it cannot scroll (owner-ruled mechanism: the scrollbar may stay, scrolling must not happen, nothing may move). Native listeners via ref — React attaches synthetic wheel/touch passively at the root. Fix 2 (owner repro: xhigh pin survives a GLM swap on screen until reload): every models-writing surface now mirrors SERVER TRUTH, never the request body. The PUT already returns the full stored record with clamps applied — settings-dialog write() and the composer's save() now setRecord/setModels from the response, so a swap that rides an unsupported level shows the clamped value in the same interaction: the row trigger, the open menu's level list + checkmark, and the composer pill all read the stored record. Live-verified the owner's exact repro: deepseek pinned extra high → GLM swap via the slot menu → trigger/menu/pill showed the stored clamped level immediately; and the lock cycle: scroll 300 → blocked while open → 300 after release, zero positional shift at engage.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import type { ModelCatalogEntry, ModelCatalogResponse, ModelsSettings } from "@/src/core";
|
||||
import type { ModelCatalogEntry, ModelCatalogResponse, ModelsSettings, UserSettings } from "@/src/core";
|
||||
import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
|
||||
import { prettyModel } from "@/components/usage-format";
|
||||
import { ModelMenuList, ThinkingMenuList } from "@/components/settings/model-menu";
|
||||
@@ -172,7 +172,13 @@ export function ModelControl() {
|
||||
setError(body.error ?? `settings rejected (${res.status})`);
|
||||
return;
|
||||
}
|
||||
setModels(next);
|
||||
// Server truth, never the request body (fix wave): a pick
|
||||
// that rides an unsupported level lands CLAMPED in the record
|
||||
// — the pill must show the stored value in this interaction.
|
||||
const stored = (
|
||||
(await res.json().catch(() => null)) as { settings?: UserSettings } | null
|
||||
)?.settings?.models;
|
||||
setModels(stored ?? next);
|
||||
setOpen(null);
|
||||
notifySettingsSaved("models");
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user