Collapsible shortcut/transition rows, optional replacement, name fallback
- Shortcuts and Transitions: saved entries collapse to a summary row (name + on/off badge); click to expand, Collapse button to close without saving - Transition summary also shows trigger phrase in italic next to the name - Shortcuts: replacement is no longer required; blank/missing defaults to [""] which removes the matched phrase (same as explicit empty replacement) - Shortcuts: name falls back to first activation word when left blank - New summary row CSS: badge-on/badge-off, label, trigger styles Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
889e4dc2c8
commit
acdc4c41d6
+3
-3
@@ -304,10 +304,10 @@ def normalize_shortcut_item(item, fallback_name=""):
|
||||
return None
|
||||
name = normalize_shortcut_name(item.get("name"), fallback_name)
|
||||
triggers = shortcut_list(item.get("triggers", item.get("activation_words", item.get("activation", []))))
|
||||
replacements = _shortcut_replacements(item.get("replacements", item.get("replacement", [])))
|
||||
replacements = _shortcut_replacements(item.get("replacements", item.get("replacement", []))) or [""]
|
||||
if not name:
|
||||
name = triggers[0] if triggers else ""
|
||||
if not name or not triggers or not replacements:
|
||||
if not name or not triggers:
|
||||
return None
|
||||
created = str(item.get("created_at") or now_iso())
|
||||
return {
|
||||
@@ -376,7 +376,7 @@ def shortcut_items(data=None):
|
||||
def save_shortcut_item(payload):
|
||||
item = normalize_shortcut_item(payload)
|
||||
if item is None:
|
||||
raise ValueError("Shortcut name, activation phrase, and replacement phrase are required.")
|
||||
raise ValueError("Shortcut activation phrase and replacement phrase are required.")
|
||||
data = load_shortcut_db()
|
||||
shortcuts = data.setdefault("shortcuts", {})
|
||||
key = shortcut_key(item["name"])
|
||||
|
||||
+79
-2
@@ -659,7 +659,23 @@ function openPanel(node) {
|
||||
}
|
||||
|
||||
drafts.forEach((item, index) => {
|
||||
const isSaved = !!item.key;
|
||||
if (!("_expanded" in item)) item._expanded = !isSaved;
|
||||
|
||||
const rowEl = el("div", "funpack-studio-shortcut-row");
|
||||
|
||||
if (!item._expanded) {
|
||||
const summary = el("div", "funpack-studio-shortcut-summary");
|
||||
const label = el("span", "funpack-studio-shortcut-label", item.name || "(unnamed)");
|
||||
const badge = el("span", item.enabled !== false ? "funpack-studio-badge-on" : "funpack-studio-badge-off",
|
||||
item.enabled !== false ? "on" : "off");
|
||||
summary.append(label, badge);
|
||||
summary.addEventListener("click", () => { item._expanded = true; renderTab("Shortcuts"); });
|
||||
rowEl.append(summary);
|
||||
list.append(rowEl);
|
||||
return;
|
||||
}
|
||||
|
||||
const top = el("div", "funpack-studio-shortcut-top");
|
||||
const nameInput = textInput(item.name || "", "Shortcut name");
|
||||
nameInput.addEventListener("input", () => { item.name = nameInput.value; });
|
||||
@@ -693,6 +709,8 @@ function openPanel(node) {
|
||||
renderTab("Shortcuts");
|
||||
} catch (e) { showError(root, e.message); }
|
||||
});
|
||||
const collapseBtn = btn("Collapse");
|
||||
collapseBtn.addEventListener("click", () => { item._expanded = false; renderTab("Shortcuts"); });
|
||||
const delBtn = btn("Delete", "danger");
|
||||
delBtn.addEventListener("click", async () => {
|
||||
try {
|
||||
@@ -705,7 +723,7 @@ function openPanel(node) {
|
||||
renderTab("Shortcuts");
|
||||
} catch (e) { showError(root, e.message); }
|
||||
});
|
||||
actions.append(saveBtn, delBtn);
|
||||
actions.append(saveBtn, collapseBtn, delBtn);
|
||||
rowEl.append(top, triggerArea, replacementArea, actions);
|
||||
list.append(rowEl);
|
||||
});
|
||||
@@ -764,7 +782,24 @@ function openPanel(node) {
|
||||
}
|
||||
|
||||
drafts.forEach((item, index) => {
|
||||
const isSaved = !!item.key;
|
||||
if (!("_expanded" in item)) item._expanded = !isSaved;
|
||||
|
||||
const rowEl = el("div", "funpack-studio-shortcut-row");
|
||||
|
||||
if (!item._expanded) {
|
||||
const summary = el("div", "funpack-studio-shortcut-summary");
|
||||
const label = el("span", "funpack-studio-shortcut-label", item.name || item.trigger || "(unnamed)");
|
||||
const trigger = el("span", "funpack-studio-shortcut-trigger", item.trigger || "");
|
||||
const badge = el("span", item.enabled !== false ? "funpack-studio-badge-on" : "funpack-studio-badge-off",
|
||||
item.enabled !== false ? "on" : "off");
|
||||
summary.append(label, trigger, badge);
|
||||
summary.addEventListener("click", () => { item._expanded = true; renderTab("Transitions"); });
|
||||
rowEl.append(summary);
|
||||
list.append(rowEl);
|
||||
return;
|
||||
}
|
||||
|
||||
const top = el("div", "funpack-studio-shortcut-top");
|
||||
const nameInput = textInput(item.name || "", "Label (display only)");
|
||||
nameInput.addEventListener("input", () => { item.name = nameInput.value; });
|
||||
@@ -790,6 +825,8 @@ function openPanel(node) {
|
||||
renderTab("Transitions");
|
||||
} catch (e) { showError(root, e.message); }
|
||||
});
|
||||
const collapseBtn = btn("Collapse");
|
||||
collapseBtn.addEventListener("click", () => { item._expanded = false; renderTab("Transitions"); });
|
||||
const delBtn = btn("Delete", "danger");
|
||||
delBtn.addEventListener("click", async () => {
|
||||
try {
|
||||
@@ -802,7 +839,7 @@ function openPanel(node) {
|
||||
renderTab("Transitions");
|
||||
} catch (e) { showError(root, e.message); }
|
||||
});
|
||||
actions.append(saveBtn, delBtn);
|
||||
actions.append(saveBtn, collapseBtn, delBtn);
|
||||
rowEl.append(top, triggerInput, actions);
|
||||
list.append(rowEl);
|
||||
});
|
||||
@@ -1334,6 +1371,46 @@ function injectStyles() {
|
||||
justify-content: flex-end;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.funpack-studio-shortcut-summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
padding: 2px 0;
|
||||
}
|
||||
.funpack-studio-shortcut-summary:hover .funpack-studio-shortcut-label {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.funpack-studio-shortcut-label {
|
||||
font-weight: 500;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.funpack-studio-shortcut-trigger {
|
||||
font-size: 0.82em;
|
||||
color: rgba(255,255,255,0.45);
|
||||
font-style: italic;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.funpack-studio-badge-on {
|
||||
font-size: 0.75em;
|
||||
padding: 1px 6px;
|
||||
border-radius: 10px;
|
||||
background: rgba(80,180,100,0.25);
|
||||
color: #7ddb8f;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.funpack-studio-badge-off {
|
||||
font-size: 0.75em;
|
||||
padding: 1px 6px;
|
||||
border-radius: 10px;
|
||||
background: rgba(255,255,255,0.07);
|
||||
color: rgba(255,255,255,0.35);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.lora-name, .lora-type { min-height: 28px; padding: 4px 6px;
|
||||
border: 1px solid rgba(180,190,200,0.28); border-radius: 5px;
|
||||
background: #17191d; color: #f2f2f2; outline: none; width: 100%; }
|
||||
|
||||
Reference in New Issue
Block a user