chansung commited on
Commit
0179e8c
·
verified ·
1 Parent(s): 37b43e8

Update script.js

Browse files
Files changed (1) hide show
  1. script.js +101 -8
script.js CHANGED
@@ -54,6 +54,11 @@ let modalThinkingBudgetSliderEl, modalThinkingBudgetValueDisplayEl;
54
  let promptDisplayModalOverlayEl, promptDisplayModalContentEl, fullPromptTextEl, promptDisplayModalCloseBtnEl;
55
  let showPromptModalButtonEl; // Added for the new button
56
 
 
 
 
 
 
57
 
58
  // --- Constants ---
59
  const API_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta/models/';
@@ -282,7 +287,20 @@ async function generateVariations() {
282
  return;
283
  }
284
 
285
- const apiKey = apiKeyEl.value.trim();
 
 
 
 
 
 
 
 
 
 
 
 
 
286
  const selectedModel = modelSelEl.value;
287
  const currentIsRefinementMode = modalRefinementCheckboxEl.checked;
288
  const currentNumVariations = parseInt(numVariationsSliderEl.value, 10);
@@ -290,7 +308,11 @@ async function generateVariations() {
290
 
291
  if (!apiKey || !userPrompt) {
292
  errorMessageEl.textContent = 'Error: API Key and Prompt (via Alt+P) are required.';
293
- if (!userPrompt && !promptModalOverlayEl.classList.contains('visible')) showPromptModal();
 
 
 
 
294
  return;
295
  }
296
  if (!selectedModel) {
@@ -320,6 +342,10 @@ async function generateVariations() {
320
  console.log(`Refining Evolution ${activeTimelineIndex + 1}. Original context: "${contextPromptForRefinement}"`);
321
  } else if (currentIsRefinementMode) {
322
  errorMessageEl.textContent = 'Error: No active evolution selected to refine. Uncheck "refine" or select an evolution from history.';
 
 
 
 
323
  return;
324
  }
325
 
@@ -339,6 +365,20 @@ async function generateVariations() {
339
  fullscreenButtons = Array(numVariationsToGenerate).fill(null);
340
  previewItems = Array(numVariationsToGenerate).fill(null);
341
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
342
 
343
  showFourGridPreviewUI();
344
 
@@ -501,6 +541,20 @@ function showSingleLargePreviewUI(htmlContent, titleText, fullPromptText) {
501
  previewGridWrapperEl.className = 'single-mode';
502
  if(perspectiveViewportEl) perspectiveViewportEl.style.perspective = 'none';
503
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
504
  const item = document.createElement('div');
505
  item.className = 'single-preview-item';
506
 
@@ -533,18 +587,52 @@ function showSingleLargePreviewUI(htmlContent, titleText, fullPromptText) {
533
  }
534
 
535
  function showInitialPreviewStateUI() {
536
- previewGridWrapperEl.innerHTML = '<div class="col-span-2 row-span-2 flex items-center justify-center text-slate-500 text-lg"><p>Press Alt+O, then Alt+P to begin.</p></div>';
537
- previewGridWrapperEl.className = 'grid-mode';
538
- if(perspectiveViewportEl) perspectiveViewportEl.style.perspective = '1500px';
539
- updateMainContentTitles("Live Previews", "Powered by Gemini Models");
 
 
 
 
 
 
 
 
 
 
540
  if (codeOutputEl) codeOutputEl.innerHTML = '<code class="language-html">// Select a variation or history item to view its code.</code>';
541
  if (selectedCodeTitleH3El) selectedCodeTitleH3El.textContent = "Selected Code:";
542
  selectedVariationGridIndex = -1;
543
- // Reset subtitle state when going back to initial view
544
  if (mainContentSubtitleH2El) {
545
  mainContentSubtitleH2El.classList.remove('prompt-truncated');
546
  delete mainContentSubtitleH2El.dataset.fullPrompt;
547
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
548
  }
549
 
550
  function updateMainContentTitles(title, subtitle) {
@@ -1196,10 +1284,15 @@ document.addEventListener('DOMContentLoaded', () => {
1196
  promptDisplayModalCloseBtnEl = document.getElementById('prompt-display-modal-close-button');
1197
  showPromptModalButtonEl = document.getElementById('show-prompt-modal-button'); // Added
1198
 
 
 
 
 
 
1199
 
1200
  // --- Check if all required elements exist ---
1201
  let missingElements = [];
1202
- const requiredElements = { apiKeyEl, modelSelEl, codeOutputEl, errorMessageEl, refinementLoadingIndicator, mainContentEl, configButtonEl, intervalSliderEl, intervalValueDisplayEl, fullscreenOverlayEl, fullscreenIframeEl, exitFullscreenBtnEl, perspectiveViewportEl, previewGridWrapperEl, historyPanelEl, historyPanelPlaceholderEl, selectedCodeTitleH3El, mainContentTitleH1El, mainContentSubtitleH2El, fullscreenHistoryNavEl, historyNavPrevBtnEl, historyNavNextBtnEl, promptModalOverlayEl, promptModalContentEl, modalUserPromptEl, modalGenerateBtnEl, modalCancelBtnEl, modalLoadingIndicatorEl, modalRefinementCheckboxEl, numVariationsSliderEl, numVariationsValueDisplayEl, configModalOverlayEl, configModalContentEl, configModalCloseBtnEl, copyCodeButtonEl, exportCodeButtonEl, historyToggleButtonEl, historyArrowDownEl, historyArrowUpEl, newButtonEl, confirmModalOverlayEl, confirmModalMessageEl, confirmModalConfirmBtnEl, confirmModalCancelBtnEl, historyNavLeftBtnEl, historyNavRightBtnEl, modalThinkingBudgetSliderEl, modalThinkingBudgetValueDisplayEl, promptDisplayModalOverlayEl, promptDisplayModalContentEl, fullPromptTextEl, promptDisplayModalCloseBtnEl, showPromptModalButtonEl }; // Added showPromptModalButtonEl
1203
  for (const key in requiredElements) { if (!requiredElements[key]) { missingElements.push(key); } }
1204
 
1205
  if (missingElements.length > 0) {
 
54
  let promptDisplayModalOverlayEl, promptDisplayModalContentEl, fullPromptTextEl, promptDisplayModalCloseBtnEl;
55
  let showPromptModalButtonEl; // Added for the new button
56
 
57
+ // --- Elements for Initial Setup CTA ---
58
+ let initialSetupCtaEl;
59
+ let initialApiKeyInputEl;
60
+ let examplePromptsContainerEl;
61
+
62
 
63
  // --- Constants ---
64
  const API_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta/models/';
 
287
  return;
288
  }
289
 
290
+ // Read API key: Prefer config modal, then initial input, then localStorage
291
+ let apiKey = apiKeyEl.value.trim();
292
+ if (!apiKey && initialApiKeyInputEl) {
293
+ apiKey = initialApiKeyInputEl.value.trim();
294
+ }
295
+ if (!apiKey) {
296
+ apiKey = localStorage.getItem('geminiApiKey') || '';
297
+ }
298
+
299
+ // Update input fields with the resolved API key
300
+ if (apiKeyEl && apiKeyEl.value !== apiKey) apiKeyEl.value = apiKey;
301
+ if (initialApiKeyInputEl && initialApiKeyInputEl.value !== apiKey) initialApiKeyInputEl.value = apiKey;
302
+
303
+
304
  const selectedModel = modelSelEl.value;
305
  const currentIsRefinementMode = modalRefinementCheckboxEl.checked;
306
  const currentNumVariations = parseInt(numVariationsSliderEl.value, 10);
 
308
 
309
  if (!apiKey || !userPrompt) {
310
  errorMessageEl.textContent = 'Error: API Key and Prompt (via Alt+P) are required.';
311
+ if (!apiKey && initialSetupCtaEl && initialSetupCtaEl.classList.contains('flex')) {
312
+ if(initialApiKeyInputEl) initialApiKeyInputEl.focus();
313
+ } else if (!userPrompt && !promptModalOverlayEl.classList.contains('visible')) {
314
+ showPromptModal();
315
+ }
316
  return;
317
  }
318
  if (!selectedModel) {
 
342
  console.log(`Refining Evolution ${activeTimelineIndex + 1}. Original context: "${contextPromptForRefinement}"`);
343
  } else if (currentIsRefinementMode) {
344
  errorMessageEl.textContent = 'Error: No active evolution selected to refine. Uncheck "refine" or select an evolution from history.';
345
+ // Also hide the initial CTA if it's somehow visible
346
+ if (initialSetupCtaEl) initialSetupCtaEl.classList.add('hidden');
347
+ if (initialSetupCtaEl) initialSetupCtaEl.classList.remove('flex');
348
+ if (previewGridWrapperEl) previewGridWrapperEl.classList.remove('hidden');
349
  return;
350
  }
351
 
 
365
  fullscreenButtons = Array(numVariationsToGenerate).fill(null);
366
  previewItems = Array(numVariationsToGenerate).fill(null);
367
 
368
+ // Ensure correct layout state for generation
369
+ if (initialSetupCtaEl) {
370
+ initialSetupCtaEl.classList.remove('active-cta'); // Start hide animation
371
+ // Hide example prompt buttons immediately or animate them out too
372
+ if (examplePromptsContainerEl) {
373
+ examplePromptsContainerEl.querySelectorAll('.example-prompt-button').forEach(btn => btn.classList.remove('visible'));
374
+ }
375
+ setTimeout(() => { // Wait for animation to roughly finish
376
+ initialSetupCtaEl.style.display = 'none';
377
+ initialSetupCtaEl.classList.remove('flex', 'flex-grow');
378
+ }, 500); // Corresponds to CSS transition duration
379
+ }
380
+ if (perspectiveViewportEl) perspectiveViewportEl.classList.remove('hidden');
381
+ // previewGridWrapperEl will be managed by showFourGridPreviewUI
382
 
383
  showFourGridPreviewUI();
384
 
 
541
  previewGridWrapperEl.className = 'single-mode';
542
  if(perspectiveViewportEl) perspectiveViewportEl.style.perspective = 'none';
543
 
544
+ // Ensure correct layout state for single preview
545
+ if (initialSetupCtaEl) {
546
+ initialSetupCtaEl.classList.remove('active-cta');
547
+ if (examplePromptsContainerEl) {
548
+ examplePromptsContainerEl.querySelectorAll('.example-prompt-button').forEach(btn => btn.classList.remove('visible'));
549
+ }
550
+ setTimeout(() => {
551
+ initialSetupCtaEl.style.display = 'none';
552
+ initialSetupCtaEl.classList.remove('flex', 'flex-grow');
553
+ }, 500);
554
+ }
555
+ if (perspectiveViewportEl) perspectiveViewportEl.classList.remove('hidden');
556
+ if (previewGridWrapperEl) previewGridWrapperEl.classList.remove('hidden');
557
+
558
  const item = document.createElement('div');
559
  item.className = 'single-preview-item';
560
 
 
587
  }
588
 
589
  function showInitialPreviewStateUI() {
590
+ // Hide the main preview grid and show the initial CTA
591
+ if (previewGridWrapperEl) previewGridWrapperEl.classList.add('hidden');
592
+ if (perspectiveViewportEl) perspectiveViewportEl.classList.add('hidden'); // Hide the whole viewport
593
+
594
+ if (initialSetupCtaEl) {
595
+ initialSetupCtaEl.style.display = 'flex'; // Set display before animation
596
+ initialSetupCtaEl.classList.add('flex-grow');
597
+ // Use requestAnimationFrame to ensure display:flex is applied before adding class for transition
598
+ requestAnimationFrame(() => {
599
+ initialSetupCtaEl.classList.add('active-cta');
600
+ });
601
+ }
602
+
603
+ updateMainContentTitles("Welcome to Live Previews", "Set up your API Key or try an example below.");
604
  if (codeOutputEl) codeOutputEl.innerHTML = '<code class="language-html">// Select a variation or history item to view its code.</code>';
605
  if (selectedCodeTitleH3El) selectedCodeTitleH3El.textContent = "Selected Code:";
606
  selectedVariationGridIndex = -1;
 
607
  if (mainContentSubtitleH2El) {
608
  mainContentSubtitleH2El.classList.remove('prompt-truncated');
609
  delete mainContentSubtitleH2El.dataset.fullPrompt;
610
  }
611
+
612
+ // Populate example prompts
613
+ if (examplePromptsContainerEl) {
614
+ examplePromptsContainerEl.innerHTML = ''; // Clear existing
615
+ const prompts = [
616
+ "A simple landing page for a new SaaS product.",
617
+ "A responsive image gallery with a lightbox.",
618
+ "A futuristic login form.",
619
+ "A personal portfolio website with a blog section."
620
+ ];
621
+ prompts.forEach((promptText, index) => {
622
+ const button = document.createElement('button');
623
+ button.className = 'example-prompt-button';
624
+ button.textContent = promptText;
625
+ button.addEventListener('click', () => {
626
+ if (modalUserPromptEl) modalUserPromptEl.value = promptText;
627
+ showPromptModal();
628
+ });
629
+ examplePromptsContainerEl.appendChild(button);
630
+ // Staggered animation for buttons
631
+ setTimeout(() => {
632
+ button.classList.add('visible');
633
+ }, 300 + index * 120); // Delay after panel animation starts, then stagger
634
+ });
635
+ }
636
  }
637
 
638
  function updateMainContentTitles(title, subtitle) {
 
1284
  promptDisplayModalCloseBtnEl = document.getElementById('prompt-display-modal-close-button');
1285
  showPromptModalButtonEl = document.getElementById('show-prompt-modal-button'); // Added
1286
 
1287
+ // --- Elements for Initial Setup CTA ---
1288
+ initialSetupCtaEl = document.getElementById('initial-setup-cta');
1289
+ initialApiKeyInputEl = document.getElementById('initial-api-key-input');
1290
+ examplePromptsContainerEl = document.getElementById('example-prompts-container');
1291
+
1292
 
1293
  // --- Check if all required elements exist ---
1294
  let missingElements = [];
1295
+ const requiredElements = { apiKeyEl, modelSelEl, codeOutputEl, errorMessageEl, refinementLoadingIndicator, mainContentEl, configButtonEl, intervalSliderEl, intervalValueDisplayEl, fullscreenOverlayEl, fullscreenIframeEl, exitFullscreenBtnEl, perspectiveViewportEl, previewGridWrapperEl, historyPanelEl, historyPanelPlaceholderEl, selectedCodeTitleH3El, mainContentTitleH1El, mainContentSubtitleH2El, fullscreenHistoryNavEl, historyNavPrevBtnEl, historyNavNextBtnEl, promptModalOverlayEl, promptModalContentEl, modalUserPromptEl, modalGenerateBtnEl, modalCancelBtnEl, modalLoadingIndicatorEl, modalRefinementCheckboxEl, numVariationsSliderEl, numVariationsValueDisplayEl, configModalOverlayEl, configModalContentEl, configModalCloseBtnEl, copyCodeButtonEl, exportCodeButtonEl, historyToggleButtonEl, historyArrowDownEl, historyArrowUpEl, newButtonEl, confirmModalOverlayEl, confirmModalMessageEl, confirmModalConfirmBtnEl, confirmModalCancelBtnEl, historyNavLeftBtnEl, historyNavRightBtnEl, modalThinkingBudgetSliderEl, modalThinkingBudgetValueDisplayEl, promptDisplayModalOverlayEl, promptDisplayModalContentEl, fullPromptTextEl, promptDisplayModalCloseBtnEl, showPromptModalButtonEl, initialSetupCtaEl, initialApiKeyInputEl, examplePromptsContainerEl }; // Added showPromptModalButtonEl
1296
  for (const key in requiredElements) { if (!requiredElements[key]) { missingElements.push(key); } }
1297
 
1298
  if (missingElements.length > 0) {