Antispam: "Mark as Spam" belongs in the Actions menu
A button pinned to every message header is a persistent control; marking spam is a verb you reach for occasionally, like Reply or Delete. It now lives in the Actions menu, between Labels and Delete. That needed a slot inside the dropdown, which the catalog had no name for: `message.actions.menu`. The host wraps it so any click closes the menu, leaving a bundle to do nothing but act. The UI kit gains `.wm-menu-item`, @applying the exact utilities ThreadView's own menu items use — the same trick the sidebar shell already relies on, so a plugin verb is indistinguishable from a core one rather than approximately similar. Labels follow the folder as before: "Mark as Spam" in the inbox or archive, "Mark as not spam" in the spam folder, nothing in Sent/Drafts/Trash. A message already taught shows that, disabled, instead of offering the lesson again. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018SqJYt7jD7oUEkoY68sBZo
This commit is contained in:
@@ -26,7 +26,17 @@ JobFunc = Callable[..., Awaitable[Any]]
|
||||
|
||||
# The frozen slot catalog (SPEC §11.3). Bundles are injected into these UI points.
|
||||
SLOT_NAMES: frozenset[str] = frozenset(
|
||||
{"thread.toolbar", "message.actions", "message.banner", "sidebar.section", "settings.page"}
|
||||
{
|
||||
"thread.toolbar",
|
||||
"message.actions",
|
||||
# Inside the per-message Actions dropdown, for plugin verbs that belong
|
||||
# with Reply/Print/Delete rather than sitting on the header as a button.
|
||||
# The host closes the menu after a click, so a bundle here just acts.
|
||||
"message.actions.menu",
|
||||
"message.banner",
|
||||
"sidebar.section",
|
||||
"settings.page",
|
||||
}
|
||||
)
|
||||
|
||||
_NAME_RE = re.compile(r"[a-z][a-z0-9_]*")
|
||||
|
||||
Reference in New Issue
Block a user