Use host native Switch for reasoning binding
This commit is contained in:
182
lib/client.js
182
lib/client.js
@@ -25,6 +25,7 @@ __export(index_exports, {
|
||||
});
|
||||
module.exports = __toCommonJS(index_exports);
|
||||
var import_react = require("react");
|
||||
var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
||||
|
||||
// src/client/skin.css
|
||||
var skin_default = `.liang-skin-backdrop {
|
||||
@@ -526,90 +527,14 @@ body[data-liang-skin="on"] .liang-effort-control__range::-webkit-slider-thumb {
|
||||
}
|
||||
|
||||
.liang-appearance-binding {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 28px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 4px 0 0;
|
||||
color: var(--dsw-alias-label-primary);
|
||||
font: inherit;
|
||||
gap: 24px;
|
||||
padding: 16px 0;
|
||||
border-bottom: 0.5px solid var(--dsw-alias-border-l2);
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.liang-appearance-binding__label {
|
||||
display: block;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.liang-appearance-binding__copy {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
flex-direction: column;
|
||||
gap: 1px;
|
||||
}
|
||||
|
||||
.liang-appearance-binding__description {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
color: var(--dsw-alias-label-secondary);
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.liang-appearance-binding__input {
|
||||
position: relative;
|
||||
flex: 0 0 36px;
|
||||
width: 36px;
|
||||
height: 20px;
|
||||
margin: 0;
|
||||
border: 1px solid var(--dsw-alias-border-l2);
|
||||
border-radius: 999px;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
appearance: none;
|
||||
background: var(--dsw-alias-interactive-bg-hover, var(--dsw-alias-bg-module-platform));
|
||||
}
|
||||
|
||||
.liang-appearance-binding__input::before {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
content: "";
|
||||
background: var(--dsw-alias-label-primary);
|
||||
box-shadow: 0 1px 3px rgb(0 0 0 / 18%);
|
||||
transition: transform 160ms ease, background-color 160ms ease;
|
||||
}
|
||||
|
||||
.liang-appearance-binding__input:checked {
|
||||
border-color: var(--dsw-static-neutral-bluish-400);
|
||||
background: var(--dsw-static-neutral-bluish-400);
|
||||
}
|
||||
|
||||
.liang-appearance-binding__input:checked::before {
|
||||
background: var(--dsw-alias-bg-layer-1, #fff);
|
||||
transform: translateX(16px);
|
||||
}
|
||||
|
||||
.liang-appearance-binding__input:focus-visible {
|
||||
box-shadow: 0 0 0 2px var(--dsw-alias-interactive-bg-hover);
|
||||
}
|
||||
|
||||
.liang-appearance-binding__input:disabled {
|
||||
cursor: progress;
|
||||
opacity: 0.7;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
@@ -639,8 +564,6 @@ body[data-liang-skin="on"] .liang-effort-control__range::-webkit-slider-thumb {
|
||||
// src/client/appearance.ts
|
||||
var NATIVE_APPEARANCE_ROW = '[class*="_cubeRow"]';
|
||||
var LIANG_APPEARANCE_BUTTON = "liang-appearance-choice";
|
||||
var LIANG_BINDING_CONTROL = "liang-appearance-binding";
|
||||
var LIANG_BINDING_INPUT = "liang-appearance-binding__input";
|
||||
function hasClassSuffix(node, suffix) {
|
||||
return [...node.classList].some((name) => name.endsWith(suffix));
|
||||
}
|
||||
@@ -672,9 +595,7 @@ function installLiangAppearanceButton(scope, presenter, packageId) {
|
||||
nativeClickHandlers.clear();
|
||||
if (mounted === null) return;
|
||||
mounted.button.removeEventListener("click", mounted.handleCustomClick);
|
||||
mounted.bindingInput.removeEventListener("change", mounted.handleBindingChange);
|
||||
mounted.button.remove();
|
||||
mounted.binding.remove();
|
||||
mounted = null;
|
||||
};
|
||||
const choose = async (enabled) => {
|
||||
@@ -708,41 +629,7 @@ function installLiangAppearanceButton(scope, presenter, packageId) {
|
||||
void choose(true);
|
||||
};
|
||||
button.addEventListener("click", handleCustomClick);
|
||||
const binding = document.createElement("label");
|
||||
binding.className = LIANG_BINDING_CONTROL;
|
||||
binding.dataset.plugin = packageId;
|
||||
const bindingCopy = document.createElement("span");
|
||||
bindingCopy.className = "liang-appearance-binding__copy";
|
||||
const bindingLabel = document.createElement("span");
|
||||
bindingLabel.className = "liang-appearance-binding__label";
|
||||
const bindingText = english ? "Bind slider to reasoning level" : "\u6ED1\u52A8\u53D8\u7956\u7ED1\u5B9A\u601D\u8003\u7B49\u7EA7";
|
||||
bindingLabel.textContent = bindingText;
|
||||
const bindingDescription = document.createElement("span");
|
||||
bindingDescription.className = "liang-appearance-binding__description";
|
||||
bindingDescription.id = "liang-appearance-binding-description";
|
||||
bindingDescription.textContent = english ? "When off, the slider does not change the reasoning level." : "\u5173\u95ED\u4E4B\u540E\u6ED1\u5757\u4E0D\u8054\u52A8\u601D\u8003\u7B49\u7EA7";
|
||||
bindingCopy.append(bindingLabel, bindingDescription);
|
||||
const bindingInput = document.createElement("input");
|
||||
bindingInput.className = LIANG_BINDING_INPUT;
|
||||
bindingInput.type = "checkbox";
|
||||
bindingInput.setAttribute("role", "switch");
|
||||
bindingInput.setAttribute("aria-label", bindingText);
|
||||
bindingInput.setAttribute("aria-describedby", bindingDescription.id);
|
||||
const updateBinding = async () => {
|
||||
if (disposed || pending) return;
|
||||
try {
|
||||
await scope.setBindEffort(bindingInput.checked);
|
||||
} catch {
|
||||
} finally {
|
||||
if (!disposed) sync();
|
||||
}
|
||||
};
|
||||
const handleBindingChange = () => {
|
||||
void updateBinding();
|
||||
};
|
||||
bindingInput.addEventListener("change", handleBindingChange);
|
||||
binding.append(bindingCopy, bindingInput);
|
||||
return { row, group, button, binding, bindingInput, handleCustomClick, handleBindingChange };
|
||||
return { row, group, button, handleCustomClick };
|
||||
};
|
||||
const sync = () => {
|
||||
if (disposed) return;
|
||||
@@ -755,19 +642,11 @@ function installLiangAppearanceButton(scope, presenter, packageId) {
|
||||
unmount();
|
||||
}
|
||||
mounted ??= createMount(target.row, target.group);
|
||||
const { row, group, button, binding, bindingInput } = mounted;
|
||||
const { row, button } = mounted;
|
||||
if (button.parentElement !== row) row.append(button);
|
||||
const snapshot = scope.getSnapshot();
|
||||
button.disabled = pending;
|
||||
button.setAttribute("aria-pressed", String(snapshot.enabled));
|
||||
if (snapshot.enabled) {
|
||||
if (binding.parentElement !== group) group.append(binding);
|
||||
bindingInput.checked = snapshot.bindEffort;
|
||||
bindingInput.setAttribute("aria-checked", String(snapshot.bindEffort));
|
||||
bindingInput.disabled = pending;
|
||||
} else {
|
||||
binding.remove();
|
||||
}
|
||||
for (const [nativeButton, handler] of nativeClickHandlers) {
|
||||
if (target.nativeButtons.includes(nativeButton)) continue;
|
||||
nativeButton.removeEventListener("click", handler, { capture: true });
|
||||
@@ -1405,6 +1284,30 @@ function LiangEffortSlider({ directory, load, select, presenter, scope }) {
|
||||
}
|
||||
);
|
||||
}
|
||||
function EffortBindingRow({ scope, t }) {
|
||||
const snapshot = (0, import_react.useSyncExternalStore)(
|
||||
(listener) => scope.subscribe(listener),
|
||||
() => scope.getSnapshot()
|
||||
);
|
||||
const [pending, setPending] = (0, import_react.useState)(false);
|
||||
if (!snapshot.enabled) return null;
|
||||
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "liang-appearance-binding", "data-plugin": PACKAGE_ID, children: [
|
||||
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("effort.binding") }),
|
||||
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
||||
import_dsh_client_ui_primitives.Switch,
|
||||
{
|
||||
checked: snapshot.bindEffort,
|
||||
disabled: pending,
|
||||
label: t("effort.binding"),
|
||||
onChange: (next) => {
|
||||
if (pending) return;
|
||||
setPending(true);
|
||||
void scope.setBindEffort(next).catch(() => void 0).finally(() => setPending(false));
|
||||
}
|
||||
}
|
||||
)
|
||||
] });
|
||||
}
|
||||
var inject = [
|
||||
"slots",
|
||||
"sessions",
|
||||
@@ -1473,23 +1376,18 @@ function apply(ctx) {
|
||||
);
|
||||
ctx.effect(
|
||||
() => ctx.locale.register(LOCALE_NAMESPACE, {
|
||||
zh: {
|
||||
"appearance.title": "\u5916\u89C2",
|
||||
"appearance.light": "\u6D45\u8272",
|
||||
"appearance.dark": "\u6DF1\u8272",
|
||||
"appearance.system": "\u8DDF\u968F\u7CFB\u7EDF",
|
||||
"appearance.liang": "\u6ED1\u52A8\u53D8\u7956"
|
||||
},
|
||||
en: {
|
||||
"appearance.title": "Appearance",
|
||||
"appearance.light": "Light",
|
||||
"appearance.dark": "Dark",
|
||||
"appearance.system": "System",
|
||||
"appearance.liang": "Slider"
|
||||
}
|
||||
zh: { "effort.binding": "\u6ED1\u52A8\u53D8\u7956\u7ED1\u5B9A\u601D\u8003\u7B49\u7EA7" },
|
||||
en: { "effort.binding": "Bind slider to reasoning level" }
|
||||
}),
|
||||
"liang-intensity-skin: settings locale"
|
||||
);
|
||||
ctx.slots.inject("settings.general.item", () => ctx.slots.register({
|
||||
name: "settings.general.item",
|
||||
id: "liang-effort-binding",
|
||||
order: 10.5,
|
||||
locale: LOCALE_NAMESPACE,
|
||||
inject: () => ({ scope })
|
||||
}, EffortBindingRow));
|
||||
ctx.slots.inject("conversation.input.right", () => ctx.slots.register({
|
||||
name: "conversation.input.right",
|
||||
id: "liang-intensity-control",
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user