From 92d20e1c8799f449e1ed54e6b087113e258b91cf Mon Sep 17 00:00:00 2001 From: mileswa1q22 <115095719+mileswolfallen2@users.noreply.github.com> Date: Sat, 6 Jan 2024 11:59:18 -0600 Subject: [PATCH] Create scriptai.js --- scriptai.js | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 scriptai.js diff --git a/scriptai.js b/scriptai.js new file mode 100644 index 00000000..0c57f49e --- /dev/null +++ b/scriptai.js @@ -0,0 +1,156 @@ + +const chatInput = document.querySelector("#chat-input"); +const sendButton = document.querySelector("#send-btn"); +const chatContainer = document.querySelector(".chat-container"); +const themeButton = document.querySelector("#theme-btn"); +const deleteButton = document.querySelector("#delete-btn"); + +let userText = null; +const API_KEY = "PASTE-YOUR-API-KEY-HERE"; // Paste your API key here + +const loadDataFromLocalstorage = () => { + // Load saved chats and theme from local storage and apply/add on the page + const themeColor = localStorage.getItem("themeColor"); + + document.body.classList.toggle("light-mode", themeColor === "light_mode"); + themeButton.innerText = document.body.classList.contains("light-mode") ? "dark_mode" : "light_mode"; + + const defaultText = `
+

ChatGPT Clone

+

Start a conversation and explore the power of AI.
Your chat history will be displayed here.

+
` + + chatContainer.innerHTML = localStorage.getItem("all-chats") || defaultText; + chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll to bottom of the chat container +} + +const createChatElement = (content, className) => { + // Create new div and apply chat, specified class and set html content of div + const chatDiv = document.createElement("div"); + chatDiv.classList.add("chat", className); + chatDiv.innerHTML = content; + return chatDiv; // Return the created chat div +} + +const getChatResponse = async (incomingChatDiv) => { + const API_URL = "https://api.openai.com/v1/completions"; + const pElement = document.createElement("p"); + + // Define the properties and data for the API request + const requestOptions = { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${API_KEY}` + }, + body: JSON.stringify({ + model: "text-davinci-003", + prompt: userText, + max_tokens: 2048, + temperature: 0.2, + n: 1, + stop: null + }) + } + + // Send POST request to API, get response and set the reponse as paragraph element text + try { + const response = await (await fetch(API_URL, requestOptions)).json(); + pElement.textContent = response.choices[0].text.trim(); + } catch (error) { // Add error class to the paragraph element and set error text + pElement.classList.add("error"); + pElement.textContent = "Oops! Something went wrong while retrieving the response. Please try again."; + } + + // Remove the typing animation, append the paragraph element and save the chats to local storage + incomingChatDiv.querySelector(".typing-animation").remove(); + incomingChatDiv.querySelector(".chat-details").appendChild(pElement); + localStorage.setItem("all-chats", chatContainer.innerHTML); + chatContainer.scrollTo(0, chatContainer.scrollHeight); +} + +const copyResponse = (copyBtn) => { + // Copy the text content of the response to the clipboard + const reponseTextElement = copyBtn.parentElement.querySelector("p"); + navigator.clipboard.writeText(reponseTextElement.textContent); + copyBtn.textContent = "done"; + setTimeout(() => copyBtn.textContent = "content_copy", 1000); +} + +const showTypingAnimation = () => { + // Display the typing animation and call the getChatResponse function + const html = `
+
+ chatbot-img +
+
+
+
+
+
+ content_copy +
`; + // Create an incoming chat div with typing animation and append it to chat container + const incomingChatDiv = createChatElement(html, "incoming"); + chatContainer.appendChild(incomingChatDiv); + chatContainer.scrollTo(0, chatContainer.scrollHeight); + getChatResponse(incomingChatDiv); +} + +const handleOutgoingChat = () => { + userText = chatInput.value.trim(); // Get chatInput value and remove extra spaces + if(!userText) return; // If chatInput is empty return from here + + // Clear the input field and reset its height + chatInput.value = ""; + chatInput.style.height = `${initialInputHeight}px`; + + const html = `
+
+ user-img +

${userText}

+
+
`; + + // Create an outgoing chat div with user's message and append it to chat container + const outgoingChatDiv = createChatElement(html, "outgoing"); + chatContainer.querySelector(".default-text")?.remove(); + chatContainer.appendChild(outgoingChatDiv); + chatContainer.scrollTo(0, chatContainer.scrollHeight); + setTimeout(showTypingAnimation, 500); +} + +deleteButton.addEventListener("click", () => { + // Remove the chats from local storage and call loadDataFromLocalstorage function + if(confirm("Are you sure you want to delete all the chats?")) { + localStorage.removeItem("all-chats"); + loadDataFromLocalstorage(); + } +}); + +themeButton.addEventListener("click", () => { + // Toggle body's class for the theme mode and save the updated theme to the local storage + document.body.classList.toggle("light-mode"); + localStorage.setItem("themeColor", themeButton.innerText); + themeButton.innerText = document.body.classList.contains("light-mode") ? "dark_mode" : "light_mode"; +}); + +const initialInputHeight = chatInput.scrollHeight; + +chatInput.addEventListener("input", () => { + // Adjust the height of the input field dynamically based on its content + chatInput.style.height = `${initialInputHeight}px`; + chatInput.style.height = `${chatInput.scrollHeight}px`; +}); + +chatInput.addEventListener("keydown", (e) => { + // If the Enter key is pressed without Shift and the window width is larger + // than 800 pixels, handle the outgoing chat + if (e.key === "Enter" && !e.shiftKey && window.innerWidth > 800) { + e.preventDefault(); + handleOutgoingChat(); + } +}); + +loadDataFromLocalstorage(); +sendButton.addEventListener("click", handleOutgoingChat);