Skip to content

Let the remaining copy actions work where the page has no Clipboard API, and say when a copy fails - #959

Merged
WaylandYang merged 1 commit into
deeplethe:devfrom
Maya-Kid:fix/copy-actions-over-http
Sep 26, 2026
Merged

WaylandYang merged 1 commit into
deeplethe:devfrom
Maya-Kid:fix/copy-actions-over-http

Conversation

@Maya-Kid

Copy link
Copy Markdown
Contributor

This is the follow-up noted in the review of #954.

Problem

#954 gave the chat's copy actions copyText. Where navigator.clipboard does not exist, as on a base opened over plain http on a local network, it falls back to execCommand("copy").

Four copy actions elsewhere still called the Clipboard API directly. On such a page each one breaks in its own way:

Where What it copies Over plain http
Library, "Copy error" in the import error dialog the error text It calls navigator.clipboard.writeText without ?., so the click throws a TypeError and nothing is shown.
Library, the api source's key dialog the ingest token and the endpoint URL The same TypeError.
Tokens a new token and the MCP snippet ?. makes it do nothing, yet the button still reads "Copied".
Chat, "Copy title" in the conversation menu the conversation's title It does nothing. It also never says anything when it does work.

Change

  • clipboard.ts: new copyAndSay(text, copied).
    • It copies with copyText, then shows a toast: copied if the copy worked, or that it failed.
    • It returns whether it copied.
  • The four actions use it and keep their messages (errorCopied, tokenCopied, endpointCopied, account.copied). "Copy title" now says "Copied".
  • Tokens' CopyButton switches to "Copied" only after the copy worked. Before, it switched first and copied after.
  • Wording: copyFailed moves from S.ask to S.toast, next to the other messages every page shares, so a failed copy is worded in one place. The chat's copy button reads it from there, and the text is unchanged.

After this, clipboard.ts is the only file in web/src that touches navigator.clipboard.

Verification

Run in containers on a Linux host: Node 20 with pnpm 10.2.1, and Playwright 1.58.2 with Chromium.

New tests

  • clipboard.test.ts has two new cases for copyAndSay, each also checking the result it returns:
    • a copy that worked says the given message (this case goes through the fallback);
    • a copy that failed says S.toast.copyFailed.
  • chat-view.test.mjs:
  • Tokens and Library: the browser fixture mounts only the chat page. Their change is the call itself, so they are covered by the type check and the helper's tests.

On dev (aad5b06) with only the test changes

The new case fails in both rounds, waiting for a "Copied" that dev never shows: 24 tests, 22 pass, 2 fail (the case and its parent). The case stops at its first failing round, so it was run a second time with the rounds swapped. The vitest cases import the new function, so they were left out.

With this change

  • pnpm install --frozen-lockfile passes.
  • pnpm test: 189 passed.
  • pnpm build passes, including style-guard and tsc.
  • The browser test: 24 of 24 pass.

…PI, and say when a copy fails

Signed-off-by: dada-yan <BinjunYann@gmail.com>

@WaylandYang WaylandYang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for closing the loop on #954. One helper, four call sites, the Tokens button only saying Copied once it copied, and the failure wording in one place. Landing it. Thanks again.

@WaylandYang WaylandYang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maintainer review: sound, landing.

@WaylandYang
WaylandYang merged commit ee129ea into deeplethe:dev Sep 26, 2026
@Maya-Kid
Maya-Kid deleted the fix/copy-actions-over-http branch September 27, 2026 03:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants