-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscript.js
158 lines (136 loc) · 6.85 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
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 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // 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 = `<div class="default-text">
<h1>Emoai</h1>
<img src="images/chatbot.jpg" alt="chatbot-img">
<p>I am here to provide you assistance regarding your mental health<br> Your conversation will be displayed here.</p>
</div>`
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 counselorPrompt = `You are a mental health counselor. Ask open ended questions like a therapist. ${userText} Please respond with care, empathy and guidance.`
const requestOptions = {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${API_KEY}`
},
body: JSON.stringify({
model: "text-davinci-003",
prompt:counselorPrompt,
temperature:0.7,
max_tokens:256,
top_p:1,
frequency_penalty:0,
presence_penalty:0
})
}
// 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 = `<div class="chat-content">
<div class="chat-details">
<img src="images/chatbot.jpg" alt="chatbot-img">
<div class="typing-animation">
<div class="typing-dot" style="--delay: 0.2s"></div>
<div class="typing-dot" style="--delay: 0.3s"></div>
<div class="typing-dot" style="--delay: 0.4s"></div>
</div>
</div>
<span onclick="copyResponse(this)" class="material-symbols-rounded">content_copy</span>
</div>`;
// 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 = `<div class="chat-content">
<div class="chat-details">
<img src="images/user.jpg" alt="user-img">
<p>${userText}</p>
</div>
</div>`;
// 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);