From 1f7f446c10eb89e0791ac22e928fcd196964f2b2 Mon Sep 17 00:00:00 2001 From: mcull Date: Mon, 29 Sep 2025 19:03:35 -0700 Subject: [PATCH] refactor(invite): simplify share UX and fix copy behavior MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Changes 1. **Removed redundant "Share..." button** - Both buttons were doing the same thing on mobile - Single button is clearer and less confusing 2. **Dynamic button label based on platform** - Mobile: "Share Link" (opens native share sheet) - Desktop: "Copy Join Link" (copies to clipboard) - Button label now matches actual behavior 3. **Fixed share sheet copy behavior** - Previously: Copying from iOS share sheet gave "Here's your invite to [Library]\n[link]" - Now: Only passes `url` to share API (not `text` + `url`) - Result: Copying from share sheet gives clean link only ## Technical Details - Extracted mobile detection to `isMobile` variable for reuse - Button label uses inline conditional based on `navigator.userAgent` - Share API now only passes `{ url: link }` instead of `{ title, text, url }` ## Testing - iOS: Button says "Share Link", opens share sheet, copying gives clean URL - Android: Button says "Share Link", opens share sheet - Desktop: Button says "Copy Join Link", copies to clipboard 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/components/ManageMembersModal.tsx | 80 +++++++-------------------- 1 file changed, 19 insertions(+), 61 deletions(-) diff --git a/src/components/ManageMembersModal.tsx b/src/components/ManageMembersModal.tsx index fecd875..37c563b 100644 --- a/src/components/ManageMembersModal.tsx +++ b/src/components/ManageMembersModal.tsx @@ -711,7 +711,7 @@ export function ManageMembersModal({ setError(null); setSuccess(null); console.log( - '[ManageMembersModal] Copy Join Link clicked' + '[ManageMembersModal] Share/Copy Join Link clicked' ); const res = await fetch( `/api/collections/${collectionId}/invite`, @@ -738,18 +738,22 @@ export function ManageMembersModal({ throw new Error('No link received from server'); } + // Detect if we're on mobile + const isMobile = + typeof navigator !== 'undefined' && + /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); + // On mobile, prefer native share over clipboard (more reliable on iOS) if ( + isMobile && typeof navigator !== 'undefined' && - (navigator as any).share && - /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) + (navigator as any).share ) { console.log( '[ManageMembersModal] using navigator.share on mobile' ); + // Only pass url to avoid "text + url" when copying from share sheet await (navigator as any).share({ - title: `Join ${collectionName} on StuffLibrary`, - text: `Here's your invite to ${collectionName}`, url: link, }); // Don't set success message for share, as the action is self-evident @@ -768,7 +772,10 @@ export function ManageMembersModal({ } } } catch (e) { - console.error('[ManageMembersModal] copy link failed', e); + console.error( + '[ManageMembersModal] share/copy link failed', + e + ); // Only show error if it's not user cancellation of share dialog if ( !(e instanceof Error && e.name === 'AbortError') && @@ -785,61 +792,12 @@ export function ManageMembersModal({ } }} > - {shareLoading ? 'Preparing…' : 'Copy Join Link'} - -