1
+ import React , { useState } from 'react' ;
2
+ import clsx from 'clsx' ;
3
+ import styles from './styles.module.css' ;
4
+
5
+ export default function DocActionsDropdown ( ) {
6
+ const [ isOpen , setIsOpen ] = useState ( false ) ;
7
+
8
+ const buildRawUrl = ( path , isIndex ) => {
9
+ if ( isIndex ) {
10
+ // For index files, use path/index.md
11
+ return `https://raw.githubusercontent.com/onflow/docs/main/docs/${ path } /index.md` ;
12
+ } else {
13
+ // For regular files, use path.md
14
+ return `https://raw.githubusercontent.com/onflow/docs/main/docs/${ path } .md` ;
15
+ }
16
+ } ;
17
+
18
+ const fetchMarkdown = async ( path ) => {
19
+ // First, try to determine if this is an index.md file by checking both paths
20
+ const directPath = `https://raw.githubusercontent.com/onflow/docs/main/docs/${ path } .md` ;
21
+ const indexPath = `https://raw.githubusercontent.com/onflow/docs/main/docs/${ path } /index.md` ;
22
+
23
+ try {
24
+ // Try the index path first
25
+ const indexResponse = await fetch ( indexPath ) ;
26
+ if ( indexResponse . ok ) {
27
+ return { url : indexPath , text : await indexResponse . text ( ) } ;
28
+ }
29
+
30
+ // If index path fails, try the direct path
31
+ const directResponse = await fetch ( directPath ) ;
32
+ if ( directResponse . ok ) {
33
+ return { url : directPath , text : await directResponse . text ( ) } ;
34
+ }
35
+
36
+ // If both fail, return null
37
+ return null ;
38
+ } catch ( error ) {
39
+ console . error ( 'Error fetching markdown:' , error ) ;
40
+ return null ;
41
+ }
42
+ } ;
43
+
44
+ const handleCopyMarkdown = async ( ) => {
45
+ try {
46
+ const path = window . location . pathname . replace ( / ^ \/ d o c s \/ ? / , '' ) . replace ( / \/ $ / , '' ) ;
47
+ const result = await fetchMarkdown ( path ) ;
48
+
49
+ if ( result ) {
50
+ navigator . clipboard . writeText ( result . text ) ;
51
+ setIsOpen ( false ) ;
52
+ } else {
53
+ throw new Error ( 'Could not fetch markdown' ) ;
54
+ }
55
+ } catch ( error ) {
56
+ console . error ( 'Error copying markdown:' , error ) ;
57
+ // Fallback to GitHub
58
+ const currentPath = window . location . pathname . replace ( / ^ \/ d o c s \/ ? / , '' ) ;
59
+ window . open ( `https://github.com/onflow/docs/tree/main/docs/${ currentPath } ` , '_blank' ) ;
60
+ }
61
+ } ;
62
+
63
+ const handleViewMarkdown = async ( ) => {
64
+ try {
65
+ const path = window . location . pathname . replace ( / ^ \/ d o c s \/ ? / , '' ) . replace ( / \/ $ / , '' ) ;
66
+ const result = await fetchMarkdown ( path ) ;
67
+
68
+ if ( result ) {
69
+ window . open ( result . url , '_blank' ) ;
70
+ setIsOpen ( false ) ;
71
+ } else {
72
+ // Fallback to GitHub
73
+ const currentPath = window . location . pathname . replace ( / ^ \/ d o c s \/ ? / , '' ) ;
74
+ window . open ( `https://github.com/onflow/docs/tree/main/docs/${ currentPath } ` , '_blank' ) ;
75
+ }
76
+ } catch ( error ) {
77
+ console . error ( 'Error viewing markdown:' , error ) ;
78
+ // Fallback to GitHub
79
+ const currentPath = window . location . pathname . replace ( / ^ \/ d o c s \/ ? / , '' ) ;
80
+ window . open ( `https://github.com/onflow/docs/tree/main/docs/${ currentPath } ` , '_blank' ) ;
81
+ }
82
+ } ;
83
+
84
+ const handleOpenInChatGPT = async ( ) => {
85
+ try {
86
+ const path = window . location . pathname . replace ( / ^ \/ d o c s \/ ? / , '' ) . replace ( / \/ $ / , '' ) ;
87
+ const result = await fetchMarkdown ( path ) ;
88
+
89
+ if ( result ) {
90
+ const prompt = `Analyze this documentation: ${ result . url } . After reading, ask me what I'd like to know. Keep responses focused on the content.` ;
91
+ const encodedPrompt = encodeURIComponent ( prompt ) ;
92
+ window . open ( `https://chatgpt.com/?q=${ encodedPrompt } ` , '_blank' ) ;
93
+ } else {
94
+ // Fallback to current URL
95
+ const currentUrl = window . location . href ;
96
+ const prompt = `Analyze this documentation: ${ currentUrl } . After reading, ask me what I'd like to know. Keep responses focused on the content.` ;
97
+ const encodedPrompt = encodeURIComponent ( prompt ) ;
98
+ window . open ( `https://chatgpt.com/?q=${ encodedPrompt } ` , '_blank' ) ;
99
+ }
100
+ setIsOpen ( false ) ;
101
+ } catch ( error ) {
102
+ console . error ( 'Error opening in ChatGPT:' , error ) ;
103
+ // Fallback to current URL
104
+ const currentUrl = window . location . href ;
105
+ const prompt = `Analyze this documentation: ${ currentUrl } . After reading, ask me what I'd like to know. Keep responses focused on the content.` ;
106
+ const encodedPrompt = encodeURIComponent ( prompt ) ;
107
+ window . open ( `https://chatgpt.com/?q=${ encodedPrompt } ` , '_blank' ) ;
108
+ setIsOpen ( false ) ;
109
+ }
110
+ } ;
111
+
112
+ const handleOpenInClaude = async ( ) => {
113
+ try {
114
+ const path = window . location . pathname . replace ( / ^ \/ d o c s \/ ? / , '' ) . replace ( / \/ $ / , '' ) ;
115
+ const result = await fetchMarkdown ( path ) ;
116
+
117
+ if ( result ) {
118
+ const prompt = `Review this documentation: ${ result . url } . Once complete, ask me what questions I have. Stay focused on the provided content.` ;
119
+ const encodedPrompt = encodeURIComponent ( prompt ) ;
120
+ window . open ( `https://claude.ai/chat/new?prompt=${ encodedPrompt } ` , '_blank' ) ;
121
+ } else {
122
+ // Fallback to current URL
123
+ const currentUrl = window . location . href ;
124
+ const prompt = `Review this documentation: ${ currentUrl } . Once complete, ask me what questions I have. Stay focused on the provided content.` ;
125
+ const encodedPrompt = encodeURIComponent ( prompt ) ;
126
+ window . open ( `https://claude.ai/chat/new?prompt=${ encodedPrompt } ` , '_blank' ) ;
127
+ }
128
+ setIsOpen ( false ) ;
129
+ } catch ( error ) {
130
+ console . error ( 'Error opening in Claude:' , error ) ;
131
+ // Fallback to current URL
132
+ const currentUrl = window . location . href ;
133
+ const prompt = `Review this documentation: ${ currentUrl } . Once complete, ask me what questions I have. Stay focused on the provided content.` ;
134
+ const encodedPrompt = encodeURIComponent ( prompt ) ;
135
+ window . open ( `https://claude.ai/chat/new?prompt=${ encodedPrompt } ` , '_blank' ) ;
136
+ setIsOpen ( false ) ;
137
+ }
138
+ } ;
139
+
140
+ const handleOpenFlowKnowledge = ( ) => {
141
+ window . open ( 'https://github.com/onflow/Flow-Data-Sources/tree/main/merged_docs' , '_blank' ) ;
142
+ setIsOpen ( false ) ;
143
+ } ;
144
+
145
+ const handleArrowClick = ( e ) => {
146
+ e . stopPropagation ( ) ;
147
+ setIsOpen ( ! isOpen ) ;
148
+ } ;
149
+
150
+ return (
151
+ < div className = { styles . dropdownContainer } >
152
+ < button
153
+ className = { styles . dropdownButton }
154
+ onClick = { handleOpenInChatGPT }
155
+ >
156
+ Open in ChatGPT
157
+ < span className = { styles . arrow } onClick = { handleArrowClick } />
158
+ </ button >
159
+ { isOpen && (
160
+ < div className = { styles . dropdownMenu } >
161
+ < button onClick = { handleOpenInClaude } className = { styles . menuItem } >
162
+ Open in Claude
163
+ </ button >
164
+ < div className = { styles . divider } />
165
+ < button onClick = { handleCopyMarkdown } className = { styles . menuItem } >
166
+ Copy as Markdown
167
+ </ button >
168
+ < button onClick = { handleViewMarkdown } className = { styles . menuItem } >
169
+ View Source Markdown
170
+ </ button >
171
+ < div className = { styles . divider } />
172
+ < button onClick = { handleOpenFlowKnowledge } className = { styles . menuItem } >
173
+ Full Flow Knowledge Source
174
+ </ button >
175
+ </ div >
176
+ ) }
177
+ </ div >
178
+ ) ;
179
+ }
0 commit comments