tauri-app: 8c profile copy buttons

The profile view now has two clipboard actions:
  * 'copy did'  — copies the bare DID to the system clipboard
  * 'copy at-uri' — copies 'at://<did>/app.twi.post' as a shareable link

Both surface a toast confirmation via the existing
maarcadetweet:notification event, so the user gets a small
'copied: ...' toast for confirmation. Right-click on a toast
still dismisses without action.

The copyToClipboard helper is in App.svelte (not pushed to
client.ts) because it only uses the browser navigator API.
This commit is contained in:
tomdebone
2026-07-06 21:26:24 +02:00
parent 238823aae1
commit 9eda0c2449
+40
View File
@@ -135,6 +135,25 @@
}
}
async function copyToClipboard(text: string) {
try {
await navigator.clipboard.writeText(text);
// Surface a tiny inline confirmation by reusing the toast stack.
// We dispatch the toast event (not pushToast directly) so the
// notification toast gets the close-on-click behavior.
const ev = new CustomEvent("maarcadetweet:notification", {
detail: {
title: "clipboard",
body: `copied: ${text.length > 40 ? text.slice(0, 37) + "…" : text}`,
url: null,
},
});
window.dispatchEvent(ev);
} catch (e) {
pushToast("error", `> clipboard failed: ${String(e)}`);
}
}
// We need to hoist these into the onMount closure (which is below)
// so the addEventListener / removeEventListener pair stays paired.
// (`_toastHandler` is the function below; the other two are
@@ -425,6 +444,21 @@
<span class="profile__handle">{displayHandle(profile.handle)}</span>
<span class="profile__did" title={profile.did}>{profile.did}</span>
</header>
<div class="profile__actions">
<button
class="btn btn--ghost"
type="button"
title="Copy DID to clipboard"
onclick={() => copyToClipboard(profile!.did)}
>copy did</button>
<button
class="btn btn--ghost"
type="button"
title="Copy AT URI to clipboard"
onclick={() =>
copyToClipboard(`at://${profile!.did}/app.twi.post`)}
>copy at-uri</button>
</div>
<dl class="counts">
<div>
<dt>followers</dt>
@@ -540,6 +574,12 @@
overflow: auto;
padding: var(--s-3);
}
.profile__actions {
display: flex;
gap: var(--s-2);
margin: var(--s-3) 0;
}
.head {
font-family: var(--font-mono);
font-size: var(--fs-50);