From e47380f2b4040c4a7a69cc4e9a7661dadd962e99 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 6 Aug 2025 20:35:34 +0000 Subject: [PATCH 01/13] Improve docs copy functionality: move from header to content area with enhanced 'Ask AI' button - Remove CopyPageDropdown from header layout in app/(docs)/layout.tsx - Add enhanced CopyPageDropdown to content area in app/(docs)/[[...slug]]/page.tsx - Update CopyPageDropdown component to support enhanced styling with 'Ask AI' button - Replace simple copy icon with prominent cyan button featuring MessageSquare icon - Maintain all existing functionality (ChatGPT, Claude, markdown export) - Position button after title/description for maximum visibility Co-Authored-By: jhaynie@agentuity.com --- app/(docs)/[[...slug]]/page.tsx | 4 ++++ app/(docs)/layout.tsx | 2 -- components/CopyPageDropdown.tsx | 28 +++++++++++++++++++++------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/app/(docs)/[[...slug]]/page.tsx b/app/(docs)/[[...slug]]/page.tsx index 96d717cf..6adf2861 100644 --- a/app/(docs)/[[...slug]]/page.tsx +++ b/app/(docs)/[[...slug]]/page.tsx @@ -18,6 +18,7 @@ import { import { notFound } from "next/navigation"; import { CommunityButton } from "../../../components/Community"; import { NavButton } from "../../../components/NavButton"; +import CopyPageDropdown from "../../../components/CopyPageDropdown"; export default async function Page(props: { params: Promise<{ slug?: string[] }>; @@ -42,6 +43,9 @@ export default async function Page(props: { > {page.data.title} {page.data.description} +
+ +
- ), }, diff --git a/components/CopyPageDropdown.tsx b/components/CopyPageDropdown.tsx index d140bec9..f90c701a 100644 --- a/components/CopyPageDropdown.tsx +++ b/components/CopyPageDropdown.tsx @@ -12,7 +12,11 @@ interface PageContent { path: string; } -export default function CopyPageDropdown() { +interface CopyPageDropdownProps { + enhanced?: boolean; +} + +export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownProps) { const [isOpen, setIsOpen] = useState(false); const [isLoading, setIsLoading] = useState(false); const pathname = usePathname(); @@ -87,12 +91,22 @@ export default function CopyPageDropdown() { return ( - + {enhanced ? ( + + ) : ( + + )} Date: Wed, 6 Aug 2025 21:02:49 +0000 Subject: [PATCH 02/13] Update copy button to match Turso example: move to header with 'Copy page' text - Move CopyPageDropdown back to header area (top-right corner) - Change button text from 'Ask AI' to 'Copy page' to match Turso approach - Use subtle styling appropriate for header layout - Maintain all existing dropdown functionality (ChatGPT, Claude, markdown export) Co-Authored-By: jhaynie@agentuity.com --- app/(docs)/[[...slug]]/page.tsx | 3 --- app/(docs)/layout.tsx | 2 ++ components/CopyPageDropdown.tsx | 8 ++++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app/(docs)/[[...slug]]/page.tsx b/app/(docs)/[[...slug]]/page.tsx index 6adf2861..bb13d853 100644 --- a/app/(docs)/[[...slug]]/page.tsx +++ b/app/(docs)/[[...slug]]/page.tsx @@ -43,9 +43,6 @@ export default async function Page(props: { > {page.data.title} {page.data.description} -
- -
+ ), }, diff --git a/components/CopyPageDropdown.tsx b/components/CopyPageDropdown.tsx index f90c701a..ab939044 100644 --- a/components/CopyPageDropdown.tsx +++ b/components/CopyPageDropdown.tsx @@ -93,11 +93,11 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP {enhanced ? ( ) : ( ) : ( From dafd78f283a9d935178fe765d67304be49b5be3c Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 6 Aug 2025 21:34:57 +0000 Subject: [PATCH 04/13] Implement segmented button with localStorage persistence and proper AI service icons - Convert CopyPageDropdown to segmented button design - Add localStorage persistence for user's preferred AI service selection - Create custom OpenAI and Claude SVG icon components - Left side executes stored preference, right side shows dropdown - User's last selection becomes sticky default across sessions - All existing functionality (ChatGPT, Claude, markdown export) preserved Co-Authored-By: jhaynie@agentuity.com --- components/CopyPageDropdown.tsx | 167 +++++++++++++++++++++++--------- components/icons/ClaudeIcon.tsx | 24 +++++ components/icons/OpenAIIcon.tsx | 23 +++++ 3 files changed, 167 insertions(+), 47 deletions(-) create mode 100644 components/icons/ClaudeIcon.tsx create mode 100644 components/icons/OpenAIIcon.tsx diff --git a/components/CopyPageDropdown.tsx b/components/CopyPageDropdown.tsx index c87cf5ab..bdc103bc 100644 --- a/components/CopyPageDropdown.tsx +++ b/components/CopyPageDropdown.tsx @@ -1,9 +1,11 @@ 'use client'; -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { usePathname } from 'next/navigation'; -import { Copy, ExternalLink, FileText, MessageSquare } from 'lucide-react'; +import { Copy, FileText, ChevronDown } from 'lucide-react'; import * as Popover from '@radix-ui/react-popover'; +import { OpenAIIcon } from './icons/OpenAIIcon'; +import { ClaudeIcon } from './icons/ClaudeIcon'; interface PageContent { content: string; @@ -12,15 +14,47 @@ interface PageContent { path: string; } +type ActionType = 'copy-markdown' | 'view-markdown' | 'open-chatgpt' | 'open-claude'; + +interface ActionConfig { + id: ActionType; + label: string; + icon: React.ComponentType<{ className?: string }>; + handler: () => Promise; +} + interface CopyPageDropdownProps { enhanced?: boolean; } +const STORAGE_KEY = 'agentuity-copy-preference'; + export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownProps) { const [isOpen, setIsOpen] = useState(false); const [isLoading, setIsLoading] = useState(false); + const [preferredAction, setPreferredAction] = useState('copy-markdown'); const pathname = usePathname(); + useEffect(() => { + try { + const stored = localStorage.getItem(STORAGE_KEY); + if (stored && ['copy-markdown', 'view-markdown', 'open-chatgpt', 'open-claude'].includes(stored)) { + setPreferredAction(stored as ActionType); + } + } catch (error) { + console.error('Failed to load copy preference:', error); + } + }, []); + + const savePreference = (action: ActionType) => { + try { + localStorage.setItem(STORAGE_KEY, action); + setPreferredAction(action); + } catch (error) { + console.error('Failed to save copy preference:', error); + } + }; + const formatMarkdownForLLM = (content: PageContent): string => { return `# ${content.title}\n\n${content.description ? `${content.description}\n\n` : ''}${content.content}`; }; @@ -88,24 +122,79 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP setIsOpen(false); }; + const actionConfigs: ActionConfig[] = [ + { + id: 'copy-markdown', + label: 'Copy as Markdown', + icon: Copy, + handler: handleCopyMarkdown + }, + { + id: 'view-markdown', + label: 'View as Markdown', + icon: FileText, + handler: handleViewMarkdown + }, + { + id: 'open-chatgpt', + label: 'Open in ChatGPT', + icon: OpenAIIcon, + handler: handleOpenInChatGPT + }, + { + id: 'open-claude', + label: 'Open in Claude', + icon: ClaudeIcon, + handler: handleOpenInClaude + } + ]; + + const primaryAction = actionConfigs.find(action => action.id === preferredAction) || actionConfigs[0]; + + const handlePrimaryAction = async () => { + await primaryAction.handler(); + }; + + const handleActionSelect = async (actionId: ActionType) => { + savePreference(actionId); + const action = actionConfigs.find(a => a.id === actionId); + if (action) { + await action.handler(); + } + }; + return ( {enhanced ? ( - +
+ + + + +
) : ( - + + + )}
- - - - + {actionConfigs.map((action) => ( + + ))}
diff --git a/components/icons/ClaudeIcon.tsx b/components/icons/ClaudeIcon.tsx new file mode 100644 index 00000000..df7ec53a --- /dev/null +++ b/components/icons/ClaudeIcon.tsx @@ -0,0 +1,24 @@ +import React from "react"; + +interface ClaudeIconProps { + className?: string; + size?: number; +} + +export function ClaudeIcon({ className = "w-5 h-5", size }: ClaudeIconProps) { + return ( + + Claude + + + + ); +} diff --git a/components/icons/OpenAIIcon.tsx b/components/icons/OpenAIIcon.tsx new file mode 100644 index 00000000..c1d02458 --- /dev/null +++ b/components/icons/OpenAIIcon.tsx @@ -0,0 +1,23 @@ +import React from "react"; + +interface OpenAIIconProps { + className?: string; + size?: number; +} + +export function OpenAIIcon({ className = "w-5 h-5", size }: OpenAIIconProps) { + return ( + + OpenAI + + + ); +} From 8b04943c65bc356ed9c1a9d23b1a2a433a911fc7 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 6 Aug 2025 22:25:24 +0000 Subject: [PATCH 05/13] Update Claude icon with official Simple Icons SVG and fix flash by hiding selector until localStorage loads - Replace ClaudeIcon.tsx with official Claude SVG from Simple Icons - Add isInitialized state to prevent flash by hiding component until localStorage is read - Maintain all existing segmented button functionality and localStorage persistence - Test confirmed: no flash, proper Claude icon display, localStorage working correctly Co-Authored-By: jhaynie@agentuity.com --- components/CopyPageDropdown.tsx | 7 +++++++ components/icons/ClaudeIcon.tsx | 3 +-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/components/CopyPageDropdown.tsx b/components/CopyPageDropdown.tsx index bdc103bc..27f8f708 100644 --- a/components/CopyPageDropdown.tsx +++ b/components/CopyPageDropdown.tsx @@ -33,6 +33,7 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP const [isOpen, setIsOpen] = useState(false); const [isLoading, setIsLoading] = useState(false); const [preferredAction, setPreferredAction] = useState('copy-markdown'); + const [isInitialized, setIsInitialized] = useState(false); const pathname = usePathname(); useEffect(() => { @@ -43,6 +44,8 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP } } catch (error) { console.error('Failed to load copy preference:', error); + } finally { + setIsInitialized(true); } }, []); @@ -163,6 +166,10 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP } }; + if (!isInitialized) { + return null; + } + return ( diff --git a/components/icons/ClaudeIcon.tsx b/components/icons/ClaudeIcon.tsx index df7ec53a..513cbe8d 100644 --- a/components/icons/ClaudeIcon.tsx +++ b/components/icons/ClaudeIcon.tsx @@ -17,8 +17,7 @@ export function ClaudeIcon({ className = "w-5 h-5", size }: ClaudeIconProps) { aria-label="Claude" > Claude - - + ); } From 17b5f5951dd03a867fce0cfe5413008c1dcdcaed Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 6 Aug 2025 23:26:36 +0000 Subject: [PATCH 06/13] Fix mobile functionality for copy page button - Add mobile-specific clipboard API fallbacks using document.execCommand - Improve popup handling with fallbacks for blocked window.open calls - Enhance touch targets with 44px minimum height for mobile accessibility - Add touch-manipulation CSS for better mobile responsiveness - Prevent auto-focus on dropdown open to avoid mobile keyboard issues - Add download fallbacks for View as Markdown on mobile browsers Fixes mobile functionality issues while preserving all desktop functionality and localStorage persistence. Co-Authored-By: jhaynie@agentuity.com --- components/CopyPageDropdown.tsx | 82 +++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 8 deletions(-) diff --git a/components/CopyPageDropdown.tsx b/components/CopyPageDropdown.tsx index 27f8f708..15a4ad12 100644 --- a/components/CopyPageDropdown.tsx +++ b/components/CopyPageDropdown.tsx @@ -86,9 +86,36 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP const markdownForLLM = formatMarkdownForLLM(content); try { - await navigator.clipboard.writeText(markdownForLLM); + if (navigator.clipboard && navigator.clipboard.writeText) { + await navigator.clipboard.writeText(markdownForLLM); + } else { + const textArea = document.createElement('textarea'); + textArea.value = markdownForLLM; + textArea.style.position = 'fixed'; + textArea.style.left = '-999999px'; + textArea.style.top = '-999999px'; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + document.execCommand('copy'); + document.body.removeChild(textArea); + } } catch (error) { console.error('Failed to copy to clipboard:', error); + const textArea = document.createElement('textarea'); + textArea.value = markdownForLLM; + textArea.style.position = 'fixed'; + textArea.style.left = '-999999px'; + textArea.style.top = '-999999px'; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + try { + document.execCommand('copy'); + } catch (fallbackError) { + console.error('Fallback copy also failed:', fallbackError); + } + document.body.removeChild(textArea); } setIsOpen(false); }; @@ -100,8 +127,28 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP const markdownForLLM = formatMarkdownForLLM(content); const blob = new Blob([markdownForLLM], { type: 'text/markdown' }); const url = URL.createObjectURL(blob); - window.open(url, '_blank'); - setTimeout(() => URL.revokeObjectURL(url), 100); + + try { + const newWindow = window.open(url, '_blank'); + if (!newWindow) { + const link = document.createElement('a'); + link.href = url; + link.download = `${content.title.replace(/[^a-z0-9]/gi, '_').toLowerCase()}.md`; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } + } catch (error) { + console.error('Failed to open markdown view:', error); + const link = document.createElement('a'); + link.href = url; + link.download = `${content.title.replace(/[^a-z0-9]/gi, '_').toLowerCase()}.md`; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } + + setTimeout(() => URL.revokeObjectURL(url), 1000); setIsOpen(false); }; @@ -111,7 +158,16 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP const markdownForLLM = formatMarkdownForLLM(content); const chatGPTUrl = `https://chatgpt.com/?q=${encodeURIComponent(`Please help me understand this documentation:\n\n${markdownForLLM}`)}`; - window.open(chatGPTUrl, '_blank'); + + try { + const newWindow = window.open(chatGPTUrl, '_blank'); + if (!newWindow) { + window.location.href = chatGPTUrl; + } + } catch (error) { + console.error('Failed to open ChatGPT:', error); + window.location.href = chatGPTUrl; + } setIsOpen(false); }; @@ -121,7 +177,16 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP const markdownForLLM = formatMarkdownForLLM(content); const claudeUrl = `https://claude.ai/new?q=${encodeURIComponent(`Please help me understand this documentation:\n\n${markdownForLLM}`)}`; - window.open(claudeUrl, '_blank'); + + try { + const newWindow = window.open(claudeUrl, '_blank'); + if (!newWindow) { + window.location.href = claudeUrl; + } + } catch (error) { + console.error('Failed to open Claude:', error); + window.location.href = claudeUrl; + } setIsOpen(false); }; @@ -179,7 +244,7 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP onClick={handlePrimaryAction} disabled={isLoading} aria-label={`${primaryAction.label} (primary action)`} - className="inline-flex items-center gap-1.5 px-2.5 py-1.5 text-sm font-medium text-gray-600 dark:text-gray-400 bg-gray-50 dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-200 disabled:opacity-50" + className="inline-flex items-center gap-1.5 px-3 py-2 text-sm font-medium text-gray-600 dark:text-gray-400 bg-gray-50 dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-200 disabled:opacity-50 min-h-[44px] touch-manipulation" > {primaryAction.label} @@ -187,7 +252,7 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP @@ -208,6 +273,7 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP className="w-64 p-2 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-md shadow-lg z-50" align="end" sideOffset={8} + onOpenAutoFocus={(e) => e.preventDefault()} >
{actionConfigs.map((action) => ( @@ -215,7 +281,7 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP key={action.id} onClick={() => handleActionSelect(action.id)} disabled={isLoading} - className={`flex items-center gap-2 w-full p-2 text-sm hover:bg-gray-100 dark:hover:bg-gray-700 rounded text-left disabled:opacity-50 ${ + className={`flex items-center gap-2 w-full p-3 text-sm hover:bg-gray-100 dark:hover:bg-gray-700 rounded text-left disabled:opacity-50 min-h-[44px] touch-manipulation ${ action.id === preferredAction ? 'bg-gray-100 dark:bg-gray-700' : '' }`} > From a3f823933f5bcda0641aed4de1de26f780badca4 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 6 Aug 2025 23:34:49 +0000 Subject: [PATCH 07/13] Fix mobile layout: prevent copy button from squashing title - Change layout from inline flex to responsive stacking on mobile - Use flex-col on small screens, flex-row on sm+ screens - Add proper gap spacing for both mobile and desktop - Resolves title squashing issue on small mobile devices - Maintains all existing functionality and localStorage persistence Co-Authored-By: jhaynie@agentuity.com --- app/(docs)/[[...slug]]/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/(docs)/[[...slug]]/page.tsx b/app/(docs)/[[...slug]]/page.tsx index 624f0160..868409cb 100644 --- a/app/(docs)/[[...slug]]/page.tsx +++ b/app/(docs)/[[...slug]]/page.tsx @@ -41,7 +41,7 @@ export default async function Page(props: { path: `content/${page.file.path}`, }} > -
+
{page.data.title}
From 46aaf28e76c8080c5aae46948de19d92040fd769 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 6 Aug 2025 23:43:23 +0000 Subject: [PATCH 08/13] Fix segmented button border styling on mobile - Add proper border-radius classes (rounded-l-md, rounded-r-md) to button parts - Add border-r to left button to create seamless connection - Remove redundant border-l from right button - Ensures segmented button appears as single cohesive unit - Fixes visual gaps/misalignment shown in iOS screenshot - Maintains all existing functionality and mobile positioning Co-Authored-By: jhaynie@agentuity.com --- components/CopyPageDropdown.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/CopyPageDropdown.tsx b/components/CopyPageDropdown.tsx index 15a4ad12..25b3ea03 100644 --- a/components/CopyPageDropdown.tsx +++ b/components/CopyPageDropdown.tsx @@ -239,12 +239,12 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP {enhanced ? ( -
+
From 598da44efb38c7ce0737b201371786f61f507753 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 7 Aug 2025 00:04:17 +0000 Subject: [PATCH 09/13] Fix segmented button width on mobile - Wrap CopyPageDropdown in flex container to prevent full-width stretching - Button now only takes width needed for content instead of full screen width - Maintains proper mobile positioning with title stacked above button - Preserves all existing functionality and responsive design - Fixes issue where border stretched horizontally across entire screen Co-Authored-By: jhaynie@agentuity.com --- app/(docs)/[[...slug]]/page.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/(docs)/[[...slug]]/page.tsx b/app/(docs)/[[...slug]]/page.tsx index 868409cb..34825e0f 100644 --- a/app/(docs)/[[...slug]]/page.tsx +++ b/app/(docs)/[[...slug]]/page.tsx @@ -43,7 +43,9 @@ export default async function Page(props: { >
{page.data.title} - +
+ +
{page.data.description} From e79efb215525d5f349016eaaf4d0f59316814e3c Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 7 Aug 2025 00:12:59 +0000 Subject: [PATCH 10/13] Hide copy button on mobile using responsive breakpoints - Add 'hidden sm:flex' classes to hide button on mobile devices - Button only shows on small screens and larger (sm breakpoint and up) - Fixes mobile click functionality issues by removing button entirely on mobile - Preserves all desktop functionality and positioning - Responsive design ensures button appears only where it works properly Co-Authored-By: jhaynie@agentuity.com --- app/(docs)/[[...slug]]/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/(docs)/[[...slug]]/page.tsx b/app/(docs)/[[...slug]]/page.tsx index 34825e0f..1231e1a5 100644 --- a/app/(docs)/[[...slug]]/page.tsx +++ b/app/(docs)/[[...slug]]/page.tsx @@ -43,7 +43,7 @@ export default async function Page(props: { >
{page.data.title} -
+
From da133c4e0a92c46f9d66f80bffeaf7c5c258e2a8 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 7 Aug 2025 00:28:37 +0000 Subject: [PATCH 11/13] Reduce padding on segmented button for more compact appearance - Reduce left button padding from px-3 py-2 to px-2 py-1.5 - Reduce dropdown button padding from px-2 py-2 to px-1.5 py-1.5 - Reduce dropdown menu options padding from p-3 to px-2 py-2 - Remove min-h-[44px] constraints for more compact sizing - Maintain readability and accessibility while achieving compact design - All functionality and responsive behavior preserved Co-Authored-By: jhaynie@agentuity.com --- components/CopyPageDropdown.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/CopyPageDropdown.tsx b/components/CopyPageDropdown.tsx index 25b3ea03..7c359b8d 100644 --- a/components/CopyPageDropdown.tsx +++ b/components/CopyPageDropdown.tsx @@ -244,7 +244,7 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP onClick={handlePrimaryAction} disabled={isLoading} aria-label={`${primaryAction.label} (primary action)`} - className="inline-flex items-center gap-1.5 px-3 py-2 text-sm font-medium text-gray-600 dark:text-gray-400 bg-gray-50 dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-200 disabled:opacity-50 min-h-[44px] touch-manipulation rounded-l-md border-r border-gray-200 dark:border-gray-700" + className="inline-flex items-center gap-1.5 px-2 py-1.5 text-sm font-medium text-gray-600 dark:text-gray-400 bg-gray-50 dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-200 disabled:opacity-50 touch-manipulation rounded-l-md border-r border-gray-200 dark:border-gray-700" > {primaryAction.label} @@ -252,7 +252,7 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP @@ -281,7 +281,7 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP key={action.id} onClick={() => handleActionSelect(action.id)} disabled={isLoading} - className={`flex items-center gap-2 w-full p-3 text-sm hover:bg-gray-100 dark:hover:bg-gray-700 rounded text-left disabled:opacity-50 min-h-[44px] touch-manipulation ${ + className={`flex items-center gap-2 w-full px-2 py-2 text-sm hover:bg-gray-100 dark:hover:bg-gray-700 rounded text-left disabled:opacity-50 ${ action.id === preferredAction ? 'bg-gray-100 dark:bg-gray-700' : '' }`} > From 52b2810ffa92e9e7a3db29a3abd9999bce3d8452 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 7 Aug 2025 00:37:13 +0000 Subject: [PATCH 12/13] Fix segmented button dropdown trigger behavior - Remove outer Popover.Trigger wrapper to prevent left button from opening dropdown - Keep only right caret button wrapped in Popover.Trigger for dropdown functionality - Left button now only executes primary action without showing dropdown - Right caret button properly opens/closes dropdown menu - Maintains all existing functionality and responsive behavior - Resolves issue where clicking left side caused dropdown to flash/show Co-Authored-By: jhaynie@agentuity.com --- components/CopyPageDropdown.tsx | 52 ++++++++++++++++----------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/components/CopyPageDropdown.tsx b/components/CopyPageDropdown.tsx index 7c359b8d..cd50670a 100644 --- a/components/CopyPageDropdown.tsx +++ b/components/CopyPageDropdown.tsx @@ -237,38 +237,36 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP return ( - - {enhanced ? ( -
- - - - -
- ) : ( + {enhanced ? ( +
+ - )} - +
+ ) : ( + + + + )} Date: Thu, 7 Aug 2025 14:19:06 +0000 Subject: [PATCH 13/13] Update ChatGPT and Claude URLs to reference docs page instead of sending content directly - Update handleOpenInChatGPT to use new URL pattern with hints=search&prompt - Update handleOpenInClaude to use new URL pattern with q parameter - Both functions now construct current page URL and reference it instead of sending markdown content - Maintains all existing functionality and localStorage persistence Co-Authored-By: jhaynie@agentuity.com --- components/CopyPageDropdown.tsx | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/components/CopyPageDropdown.tsx b/components/CopyPageDropdown.tsx index cd50670a..d4b0fbe1 100644 --- a/components/CopyPageDropdown.tsx +++ b/components/CopyPageDropdown.tsx @@ -153,11 +153,8 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP }; const handleOpenInChatGPT = async () => { - const content = await fetchPageContent(); - if (!content) return; - - const markdownForLLM = formatMarkdownForLLM(content); - const chatGPTUrl = `https://chatgpt.com/?q=${encodeURIComponent(`Please help me understand this documentation:\n\n${markdownForLLM}`)}`; + const currentUrl = `${window.location.origin}${pathname}`; + const chatGPTUrl = `https://chatgpt.com/?hints=search&prompt=${encodeURIComponent(`Read from ${currentUrl} so I can ask questions about it`)}`; try { const newWindow = window.open(chatGPTUrl, '_blank'); @@ -172,11 +169,8 @@ export default function CopyPageDropdown({ enhanced = false }: CopyPageDropdownP }; const handleOpenInClaude = async () => { - const content = await fetchPageContent(); - if (!content) return; - - const markdownForLLM = formatMarkdownForLLM(content); - const claudeUrl = `https://claude.ai/new?q=${encodeURIComponent(`Please help me understand this documentation:\n\n${markdownForLLM}`)}`; + const currentUrl = `${window.location.origin}${pathname}`; + const claudeUrl = `https://claude.ai/new?q=${encodeURIComponent(`Read from ${currentUrl} so I can ask questions about it`)}`; try { const newWindow = window.open(claudeUrl, '_blank');