@@ -99,8 +99,13 @@ <h1 class="text-2xl font-bold text-white">Astral Drafter</h1>
9999 < circle class ="opacity-25 " cx ="12 " cy ="12 " r ="10 " stroke ="currentColor " stroke-width ="4 "> </ circle >
100100 < path class ="opacity-75 " fill ="currentColor " d ="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z "> </ path >
101101 </ svg >
102- < span > Generate & Save Prose</ span >
102+ < span > Generate Prose</ span >
103103 </ button >
104+
105+ < button id ="save-button " class ="mt-2 w-full bg-green-600 text-white font-bold py-3 px-4 rounded-md hover:bg-green-700 disabled:bg-green-800 disabled:cursor-not-allowed transition " disabled >
106+ < span > Save to File</ span >
107+ </ button >
108+
104109 < div id ="error-message " class ="mt-3 text-center text-red-400 text-sm "> </ div >
105110 </ div >
106111 </ div >
@@ -128,6 +133,7 @@ <h1 class="text-2xl font-bold text-white">Astral Drafter</h1>
128133 < script >
129134 // --- Element Selectors ---
130135const generateButton = document . getElementById ( 'generate-button' ) ;
136+ const saveButton = document . getElementById ( 'save-button' ) ;
131137const newSceneButton = document . getElementById ( 'new-scene-button' ) ;
132138const spinner = document . getElementById ( 'spinner' ) ;
133139const prevSceneInput = document . getElementById ( 'prev-scene-summary' ) ;
@@ -161,6 +167,7 @@ <h1 class="text-2xl font-bold text-white">Astral Drafter</h1>
161167outlineInput . addEventListener ( 'input' , updateContextUsage ) ;
162168characterInput . addEventListener ( 'input' , updateContextUsage ) ;
163169generateButton . addEventListener ( 'click' , generateProse ) ;
170+ saveButton . addEventListener ( 'click' , saveProseToFile ) ;
164171newSceneButton . addEventListener ( 'click' , resetInterface ) ;
165172sendButton . addEventListener ( 'click' , sendChatMessage ) ;
166173chatInput . addEventListener ( 'keypress' , ( e ) => {
@@ -180,9 +187,10 @@ <h1 class="text-2xl font-bold text-white">Astral Drafter</h1>
180187 conversationHistory = [ ] ;
181188 currentOutputPath = '' ;
182189 lastGeneratedContent = '' ;
183- chatInput . value = '' ;
190+ chatInput . value = true ;
184191 chatInput . disabled = true ;
185192 sendButton . disabled = true ;
193+ saveButton . disabled = true ;
186194 updateContextUsage ( ) ;
187195}
188196
@@ -211,6 +219,47 @@ <h1 class="text-2xl font-bold text-white">Astral Drafter</h1>
211219 }
212220}
213221
222+ async function saveProseToFile ( ) {
223+ if ( ! lastGeneratedContent || ! currentOutputPath ) {
224+ errorMessage . textContent = "No content to save or output path is missing." ;
225+ return ;
226+ }
227+
228+ saveButton . disabled = true ;
229+ errorMessage . textContent = '' ;
230+
231+ try {
232+ const response = await fetch ( MCP_SERVER_URL , {
233+ method : 'POST' ,
234+ headers : { 'Content-Type' : 'application/json' } ,
235+ body : JSON . stringify ( {
236+ save_content : lastGeneratedContent ,
237+ output_path : currentOutputPath
238+ } )
239+ } ) ;
240+
241+ if ( ! response . ok ) {
242+ const errorData = await response . json ( ) ;
243+ throw new Error ( errorData . error || `Save request failed: ${ response . status } ` ) ;
244+ }
245+
246+ const result = await response . json ( ) ;
247+ // You can add a success message here if you want
248+ console . log ( result . message ) ;
249+ // Maybe flash the button green or show a small confirmation message
250+ const originalText = saveButton . textContent ;
251+ saveButton . textContent = 'Saved!' ;
252+ setTimeout ( ( ) => { saveButton . textContent = originalText ; } , 2000 ) ;
253+
254+
255+ } catch ( error ) {
256+ console . error ( "Error saving file:" , error ) ;
257+ errorMessage . textContent = `Error saving file: ${ error . message } ` ;
258+ } finally {
259+ saveButton . disabled = false ;
260+ }
261+ }
262+
214263async function generateProse ( ) {
215264 const prevScene = prevSceneInput . value . trim ( ) ;
216265 const outline = outlineInput . value . trim ( ) ;
@@ -268,6 +317,7 @@ <h1 class="text-2xl font-bold text-white">Astral Drafter</h1>
268317 generateButton . disabled = true ;
269318 sendButton . disabled = true ;
270319 chatInput . disabled = true ;
320+ saveButton . disabled = true ;
271321 spinner . classList . remove ( 'hidden' ) ;
272322
273323 const aiResponseContainer = addAiMessageContainer ( ) ;
@@ -280,7 +330,6 @@ <h1 class="text-2xl font-bold text-white">Astral Drafter</h1>
280330 body : JSON . stringify ( {
281331 conversation_history : conversationHistory ,
282332 stream : true ,
283- output_path : currentOutputPath
284333 } )
285334 } ) ;
286335
@@ -318,8 +367,8 @@ <h1 class="text-2xl font-bold text-white">Astral Drafter</h1>
318367 } ) ;
319368
320369 addCopyToClipboardButton ( aiResponseContainer , fullResponse ) ;
321- addSaveConfirmation ( aiResponseContainer , currentOutputPath ) ;
322-
370+ saveButton . disabled = false ;
371+
323372 } catch ( error ) {
324373 console . error ( "Error querying Bridge server:" , error ) ;
325374 aiResponseContent . innerText = `Error connecting to Bridge server. Make sure it's running at ${ MCP_SERVER_URL } .\n\nDetails: ${ error . message } ` ;
@@ -409,7 +458,9 @@ <h1 class="text-2xl font-bold text-white">Astral Drafter</h1>
409458 container . appendChild ( confirmation ) ;
410459}
411460
412- resetInterface ( ) ;
461+ function resetInterface ( ) {
462+ saveButton . disabled = true ;
463+ } ;
413464 </ script >
414465</ body >
415466</ html >
0 commit comments