44
55const socket = io ( `http://${ window . location . host } ` ) ;
66
7+ let generateStoryButtonOriginalHTML = '' ; // To store the original content of the generate story button
8+ let storyBuffer = '' ;
9+
710
811
912function initSocketIO ( ) {
10- socket . on ( 'response' , ( data ) => {
11- document . getElementById ( 'story-container' ) . style . display = 'flex' ;
12- const storyResponse = document . getElementById ( 'story-response' ) ;
13- storyResponse . textContent = data ;
14- document . getElementById ( 'loading-spinner' ) . style . display = 'none' ;
15- const clearStoryButton = document . getElementById ( 'clear-story-button' ) ;
16- clearStoryButton . style . display = 'block' ;
17- clearStoryButton . disabled = false ;
13+ socket . on ( 'prompt' , ( data ) => {
14+ const promptContainer = document . getElementById ( 'prompt-container' ) ;
15+ const promptDisplay = document . getElementById ( 'prompt-display' ) ;
16+ promptDisplay . innerHTML = data ;
17+ promptContainer . style . display = 'block' ;
1818 } ) ;
19+
20+ socket . on ( 'response' , ( data ) => {
21+
22+ document . getElementById ( 'story-container' ) . style . display = 'flex' ;
23+
24+ storyBuffer += data ;
25+
26+ } ) ;
27+
28+
29+
30+ socket . on ( 'stream_end' , ( ) => {
31+
32+ const storyResponse = document . getElementById ( 'story-response' ) ;
33+
34+ storyResponse . innerHTML = storyBuffer ;
35+
36+
37+
38+ document . getElementById ( 'loading-spinner' ) . style . display = 'none' ;
39+
40+ const clearStoryButton = document . getElementById ( 'clear-story-button' ) ;
41+
42+ clearStoryButton . style . display = 'block' ;
43+
44+ clearStoryButton . disabled = false ;
45+
46+
47+
48+ const generateStoryButton = document . querySelector ( '.generate-story-button' ) ;
49+
50+ if ( generateStoryButton ) {
51+
52+ generateStoryButton . disabled = false ;
53+
54+ generateStoryButton . innerHTML = generateStoryButtonOriginalHTML ; // Restore original content
55+
56+ }
57+
58+ } ) ;
1959}
2060
2161function unlockAndOpenNext ( currentContainer ) {
@@ -33,6 +73,12 @@ function unlockAndOpenNext(currentContainer) {
3373 }
3474}
3575
76+ function getRandomElement ( elements ) {
77+ if ( elements . length === 0 ) return null ;
78+ const randomIndex = Math . floor ( Math . random ( ) * elements . length ) ;
79+ return elements [ randomIndex ] ;
80+ }
81+
3682function setupChipSelection ( container ) {
3783 const chips = container . querySelectorAll ( '.chip' ) ;
3884 const selectedValue = container . querySelector ( '.selected-value' ) ;
@@ -49,6 +95,13 @@ function setupChipSelection(container) {
4995 if ( ! alreadySelected ) {
5096 unlockAndOpenNext ( container ) ;
5197 }
98+
99+ // Collapse the current container
100+ const content = container . querySelector ( '.parameter-content' ) ;
101+ const arrow = container . querySelector ( '.arrow-icon' ) ;
102+ content . style . display = 'none' ;
103+ arrow . classList . remove ( 'rotated' ) ;
104+
52105 } ) ;
53106 } ) ;
54107}
@@ -129,6 +182,17 @@ function checkCharactersAndUnlockNext(charactersContainer) {
129182}
130183
131184function gatherDataAndGenerateStory ( ) {
185+ document . querySelectorAll ( '.parameter-container' ) . forEach ( container => {
186+ const content = container . querySelector ( '.parameter-content' ) ;
187+ if ( content && content . style . display === 'block' ) {
188+ content . style . display = 'none' ;
189+ const arrow = container . querySelector ( '.arrow-icon' ) ;
190+ if ( arrow ) {
191+ arrow . classList . remove ( 'rotated' ) ;
192+ }
193+ }
194+ } ) ;
195+
132196 const age = document . querySelector ( '.parameter-container:nth-child(1) .chip.selected' ) ?. textContent . trim ( ) || 'any' ;
133197 const theme = document . querySelector ( '.parameter-container:nth-child(2) .chip.selected' ) ?. textContent . trim ( ) || 'any' ;
134198 const storyTypeContainer = document . querySelector ( '.parameter-container:nth-child(3)' ) ;
@@ -168,9 +232,20 @@ function generateStory(data) {
168232 document . querySelector ( '.story-output-placeholder' ) . style . display = 'none' ;
169233 const responseArea = document . getElementById ( 'story-response-area' ) ;
170234 responseArea . style . display = 'flex' ;
235+ document . getElementById ( 'prompt-container' ) . style . display = 'none' ;
236+ document . getElementById ( 'prompt-display' ) . textContent = '' ;
171237 document . getElementById ( 'story-container' ) . style . display = 'none' ;
172- document . getElementById ( 'loading-spinner' ) . style . display = 'block' ;
173- document . getElementById ( 'story-response' ) . textContent = '' ;
238+ document . getElementById ( 'story-response' ) . innerHTML = '' ; // Use innerHTML to clear
239+ storyBuffer = '' ; // Reset buffer
240+ document . getElementById ( 'loading-spinner' ) . style . display = 'block' ; // Show the general loading spinner
241+
242+ const generateStoryButton = document . querySelector ( '.generate-story-button' ) ;
243+ if ( generateStoryButton ) {
244+ generateStoryButton . disabled = true ;
245+ // Append the spinner instead of replacing innerHTML
246+ generateStoryButton . innerHTML += '<div class="button-spinner spinner"></div>' ;
247+ }
248+
174249 document . getElementById ( 'clear-story-button' ) . style . display = 'none' ;
175250 socket . emit ( 'generate_story' , data ) ;
176251}
@@ -223,10 +298,12 @@ function resetStoryView() {
223298 }
224299 }
225300
226- // Hide "Generate story" button
301+ // Restore "Generate story" button to original state
227302 const generateStoryButton = document . querySelector ( '.generate-story-button' ) ;
228303 if ( generateStoryButton ) {
229- generateStoryButton . style . display = 'none' ;
304+ generateStoryButton . style . display = 'none' ; // Keep hidden if no chars, will be set to flex by checkCharactersAndUnlockNext
305+ generateStoryButton . disabled = false ;
306+ generateStoryButton . innerHTML = generateStoryButtonOriginalHTML ;
230307 }
231308
232309 // Reset parameter containers state
@@ -250,6 +327,11 @@ function resetStoryView() {
250327document . addEventListener ( 'DOMContentLoaded' , ( ) => {
251328 initSocketIO ( ) ;
252329
330+ const generateStoryButton = document . querySelector ( '.generate-story-button' ) ;
331+ if ( generateStoryButton ) {
332+ generateStoryButtonOriginalHTML = generateStoryButton . innerHTML ; // Store original content
333+ }
334+
253335 const parameterContainers = document . querySelectorAll ( '.parameter-container' ) ;
254336
255337 parameterContainers . forEach ( ( container , index ) => {
@@ -259,7 +341,9 @@ document.addEventListener('DOMContentLoaded', () => {
259341 content . style . display = 'block' ;
260342 arrow . classList . add ( 'rotated' ) ;
261343 } else {
262- container . classList . add ( 'disabled' ) ;
344+ if ( container . id !== 'prompt-container' ) {
345+ container . classList . add ( 'disabled' ) ;
346+ }
263347 }
264348 } ) ;
265349
@@ -374,4 +458,56 @@ document.addEventListener('DOMContentLoaded', () => {
374458 console . error ( 'Could not copy text: ' , err ) ;
375459 } ) ;
376460 } ) ;
461+
462+ document . getElementById ( 'generate-randomly-button' ) . addEventListener ( 'click' , ( ) => {
463+ // Age
464+ const ageChips = document . querySelectorAll ( '.parameter-container:nth-child(1) .chip' ) ;
465+ const randomAgeChip = getRandomElement ( ageChips ) ;
466+ const age = randomAgeChip ? randomAgeChip . textContent . trim ( ) : 'any' ;
467+
468+ // Theme
469+ const themeChips = document . querySelectorAll ( '.parameter-container:nth-child(2) .chip' ) ;
470+ const randomThemeChip = getRandomElement ( themeChips ) ;
471+ const theme = randomThemeChip ? randomThemeChip . textContent . trim ( ) : 'any' ;
472+
473+ // Story Type
474+ const storyTypeContainer = document . querySelector ( '.parameter-container:nth-child(3)' ) ;
475+
476+ // Tone
477+ const toneChips = storyTypeContainer . querySelectorAll ( '.story-type-paragraph:nth-child(1) .chip' ) ;
478+ const randomToneChip = getRandomElement ( toneChips ) ;
479+ const tone = randomToneChip ? randomToneChip . textContent . trim ( ) : 'any' ;
480+
481+ // Ending type
482+ const endingTypeChips = storyTypeContainer . querySelectorAll ( '.story-type-paragraph:nth-child(2) .chip' ) ;
483+ const randomEndingTypeChip = getRandomElement ( endingTypeChips ) ;
484+ const endingType = randomEndingTypeChip ? randomEndingTypeChip . textContent . trim ( ) : 'any' ;
485+
486+ // Narrative structure
487+ const narrativeStructureChips = storyTypeContainer . querySelectorAll ( '.story-type-paragraph:nth-child(3) .chip' ) ;
488+ const randomNarrativeStructureChip = getRandomElement ( narrativeStructureChips ) ;
489+ const narrativeStructure = randomNarrativeStructureChip ? randomNarrativeStructureChip . textContent . trim ( ) : 'any' ;
490+
491+ // Duration
492+ const durationChips = storyTypeContainer . querySelectorAll ( '.story-type-paragraph:nth-child(4) .chip' ) ;
493+ const randomDurationChip = getRandomElement ( durationChips ) ;
494+ const duration = randomDurationChip ? randomDurationChip . textContent . trim ( ) : 'any' ;
495+
496+ // Characters and Other will be empty for random generation.
497+ const characters = [ ] ;
498+ const other = '' ;
499+
500+ const storyData = {
501+ age,
502+ theme,
503+ tone,
504+ endingType,
505+ narrativeStructure,
506+ duration,
507+ characters,
508+ other,
509+ } ;
510+
511+ generateStory ( storyData ) ;
512+ } ) ;
377513} ) ;
0 commit comments