From de3455becfffcb9d5efb47ccc5580b37be7efaa6 Mon Sep 17 00:00:00 2001 From: Silberengel Date: Thu, 23 Apr 2026 15:34:02 +0200 Subject: [PATCH] copy payto addresses --- assets/bootstrap.js | 6 ++++ assets/controllers/copy_text_controller.js | 30 +++++++++++++++++++ assets/styles/app.css | 23 +++++++++++++- .../partial/author_profile_header.html.twig | 15 +++++++++- 4 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 assets/controllers/copy_text_controller.js diff --git a/assets/bootstrap.js b/assets/bootstrap.js index 306468d..219beff 100644 --- a/assets/bootstrap.js +++ b/assets/bootstrap.js @@ -1,6 +1,7 @@ import { startStimulusApp } from '@symfony/stimulus-bundle'; import ArticleCommentsController from './controllers/article_comments_controller.js'; import CommentReplyController from './controllers/comment_reply_controller.js'; +import CopyTextController from './controllers/copy_text_controller.js'; const app = startStimulusApp(); @@ -15,3 +16,8 @@ try { } catch { /* already registered by the bundle */ } +try { + app.register('copy-text', CopyTextController); +} catch { + /* already registered by the bundle */ +} diff --git a/assets/controllers/copy_text_controller.js b/assets/controllers/copy_text_controller.js new file mode 100644 index 0000000..1227902 --- /dev/null +++ b/assets/controllers/copy_text_controller.js @@ -0,0 +1,30 @@ +import { Controller } from '@hotwired/stimulus'; + +/** + * Copies data-copy-text-text-value to the clipboard (e.g. full payment URI for wallets). + */ +export default class extends Controller { + static values = { text: String }; + + static targets = ['button']; + + async copy() { + const t = this.textValue ?? ''; + if (t === '') { + return; + } + try { + await navigator.clipboard.writeText(t); + const btn = this.hasButtonTarget ? this.buttonTarget : this.element.querySelector('button'); + if (btn) { + const prev = btn.textContent; + btn.textContent = 'Copied'; + window.setTimeout(() => { + btn.textContent = prev; + }, 2000); + } + } catch (e) { + console.warn('Copy failed', e); + } + } +} diff --git a/assets/styles/app.css b/assets/styles/app.css index 4a27403..3f89fe7 100644 --- a/assets/styles/app.css +++ b/assets/styles/app.css @@ -614,13 +614,34 @@ footer a { .author-profile__meta-value, .author-profile__identity-link, -.author-profile__payment-link { +.author-profile__payment-addr { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.author-profile__payment-value { + display: flex; + align-items: center; + gap: 0.4rem; + min-width: 0; + max-width: 100%; +} + +.author-profile__payment-addr { + flex: 1 1 auto; + color: inherit; + text-decoration: none; +} + +.author-profile__copy-btn { + flex-shrink: 0; + font-size: 0.75rem; + padding: 0.2rem 0.5rem; + line-height: 1.2; +} + /* NIP-05: ellipsis long addresses; keep ✓ immediately after the (truncated) text, not at the column edge. */ .author-profile__nip05-value { display: flex; diff --git a/templates/partial/author_profile_header.html.twig b/templates/partial/author_profile_header.html.twig index 4d440d2..e290e6c 100644 --- a/templates/partial/author_profile_header.html.twig +++ b/templates/partial/author_profile_header.html.twig @@ -51,7 +51,20 @@ {% for row in profile_payment_links %}
  • - {{ row.label|e }} +
    + {{ row.label|e }} + +
  • {% endfor %}