mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-08 23:13:17 +08:00
Improve WhatsApp delivery suggestions and peer labels (ops.30).
Surface chat/access-list contacts as selectable targets with clearer nicknames, and keep conversation peers usable for ops schedulers. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
e84630565c
commit
356538ac18
19 changed files with 827 additions and 324 deletions
|
|
@ -571,8 +571,8 @@ var React25 = __toESM(require("react"), 1);
|
|||
// package.json
|
||||
var package_default = {
|
||||
name: "dsh-im-ops",
|
||||
version: "4.9.1-ops.22",
|
||||
description: "Ops fork of dsh-im (all channels kept). Based on @xmanrui/dsh-im@4.9.1 \u2014 access/session policies owned here.",
|
||||
version: "4.9.1-ops.30",
|
||||
description: "Ops fork of dsh-im (all channels kept). Based on @xmanrui/dsh-im@4.9.1 - access/session policies owned here.",
|
||||
keywords: [
|
||||
"deepseek-harness",
|
||||
"dsh",
|
||||
|
|
@ -1725,12 +1725,16 @@ var EN = Object.freeze({
|
|||
"\u5DF2\u804A\u4F1A\u8BDD": "Conversation",
|
||||
"\u4ECE\u4F1A\u8BDD\u9009\u62E9targetID": "Select a targetID from conversations",
|
||||
"\u9009\u62E9\u540E\u4F1A\u81EA\u52A8\u586B\u5199\u76EE\u6807\u4FE1\u606F\u548C\u8C03\u7528\u522B\u540D\uFF0C\u786E\u8BA4\u540E\u518D\u4FDD\u5B58\u3002": "Selecting a conversation fills the target details and call alias. Review them before saving.",
|
||||
"\u4F1A\u5217\u51FA\u5DF2\u804A\u8FC7\u7684\u79C1\u804A/\u7FA4\u804A\uFF0C\u4EE5\u53CA\u8BBF\u95EE\u540D\u5355\u91CC\u8BB0\u4F4F\u7684\u8054\u7CFB\u4EBA\u4E0E\u7FA4\uFF08\u663E\u793A\u4E3A\u6635\u79F0 \xB7 \u7535\u8BDD / \u7FA4\u540D\uFF09\u3002": "Lists known DMs and groups, plus remembered access-list contacts and groups (shown as nickname \xB7 phone / group name).",
|
||||
"\u53EF\u9009\u6295\u9012\u4F1A\u8BDD": "Available delivery conversations",
|
||||
"\u4F8B\u5982 \u5F20\u4E09 \xB7 13800138000": "For example, Alice \xB7 13800138000",
|
||||
"\u6B63\u5728\u5237\u65B0\u2026": "Refreshing\u2026",
|
||||
"\u5237\u65B0": "Refresh",
|
||||
"\u6B63\u5728\u8BFB\u53D6\u5DF2\u804A\u4F1A\u8BDD\u2026": "Loading known conversations\u2026",
|
||||
"\u65E0\u6CD5\u8BFB\u53D6\u5DF2\u804A\u4F1A\u8BDD\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002": "Could not load known conversations. Try again later.",
|
||||
"\u8FD8\u6CA1\u6709\u53EF\u9009\u62E9\u7684\u4F1A\u8BDD": "No conversations to choose from",
|
||||
"\u5148\u5728\u5BF9\u5E94\u5E73\u53F0\u4E0E\u673A\u5668\u4EBA\u804A\u4E00\u6761\u6D88\u606F\uFF0C\u518D\u5237\u65B0\u3002": "Send the bot a message on the platform, then refresh.",
|
||||
"\u5148\u5728\u5BF9\u5E94\u5E73\u53F0\u4E0E\u673A\u5668\u4EBA\u804A\u4E00\u6761\u6D88\u606F\uFF08\u79C1\u804A\u6216\u7FA4\u804A\uFF09\uFF0C\u6216\u5148\u5728\u300C\u8BBF\u95EE\u8BBE\u7F6E\u300D\u91CC\u51FA\u73B0\u8FC7\u8054\u7CFB\u4EBA/\u7FA4\uFF0C\u518D\u5237\u65B0\u3002": "Chat with the bot first (DM or group), or wait until contacts/groups appear under Access settings, then refresh.",
|
||||
"\u5DF2\u6DFB\u52A0": "Added",
|
||||
"\u624B\u52A8\u586B\u5199\uFF08\u9AD8\u7EA7\uFF09": "Enter manually (advanced)",
|
||||
"\u6D4B\u8BD5\u6D88\u606F\u5DF2\u53D1\u9001\uFF0C\u8BF7\u5230\u76EE\u6807\u4F1A\u8BDD\u786E\u8BA4\u3002": "Test message sent. Confirm it in the target conversation.",
|
||||
|
|
@ -13901,7 +13905,7 @@ function TargetForm({
|
|||
value: name2,
|
||||
disabled: testing,
|
||||
maxLength: 80,
|
||||
placeholder: "\u4F8B\u5982 \u6BCF\u65E5\u6C47\u62A5\u7FA4",
|
||||
placeholder: definition.label === "WhatsApp" ? "\u4F8B\u5982 \u5F20\u4E09 \xB7 13800138000" : "\u4F8B\u5982 \u6BCF\u65E5\u6C47\u62A5\u7FA4",
|
||||
onChange: (event) => setName(event.target.value)
|
||||
})
|
||||
),
|
||||
|
|
@ -13975,12 +13979,6 @@ function TargetForm({
|
|||
)
|
||||
);
|
||||
}
|
||||
function suggestionOptionLabel(definition, suggestion, added) {
|
||||
const name2 = suggestionDisplayName(suggestion);
|
||||
const type = localizeText(kindLabel(definition, suggestion.kind));
|
||||
const route = fieldsFor(definition, suggestion.kind).map((field) => maskRouteValue(suggestion.route?.[field.key])).filter(Boolean).join(" \xB7 ");
|
||||
return [name2, type, route, added ? localizeText("\u5DF2\u6DFB\u52A0") : null].filter(Boolean).join(" \xB7 ");
|
||||
}
|
||||
function TargetSuggestionPicker({
|
||||
definition,
|
||||
phase,
|
||||
|
|
@ -13993,6 +13991,7 @@ function TargetSuggestionPicker({
|
|||
onCancel
|
||||
}) {
|
||||
const configured = new Set(targets.map((target) => routeIdentity(definition, target)).filter(Boolean));
|
||||
const channelHint = definition.label === "WhatsApp" ? "\u4F1A\u5217\u51FA\u5DF2\u804A\u8FC7\u7684\u79C1\u804A/\u7FA4\u804A\uFF0C\u4EE5\u53CA\u8BBF\u95EE\u540D\u5355\u91CC\u8BB0\u4F4F\u7684\u8054\u7CFB\u4EBA\u4E0E\u7FA4\uFF08\u663E\u793A\u4E3A\u6635\u79F0 \xB7 \u7535\u8BDD / \u7FA4\u540D\uFF09\u3002" : "\u9009\u62E9\u540E\u4F1A\u81EA\u52A8\u586B\u5199\u76EE\u6807\u4FE1\u606F\u548C\u8C03\u7528\u522B\u540D\uFF0C\u786E\u8BA4\u540E\u518D\u4FDD\u5B58\u3002";
|
||||
return h2(
|
||||
"section",
|
||||
{ className: "dim-targetSuggestions", "aria-label": "\u4ECE\u5DF2\u804A\u8FC7\u7684\u4F1A\u8BDD\u9009\u62E9" },
|
||||
|
|
@ -14003,7 +14002,7 @@ function TargetSuggestionPicker({
|
|||
"div",
|
||||
null,
|
||||
h2("h3", null, "\u4ECE\u5DF2\u804A\u8FC7\u7684\u4F1A\u8BDD\u9009\u62E9"),
|
||||
h2("p", null, "\u9009\u62E9\u540E\u4F1A\u81EA\u52A8\u586B\u5199\u76EE\u6807\u4FE1\u606F\u548C\u8C03\u7528\u522B\u540D\uFF0C\u786E\u8BA4\u540E\u518D\u4FDD\u5B58\u3002")
|
||||
h2("p", null, channelHint)
|
||||
),
|
||||
h2(DeliveryButton, {
|
||||
onClick: () => void onRefresh(),
|
||||
|
|
@ -14019,33 +14018,42 @@ function TargetSuggestionPicker({
|
|||
"div",
|
||||
{ className: "dim-targetSuggestionState" },
|
||||
h2("strong", null, "\u8FD8\u6CA1\u6709\u53EF\u9009\u62E9\u7684\u4F1A\u8BDD"),
|
||||
h2("p", null, "\u5148\u5728\u5BF9\u5E94\u5E73\u53F0\u4E0E\u673A\u5668\u4EBA\u804A\u4E00\u6761\u6D88\u606F\uFF0C\u518D\u5237\u65B0\u3002")
|
||||
h2("p", null, "\u5148\u5728\u5BF9\u5E94\u5E73\u53F0\u4E0E\u673A\u5668\u4EBA\u804A\u4E00\u6761\u6D88\u606F\uFF08\u79C1\u804A\u6216\u7FA4\u804A\uFF09\uFF0C\u6216\u5148\u5728\u300C\u8BBF\u95EE\u8BBE\u7F6E\u300D\u91CC\u51FA\u73B0\u8FC7\u8054\u7CFB\u4EBA/\u7FA4\uFF0C\u518D\u5237\u65B0\u3002")
|
||||
) : h2(
|
||||
"label",
|
||||
{ className: "dim-targetSuggestionField" },
|
||||
h2("span", null, "\u5DF2\u804A\u4F1A\u8BDD"),
|
||||
h2(
|
||||
"select",
|
||||
{
|
||||
name: "suggestion",
|
||||
value: "",
|
||||
onChange: (event) => {
|
||||
if (event.target.value === "") return;
|
||||
const suggestion = suggestions[Number(event.target.value)];
|
||||
if (suggestion) onSelect(suggestion);
|
||||
}
|
||||
},
|
||||
h2("option", { value: "", disabled: true }, "\u4ECE\u4F1A\u8BDD\u9009\u62E9targetID"),
|
||||
suggestions.map((suggestion, index) => {
|
||||
const identity = routeIdentity(definition, suggestion);
|
||||
const added = configured.has(identity);
|
||||
return React23.createElement("option", {
|
||||
key: suggestion.id ?? suggestion.suggestionId ?? `${identity}:${index}`,
|
||||
value: String(index),
|
||||
disabled: added
|
||||
}, suggestionOptionLabel(definition, suggestion, added));
|
||||
})
|
||||
)
|
||||
"ul",
|
||||
{ className: "dim-targetSuggestionList", role: "listbox", "aria-label": "\u53EF\u9009\u6295\u9012\u4F1A\u8BDD" },
|
||||
suggestions.map((suggestion, index) => {
|
||||
const identity = routeIdentity(definition, suggestion);
|
||||
const added = configured.has(identity);
|
||||
return h2(
|
||||
"li",
|
||||
{ key: suggestion.id ?? suggestion.suggestionId ?? `${identity}:${index}` },
|
||||
h2(
|
||||
"button",
|
||||
{
|
||||
type: "button",
|
||||
className: "dim-targetSuggestionItem",
|
||||
role: "option",
|
||||
"aria-disabled": added ? "true" : void 0,
|
||||
disabled: added,
|
||||
onClick: () => {
|
||||
if (!added) onSelect(suggestion);
|
||||
}
|
||||
},
|
||||
// Platform display names must stay raw (bypass h() i18n phrase rewrite).
|
||||
React23.createElement(
|
||||
"strong",
|
||||
null,
|
||||
suggestionDisplayName(suggestion) || suggestionFallbackName(definition, suggestion)
|
||||
),
|
||||
h2("span", null, [
|
||||
localizeText(kindLabel(definition, suggestion.kind)),
|
||||
added ? localizeText("\u5DF2\u6DFB\u52A0") : null
|
||||
].filter(Boolean).join(" \xB7 ")),
|
||||
React23.createElement("code", null, fieldsFor(definition, suggestion.kind).map((field) => maskRouteValue(suggestion.route?.[field.key])).filter(Boolean).join(" \xB7 "))
|
||||
)
|
||||
);
|
||||
})
|
||||
),
|
||||
h2(
|
||||
"div",
|
||||
|
|
@ -14932,6 +14940,13 @@ body[data-ds-dark-theme] .dim-page select option, body[data-ds-dark-theme] .dim-
|
|||
.dim-targetSuggestionField { min-width: 0; display: grid; gap: 5px; margin-top: 12px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 16px; }
|
||||
.dim-targetSuggestionField select { width: 100%; min-width: 0; height: 38px; padding: 0 10px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 12px; cursor: pointer; }
|
||||
.dim-targetSuggestionField select:focus { outline: 2px solid color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 28%, transparent); border-color: var(--dsw-alias-state-business-primary, #3370ff); }
|
||||
.dim-targetSuggestionList { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 8px; max-height: 280px; overflow: auto; }
|
||||
.dim-targetSuggestionItem { width: 100%; box-sizing: border-box; display: grid; gap: 2px; text-align: left; padding: 10px 12px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; background: var(--dsw-alias-bg-layer-1, #fff); color: inherit; font: inherit; cursor: pointer; }
|
||||
.dim-targetSuggestionItem:hover:not(:disabled) { border-color: var(--dsw-alias-state-business-primary, #3370ff); }
|
||||
.dim-targetSuggestionItem:disabled { opacity: 0.55; cursor: not-allowed; }
|
||||
.dim-targetSuggestionItem strong { color: var(--dsw-alias-label-primary, #1f2329); font-size: 13px; line-height: 20px; font-weight: 600; }
|
||||
.dim-targetSuggestionItem span { color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 16px; }
|
||||
.dim-targetSuggestionItem code { color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; line-height: 16px; word-break: break-all; }
|
||||
.dim-targetForm { margin-top: 14px; padding: 14px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 10px; background: var(--dsw-alias-bg-module-platform, #f7f8fa); }
|
||||
.dim-targetFormHeading h3 { margin: 0; font-size: 14px; line-height: 21px; }
|
||||
.dim-targetFormHeading p { margin: 2px 0 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 17px; }
|
||||
|
|
|
|||
448
lib/index.js
448
lib/index.js
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue