From dc1126bdc845232bc9ace214311b0e78c8fd6c52 Mon Sep 17 00:00:00 2001 From: b1rdmania <102524336+b1rdmania@users.noreply.github.com> Date: Mon, 29 Dec 2025 16:37:06 +0000 Subject: [PATCH] Add fallback for iOS share when copy fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When clipboard copy fails, shows a text input with the share link so users can manually select and copy it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- index.html | 4 ++++ src/main.ts | 26 +++++++++++++++++++++----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index 54b400a..2d0e62d 100644 --- a/index.html +++ b/index.html @@ -1220,6 +1220,10 @@ + diff --git a/src/main.ts b/src/main.ts index 70e572b..76437f1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -55,6 +55,8 @@ class MotifApp { private copyLinkBtn!: HTMLButtonElement; private shareToXBtn!: HTMLButtonElement; + private shareFallback!: HTMLElement; + private shareFallbackInput!: HTMLInputElement; // Embed snippet UI private embedSection: HTMLElement | null = null; @@ -127,6 +129,8 @@ class MotifApp { this.copyLinkBtn = document.getElementById('copyLinkBtn') as HTMLButtonElement; this.shareToXBtn = document.getElementById('shareToXBtn') as HTMLButtonElement; + this.shareFallback = document.getElementById('shareFallback')!; + this.shareFallbackInput = document.getElementById('shareFallbackInput') as HTMLInputElement; // iOS audio unlock UI (Motif) this.iosAudioBanner = document.getElementById('iosAudioBanner')!; @@ -745,11 +749,21 @@ class MotifApp { } // Show feedback - const originalText = this.copyLinkBtn.textContent; - this.copyLinkBtn.textContent = copied ? 'Copied!' : 'Failed'; - setTimeout(() => { - this.copyLinkBtn.textContent = originalText; - }, 1500); + if (copied) { + const originalText = this.copyLinkBtn.textContent; + this.copyLinkBtn.textContent = 'Copied!'; + this.shareFallback.style.display = 'none'; + setTimeout(() => { + this.copyLinkBtn.textContent = originalText; + }, 1500); + } else { + // Show fallback with the link for manual copying + this.shareFallbackInput.value = shareUrl; + this.shareFallback.style.display = 'block'; + // Select the text so user can easily copy + this.shareFallbackInput.focus(); + this.shareFallbackInput.select(); + } } private async handleShareToX(): Promise { @@ -818,6 +832,8 @@ class MotifApp { this.copyLinkBtn.disabled = !(state === 'generated' && this.hasGenerated); this.shareToXBtn.style.display = state === 'generated' ? 'inline-block' : 'none'; this.shareToXBtn.disabled = !(state === 'generated' && this.hasGenerated); + // Hide share fallback when state changes + this.shareFallback.style.display = 'none'; // New search button only after generation if (this.newSearchBtn) {