Code viewer for World: DALL-E "Hello World"
// ==== Hello World =================================================================================================
// This code is designed for use on the Ancient Brain site.
// This code may be freely copied and edited by anyone on the Ancient Brain site.
// To include a working run of this program on another site, see the "Embed code" links provided on Ancient Brain.
// ====================================================================================================================

const style = document.createElement('style');
style.textContent = `
  body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background-color: #edf2f4;
    margin: 0;
    padding: 20px;
  }
  h1 {
    color: #2b2d42;
    text-align: center;
  }
  .input-container, .output-container {
    background-color: #ffffff;
    border: 1px solid #8d99ae;
    padding: 20px;
    border-radius: 10px;
    margin-bottom: 20px;
  }
  input[type="text"], button {
    padding: 10px;
    border-radius: 5px;
    border: 1px solid #8d99ae;
    margin: 10px 0;
  }
  button {
    background-color: #2b2d42;
    color: white;
    cursor: pointer;
  }
  button:hover {
    background-color: #3f51b5;
  }
  #output {
    white-space: pre-wrap; /* Wraps text */
  }
`;
document.head.appendChild(style);

// Inject the HTML structure into the body
document.body.innerHTML = `
  <h1>Generate an Image with DALL·E</h1>
  <div class="input-container api-key-container">
    <h3>Enter API Key</h3>
    <input type="text" id="api-key" placeholder="Enter your API Key...">
    <button id="set-api-key">Set API Key</button>
  </div>
  <div class="input-container">
    <h3>Enter a prompt</h3>
    <input type="text" id="input-prompt" placeholder="Think of anything...">
    <button id="submit-prompt">Submit</button>
  </div>
  <div class="output-container">
    <h3>DALL·E replies</h3>
    <br>
    <div id="output"></div>
  </div>
`;

// Add loading bar CSS to the head
const loadingStyle = document.createElement('style');
loadingStyle.textContent = `
.loading {
  display: none; /* Initially hidden */
  justify-content: flex-start; /* Align to the left */
  align-items: center;
  margin-top: 20px;
  padding-left: 20px; /* Padding on the left */
}

.loading div {
  width: 1rem;
  height: 1rem;
  margin: 0 0.3rem;
  background-color: #979fd0; /* Bluebell color */
  border-radius: 50%;
  animation: bounce 0.9s infinite alternate;
}

.loading div:nth-child(2) {
  animation-delay: 0.3s;
}

.loading div:nth-child(3) {
  animation-delay: 0.6s;
}

@keyframes bounce {
  to {
    opacity: 0.3;
    transform: translate3d(0, -1rem, 0);
  }
}
`;
document.head.appendChild(loadingStyle);

// Add loading bar HTML to the output div
const outputDiv = document.querySelector("#output"); // Get the output div
const loadingBar = document.createElement('div');
loadingBar.className = 'loading';
loadingBar.innerHTML = '<div></div><div></div><div></div>';
outputDiv.appendChild(loadingBar); // Append to the output div

let apiKey = ''; // Variable to store the API key

function setApiKey() {
  apiKey = document.querySelector("#api-key").value.trim();
  if (apiKey) {
    console.log("API Key set:", apiKey); // Log the API key for debugging
    alert("API Key set successfully.");
    document.querySelector(".api-key-container").style.display = 'none';
  } else {
    alert("Please enter an API key.");
  }
}

function showLoading() {
  loadingBar.style.display = 'flex'; // Show loading bar
}

function hideLoading() {
  loadingBar.style.display = 'none'; // Hide loading bar
}

function generateImage(prompt) {
  showLoading(); // Show loading bar when starting image generation

  // Configuration for the API request
  const data = {
    model: "dall-e-3",
    prompt: prompt,
    n: 1,
    size: "1024x1024"
  };

  console.log("Request data:", data); // Log the request data

  // Making the API request
  fetch('https://api.openai.com/v1/images/generations', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${apiKey}`
    },
    body: JSON.stringify(data)
  })
  .then(response => {
    console.log("Response received:", response); // Log the response object
    if (!response.ok) {
      console.error('Network response was not ok:', response); // Log error details
      throw new Error('Network response was not ok: ' + response.statusText);
    }
    return response.json();
  })
  .then(data => {
    console.log("Data:", data); // Log the data received
    if (data && data.data && data.data.length > 0) {
      const imageUrl = data.data[0].url;
      outputDiv.innerHTML = `<img src="${imageUrl}" alt="Generated Image" />`;
    } else {
      outputDiv.textContent = "No image generated.";
    }
    hideLoading(); // Hide loading bar on success
  })
  .catch(error => {
    console.error('Error while generating image:', error); // Log the error
    outputDiv.textContent = "Error while generating image: " + error.message;
    hideLoading(); // Hide loading bar on error
  });
}

// Event listeners
document.addEventListener('DOMContentLoaded', function () {
  document.querySelector("#set-api-key").addEventListener('click', setApiKey);
  document.querySelector("#submit-prompt").addEventListener('click', function() {
    const prompt = document.querySelector("#input-prompt").value.trim();
    if (prompt && apiKey) {
      generateImage(prompt);
      document.querySelector("#input-prompt").value = '';
    } else {
      alert("Please enter a prompt and set the API key.");
    }
  });
});