LEGACY CODE FOR ASSIGNMENT-SOLVER
THE HTML CODE
<!DOCTYPE html>
<!-- Coding By CodingNepal - www.codingnepalweb.com -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>Assignment-Solver</title>
<!-- Linking Google Fonts For Icons -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?
family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@24,400,0,0" />
<link rel="stylesheet" href="firebase-2-style.css">
<script type="module" src="firebase-homepage.js"></script>
</head>
<body>
<div class="container">
<div id="sidebar" class="sidebar">
<div id="mySidenav" class="sidenav">
<div class="sidebar-content">
<div class="topBarAction">
<i class="fa-solid fa-bars"></i>
</div>
<button id="new-conversation-btn">
<span class="icon-plus">+</span>
<span class="tooltiptext">New Chat</span>
</button>
<div class="user-info">
<div class="avatar" id="avatarCircle"></div>
<div class="user-name">
<div><span id="loggedUserFName"></span></div>
<div><span id="loggedUserLName"></span></div>
<div><span id="loggedUserEmail"></span></div>
<div><span id="loggedUserPhoneNumber"></span></div>
<button id="logout">Logout</button>
</div>
</div>
<div class="conversation-list">
<div class="conversation">
<p class="conversation-text">
Recent Conversation:
</p>
<p class="conversation-content">
<!-- Display recent conversation here -->
</p>
</div>
<div class="conversation">
<p class="conversation-text">
Last Conversation:
</p>
<p class="conversation-content">
<!-- Display last conversation here -->
</p>
</div>
</div>
</div>
<a href="javascript:void(0)" class="closebtn"
onclick="closeNav()">×</a>
</div>
<span style="font-size:30px;cursor:pointer; color:#a546f8;"
onclick="openNav()">☰ </span>
</div>
<!-- Premium Version Ribbon -->
<div class="premium-ribbon">
<p>Starter Plan</p>
</div>
<!-- chat space -->
<div id="main-content" class="main-content">
<header class="header">
<!-- Header Greetings -->
<h1 class="title">Hello, I am Assignment-Solver </h1>
<p class="subtitle">How can I help you today?</p>
<!-- Suggestion list -->
<ul class="suggestion-list">
<li class="suggestion">
<h4 class="text">Can you explain this my assignments for me
step by step.</h4>
<span class="icon material-symbols-rounded">draw</span>
</li>
<li class="suggestion">
<h4 class="text">What are the best tips to improve my grade
in school?</h4>
<span class="icon material-symbols-
rounded">lightbulb</span>
</li>
<li class="suggestion">
<h4 class="text">Create a personalized study plan for me?
</h4>
<span class="icon material-symbols-rounded">explore</span>
</li>
<li class="suggestion">
<h4 class="text">Help me write an essay on any topic.</h4>
<span class="icon material-symbols-rounded">code</span>
</li>
</ul>
</header>
<!-- Chat List / Container -->
<div class="chat-list"></div>
<!-- Like Modal -->
<div id="likeModal" class="modal">
<div class="modal-content">
<span class="close-button">×</span>
<p id="likeModalMessage"></p>
<button id="submitLike">OK</button>
</div>
</div>
<!-- Dislike Modal -->
<div id="dislikeModal" class="modal">
<div class="modal-content">
<span class="close-button">×</span>
<p id="dislikeModalMessage"></p>
<button id="submitDislike">OK</button>
</div>
</div>
<!-- Review Modal -->
<div id="customModal" class="modal">
<div class="modal-content">
<span class="close-button">×</span>
<p id="modalMessage"></p>
<textarea id="reviewInput" style="width: 100%; height: 200%;
padding: 10px;"></textarea>
<button id="submitReview">Submit Review</button>
</div>
</div>
<!-- Premium Subscription Modal -->
<div id="premiumModal" class="modal">
<div class="modal-content" style="border-radius: 5px; padding:
15px;">
<span class="close-button">×</span>
<p>Subscribe to the premium version to enjoy full
functionality!</p>
<button id="subscribeButton" style="border-radius: 10px;
padding: 5px;">Subscribe Now</button>
</div>
</div>
<!-- Typing Area -->
<div class="typing-area">
<form action="#" class="typing-form">
<div class="input-wrapper">
<textarea placeholder="Enter your question here..."
class="typing-input" required></textarea>
</div>
<button id="send-message-button" class="icon material-
symbols-rounded">send</button>
<div class="action-buttons">
<span id="theme-toggle-button" class="icon material-
symbols-rounded">light_mode</span>
<span id="delete-chat-button" class="icon material-symbols-
rounded">delete</span>
<label for="file-upload" class="icon material-symbols-
rounded">upload_file</label>
<input type="file" id="file-upload" style="display:none;"
accept="image/*,application/pdf,.doc,.docx,.txt,video/*,audio/*"
multiple>
</div>
</form>
</div>
<p class="disclaimer-text">
Assignment-Solver may display inaccurate info, including about
people, so double-check its responses.
</p>
</div>
</div>
<script src="firebase_2-script.js"></script>
</body>
</html>
THE CSS CODE
/* Import Google Font - Poppins */
@import url('https://fonts.googleapis.com/css2?
family=Poppins:wght@400;500;600&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Arial", "Verdana";
font-size: 15px; /* Set the default font size to 15px */
}
:root {
/* Dark mode colors */
--text-color: #E3E3E3;
--subheading-color: #828282;
--placeholder-color: #A6A6A6;
--primary-color: #242424;
--secondary-color: #383838;
--secondary-hover-color: #8F12FD;
--sidebar-color: #383838; /* Define sidebar color for dark mode */
--conversation-hover-color: #9fccf7;
}
.light_mode {
/* Light mode colors */
--text-color: #000000;
--subheading-color: #8F12FD;
--placeholder-color: #000000;
--primary-color: #edd9ff;
--secondary-color: #8653b3;
--secondary-hover-color: #4294E3;
--sidebar-color: #d6aafc; /* Define sidebar color for light mode */
--conversation-hover-color: #9fccf7;
}
body {
background: var(--primary-color);
font-family: "Lato", sans-serif;
display: flex;
flex-direction: column;
height: auto; /* Allow the body to grow with content */
overflow-y: auto; /* Allow vertical scrolling */
}
.header, .chat-list .message {
margin: 0 auto;
max-width: 100%;
}
.header {
margin-top: 0%;
padding: 0rem;
width: 100%;
}
body.hide-header .header {
margin: 0;
display: none;
}
.header :where(.title, .subtitle) {
color: var(--text-color);
font-weight: 200;
line-height: 1.5; /* Adjust line height for better spacing */
margin: 0.5rem 0; /* Add margin for better spacing */
}
.header .title {
width: fit-content;
font-size: 2.5rem; /* Adjust font size for better responsiveness */
background-clip: text;
background: linear-gradient(to right, #4294E3, #8F12FD);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.header .subtitle {
font-size: 1.2rem; /* Adjust font size for better responsiveness */
color: var(--subheading-color);
}
.suggestion-list {
width: 100%;
list-style: none;
display: flex;
flex-wrap: wrap; /* Allow items to wrap to the next line */
gap: 1.25rem;
margin-top: 3vh;
scroll-snap-type: x mandatory;
scrollbar-width: none;
justify-content: center; /* Center align items */
}
.suggestion-list .suggestion {
cursor: pointer;
padding: 1.25rem;
width: calc(100% / 3 - 2.5rem); /* Adjust width for three items per
row */
flex-shrink: 0;
display: flex;
flex-direction: column;
align-items: flex-end;
border-radius: 0.75rem;
justify-content: space-between;
background: var(--secondary-color);
transition: 0.2s ease;
box-sizing: border-box; /* Include padding and border in the
element's total width and height */
}
.suggestion-list .suggestion:hover {
background: var(--secondary-hover-color);
}
.suggestion-list .suggestion :where(.text, .icon) {
font-weight: 400;
color: var(--text-color);
}
.suggestion-list .suggestion .icon {
width: 42px;
height: 38px;
display: flex;
font-size: 1.3rem;
margin-top: 1rem;
align-self: flex-end;
align-items: center;
border-radius: 50%;
justify-content: center;
color: var(--text-color);
background: var(--primary-color);
}
/* Media queries for responsiveness */
@media (max-width: 768px) {
.suggestion-list .suggestion {
width: calc(100% / 2 - 2.5rem); /* Adjust width for two items per
row */
}
}
@media (max-width: 480px) {
.suggestion-list .suggestion {
width: calc(100% - 2.5rem); /* Adjust width for one item per row */
}
}
.chat-list {
padding: 2rem 1rem 20px; /* Adjust the bottom padding to 20px */
max-height: calc(80vh - 80px); /* Adjust the max height */
overflow-y: auto;
scrollbar-color: #8F12FD transparent;
flex-grow: 1;
margin-left: 20px;
border-radius: 20px;
}
.chat-list .message.incoming {
margin-top: 1.5rem;
}
.chat-list .message .message-content {
display: flex;
gap: 1.5rem;
width: 100%;
align-items: center;
border-radius: 10px;
padding: 10px;
background-color: var(--sidebar-color); /* Use the sidebar color
variable */
color: var(--text-color);
}
.chat-list .message .text {
color: var(--text-color);
white-space: pre-wrap;
}
.chat-list .message.error .text {
color: var(--primary-color);
}
.chat-list .message.loading .text {
display: none;
}
.chat-list .message .avatar {
width: 40px;
height: 40px;
object-fit: cover;
border-radius: 50%;
align-self: flex-start;
}
.chat-list .message.loading .avatar {
animation: rotate 3s linear infinite;
}
@keyframes rotate {
100% {
transform: rotate(360deg);
}
}
.chat-list .message .icon {
color: var(--text-color);
cursor: pointer;
height: 35px;
width: 35px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background: none;
font-size: 1.25rem;
margin-left: 3.5rem;
visibility: hidden;
}
.chat-list .message .icon.hide {
visibility: hidden;
}
.chat-list .message:not(.loading, .error):hover .icon:not(.hide) {
visibility: visible;
}
.chat-list .message .icon:hover {
background: var(--secondary-hover-color);
}
.chat-list .message .loading-indicator {
display: none;
gap: 0.8rem;
width: 100%;
flex-direction: column;
}
.chat-list .message.loading .loading-indicator {
display: flex;
}
.chat-list .message .loading-indicator .loading-bar {
height: 8px;
width: 80%;
border-radius: 0.135rem;
background-position: -800px 0;
background: linear-gradient(to right, #4294E3, var(--primary-color),
#8F12FD);
animation: loading 4s linear infinite;
}
.chat-list .message .loading-indicator .loading-bar:last-child {
width: 60%;
}
@keyframes loading {
0% {
background-position: -800px 0;
}
100% {
background-position: 800px 0;
}
}
.typing-area {
position: relative;
width: 100%;
left: 0;
bottom: 0;
padding: 1rem; /* Adjust the padding to reduce the gap */
margin-bottom: 6px; /* Ensure the input form is always visible */
display: flex;
justify-content: center; /* Center the typing area */
}
.disclaimer-text {
text-align: center;
font-size: 0.85rem;
margin-top: 0rem;
color: var(--placeholder-color);
padding-top: 20px;
}
/* Responsive media query code for small screen */
@media (max-width: 768px) {
.header :where(.title, .subtitle) {
font-size: 1.6rem;
line-height: 1.7rem;
}
.header .title {
font-size: 2rem;
}
.header .subtitle {
font-size: 1rem;
}
.typing-area .icon {
height: 50px;
width: 50px;
}
.typing-area .disclaimer-text {
font-size: 0.75rem;
margin-top: 0.5rem;
}
.suggestion-list .suggestion {
width: calc(100% / 2 - 2.5rem); /* Adjust width for two items per
row */
}
}
@media (max-width: 480px) {
.header .title {
font-size: 1.5rem; /* Adjust font size for very small screens */
}
.header .subtitle {
font-size: 0.875rem; /* Adjust font size for very small screens */
}
.suggestion-list .suggestion {
width: calc(100% - 2.5rem); /* Adjust width for one item per row */
}
}
/* Add this to your existing CSS */
.main-content {
transition: margin-left 0.3s ease;
flex-grow: 1;
display: flex;
flex-direction: column;
margin-left: 50px;
}
.main-content.sidebar-open {
margin-left: 350px; /* Adjust the value based on your sidebar width
*/
}
.sidenav.open {
width: 300px; /* Adjust the value based on your sidebar width */
padding: 1px;
}
/* Sidebar navigation bar */
.sidenav {
height: 100%;
width: 0; /* Collapse the sidebar initially */
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: var(--sidebar-color); /* Use the sidebar color
variable */
overflow-x: hidden; /* Prevent the sidebar from scrolling */
transition: 0.5s;
padding-top: 80px;
color: var(--text-color);
}
.sidenav a {
padding: 0px 0px 0px 0px;
text-decoration: none;
font-size: 25px;
display: block;
transition: 0.3s;
color: black;
}
.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
color: var(--text-color);
transition: background 0.3s ease;
padding-top: 20px;
.sidenav .closebtn:hover {
color: var(--secondary-hover-color);
}
@media screen and (max-height: 450px) {
.sidenav {padding-top: 15px;}
.sidenav a {font-size: 12px;}
}
/* New conversation icon */
.icon-plus {
font-size: 28px;
border-radius: 20%; /* For circular shape */
background: linear-gradient(to right, #4294E3, #8F12FD); /* Gradient
background */
color: white;
padding: 2px; /* Adjust padding as needed */
}
#new-conversation-btn {
background-color: transparent;
border: 20px;
cursor: pointer;
position: relative;
display: flexbox; /* Use flexbox */
justify-content: right; /* Align icon to the right */
margin: 25px;
}
.tooltiptext {
visibility: hidden;
width: 80px;
background-color: #8F12FD;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 0;
position: absolute;
z-index: 1;
right: -85px; /* Adjust top position as needed */
/* Align to the right edge of the button */
}
#new-conversation-btn:hover .tooltiptext {
visibility: visible;
}
/* Avatar icon and username */
.avatar {
width: 50px;
height: 50px;
border-radius: 50%;
object-fit: cover;
}
.conversation-list {
height: 70vh; /* Define height */
width: 100%; /* Ensure it takes the full width of the sidebar */
overflow-y: auto; /* Make it scrollable */
margin-bottom: 60px; /* Ensure there's space for the fixed user-info
*/
padding: 10px; /* Optional: add some padding */
box-sizing: border-box; /* Ensure padding is included in the width */
}
.user-info {
display: flex; /* Use flexbox for alignment */
align-items: center; /* Center align items vertically */
position: absolute; /* Position it within the sidebar */
bottom: 0; /* Position it at the bottom of the sidebar */
width: 100%; /* Ensure it spans the full width of the sidebar */
background-color: var(--primary-color); /* Optional: add a background
color */
padding: 10px; /* Optional: add some padding */
box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1); /* Optional: add a shadow
for better visual separation */
}
.user-name {
margin-left: 10px;
/* WhatsApp-like chat UI */
.chat-list .message {
display: flex;
margin-bottom: 10px;
}
.chat-list .message.user {
justify-content: flex-end;
}
.chat-list .message.user .message-content {
background-color: #dcf8c6;
color: #000;
border-radius: 20px 20px 0 20px;
padding: 10px;
max-width: 70%;
word-wrap: break-word;
}
.chat-list .message.ai {
justify-content: flex-start;
}
.chat-list .message.ai .message-content {
background-color: #fff;
color: #000;
border-radius: 20px 20px 20px 0;
padding: 10px;
max-width: 70%;
word-wrap: break-word;
}
.chat-list .message .timestamp {
font-size: 0.75rem;
color: #999;
margin-top: 5px;
}
.chat-list .message.user .timestamp {
text-align: right;
}
.chat-list .message.ai .timestamp {
text-align: left;
}
/* This is code for the conversation sidebar */
.conversation-wrapper {
background-color: var(--primary-color);
padding: 10px;
margin-bottom: 10px;
border-radius: 5px;
transition: background-color 0.3s ease;
display: flex;
flex-direction: row; /* Change to row layout */
align-items: flex-start; /* Align items to the left */
}
.conversation-wrapper:hover {
background-color: var(--conversation-hover-color);
}
.conversation-timestamp {
font-size: 12px;
color: var(--subheading-color);
margin-bottom: 5px;
}
.conversation-content {
font-family: "Arial", "Verdana";
font-size: 12px;
margin-bottom: 10px;
display: flex;
align-items: center;
width: 100%;
color: var(--text-color);
}
.delete-button {
background: none;
border: none;
color: var(--subheading-color);
cursor: pointer;
font-size: 1.5rem;
}
.delete-button:hover {
color: var(--text-color);
}
/* typing issue corrected */
.typing-area {
display: flex;
width: 100%;
padding: 1rem; /* Adjust the padding to reduce the gap */
margin-bottom: 3px; /* Ensure the input form is always visible */
justify-content: space-between; /* Align items with space between
them */
}
.typing-form {
display: flex;
width: 100%;
gap: 0.5rem;
}
.input-wrapper {
flex-grow: 1; /* Allow the input-wrapper to grow and take up
available space */
min-height: 56px; /* Minimum height */
display: flex;
position: relative;
flex-direction: column; /* Ensure the wrapper can grow vertically */
box-sizing: border-box; /* Include padding and border in the
element's total width and height */
max-height: 200px; /* Set the maximum height to 300px */
border-radius: 20px;
}
.typing-form .typing-input {
width: 100%; /* Ensure the input takes the full width of the input-
wrapper */
height: auto; /* Allow the height to adjust automatically */
border: none;
outline: none;
resize: none;
font-size: 1rem;
color: var(--text-color);
border-radius: 10px;
white-space: pre-wrap; /* Allow text to wrap to the next line */
overflow-wrap: break-word; /* Break long words */
min-height: 56px; /* Minimum height */
max-height: 500px; /* Maximum height */
transition: height 0.2s ease; /* Smooth transition for height change
*/
box-sizing: border-box; /* Include padding and border in the
element's total width and height */
padding: 20px; /* Add padding to the input */
background-color: var(--secondary-color);
}
.typing-form .typing-input:focus {
background: var(--secondary-hover-color);
}
.typing-form .typing-input::placeholder {
color: var(--placeholder-color);
}
.typing-area .icon {
width: 56px;
height: 56px;
flex-shrink: 0;
cursor: pointer;
border-radius: 20%;
display: flex;
font-size: 1.4rem;
color: var(--text-color);
align-items: center;
justify-content: center;
background: var(--secondary-color);
transition: 0.2s ease;
}
.typing-area .icon:hover {
background: var(--secondary-hover-color);
}
.typing-form #send-message-button {
outline: none;
border: none;
background: var(--secondary-color);
transition: background 0.2s ease;
margin-top: 8px;
padding: 10px; /* Add padding to the button */
border-radius: 20%; /* Make the button circular */
cursor: pointer;
}
.typing-form #send-message-button:hover {
background: var(--secondary-hover-color);
}
.typing-form .typing-input:valid ~ #send-message-button {
transform: scale(1);
}
.action-buttons {
display: flex;
gap: 0.5rem;
padding-top: 9px;
}
.action-buttons .icon {
width: 56px;
height: 56px;
flex-shrink: 0;
cursor: pointer;
border-radius: 20%;
display: flex;
font-size: 1.4rem;
color: var(--text-color);
align-items: center;
justify-content: center;
background: var(--secondary-color);
transition: 0.2s ease;
}
.action-buttons .icon:hover {
background: var(--secondary-hover-color);
}
.end-buttons {
display: flex;
flex-direction: column; /* Arrange buttons in a column */
gap: 3px; /* Add 3px space between buttons */
}
.end-buttons button {
background-color: var(--secondary-color); /* Set background color */
color: var(--text-color);
border: none;
border-radius: 20%;
padding: 10px;
cursor: pointer;
transition: background-color 0.2s ease;
}
/* Set background color for modal */
/* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Content */
.modal-content {
background-color: #fefefe;
margin: 15% auto; /* 15% from the top and centered */
padding: 20px;
border: 1px solid #888;
width: 80%; /* Could be more or less, depending on screen size */
max-width: 500px; /* Maximum width */
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2), 0 6px 20px 0
rgba(0,0,0,0.19);
animation-name: animatetop;
animation-duration: 0.4s;
}
/* The Close Button */
.close-button {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close-button:hover,
.close-button:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
/* Modal Message */
.modal p {
margin: 10px 0;
}
/* Modal Buttons */
.modal button {
background-color: var(--sidebar-color);
color: white;
padding: 10px 20px;
margin: 10px 0;
border: none;
cursor: pointer;
width: 100%;
}
.modal button:hover {
opacity: 0.8;
}
/* Animation */
@keyframes animatetop {
from {top: -300px; opacity: 0}
to {top: 0; opacity: 1}
}
/* Premium Version Ribbon */
.premium-ribbon {
position: fixed;
top: 20px;
right: 20px;
background-color: #a546f8; /* Secondary color */
color: white;
padding: 10px 20px;
border-radius: 20px;
z-index: 1000;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
/* Premium Subscription Modal */
#premiumModal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
}
#premiumModal .modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
max-width: 400px;
}
#premiumModal .close-button {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
#premiumModal .close-button:hover,
#premiumModal .close-button:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
#logout{
background-color: var(--secondary-color);
padding: 3px;
border-radius: 5px;
}
#logout:hover{
background-color: var(--secondary-hover-color);
}
.avatar {
width: 50px;
height: 50px;
border-radius: 50%;
background-color: var(--secondary-color); /* You can change the
background color */
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
font-weight: bold;
margin-bottom: 10px; /* Optional: Adds space between the avatar and
the user info */
}
THE JAVASCRIPT
const typingForm = document.querySelector(".typing-form");
const sendButton = document.getElementById("send-message-button");
const chatContainer = document.querySelector(".chat-list");
const suggestions = document.querySelectorAll(".suggestion");
const toggleThemeButton = document.querySelector("#theme-toggle-
button");
const deleteChatButton = document.querySelector("#delete-chat-button");
const fileUploadButton = document.getElementById("file-upload");
// State variables
let userMessage = null;
let isResponseGenerating = false;
let currentConversationIndex = -1; // Track the index of the current
conversation
let uploadedFiles = [];
let conversationHistory = []; // Store conversation history
// API configuration
const API_KEY = "AIzaSyBVDQxbstQsaL4p3Wp1e6U878CilqqRUyw"; // Your API
key here
const API_URL =
`https://generativelanguage.googleapis.com/v1/models/gemini-1.5-
pro:generateContent?key=${API_KEY}`;
// Load theme and chat data from local storage on page load
const loadDataFromLocalstorage = () => {
const savedChats = localStorage.getItem("saved-chats");
const isLightMode = localStorage.getItem("themeColor") ===
"light_mode";
// Apply the stored theme
document.body.classList.toggle("light_mode", isLightMode);
toggleThemeButton.innerText = isLightMode ? "dark_mode" :
"light_mode";
// Restore saved chats or clear the chat container
chatContainer.innerHTML = savedChats || "";
document.body.classList.toggle("hide-header", savedChats);
chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll to
the bottom
// Display the conversations in the sidebar
const conversations =
JSON.parse(localStorage.getItem("conversations")) || [];
const conversationListElement =
document.querySelector(".conversation-list");
// Clear the conversation list
conversationListElement.innerHTML = "";
// Add each conversation to the conversation list
conversations.reverse().forEach((conversation, index) => {
const conversationWrapper = document.createElement("div");
conversationWrapper.classList.add("conversation-wrapper");
// Format the timestamp
const timestamp = new Date(conversation.timestamp);
const options = {
day: "2-digit",
month: "2-digit",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
hour12: true,
};
const formattedTimestamp = new Intl.DateTimeFormat("en-GB",
options).format(timestamp);
// Create the timestamp element
const timestampElement = document.createElement("p");
timestampElement.classList.add("conversation-timestamp");
timestampElement.innerText = formattedTimestamp;
// Create the conversation content element
const contentElement = document.createElement("p");
contentElement.classList.add("conversation-content");
contentElement.innerText = conversation.message.length > 25
? conversation.message.substring(0, 30) + "..."
: conversation.message;
// Create the delete button
const deleteButton = document.createElement("button");
deleteButton.classList.add("delete-button", "icon", "material-
symbols-rounded");
deleteButton.innerText = "delete";
deleteButton.addEventListener("click", (e) => {
e.stopPropagation(); // Prevent the click event from bubbling up
to the conversation wrapper
// Remove the conversation from the array and local storage
conversations.splice(index, 1);
localStorage.setItem("conversations",
JSON.stringify(conversations));
loadDataFromLocalstorage();
});
// Append the elements to the conversation wrapper
conversationWrapper.appendChild(timestampElement);
conversationWrapper.appendChild(contentElement);
conversationWrapper.appendChild(deleteButton);
// Add click event listener to restore the conversation
conversationWrapper.addEventListener("click", () => {
chatContainer.innerHTML = conversation.chatContent;
chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll
to the bottom
document.body.classList.add("hide-header"); // Hide the header
closeNav(); // Close the sidebar
currentConversationIndex = conversations.length - 1 - index; //
Set the current conversation index
conversationHistory = conversation.history || []; // Restore
conversation history
});
conversationListElement.appendChild(conversationWrapper);
});
};
// Create a new message element and return it
const createMessageElement = (content, ...classes) => {
const div = document.createElement("div");
div.classList.add("message", ...classes);
div.innerHTML = content;
return div;
};
// Show typing effect by displaying words one by one
const showTypingEffect = (text, textElement, incomingMessageDiv) => {
textElement.innerText = ""; // Clear the text element before starting
the typing effect
const words = text.split(" ");
let currentWordIndex = 0;
const typingInterval = setInterval(() => {
// Append each word to the text element with a space
textElement.innerText +=
(currentWordIndex === 0 ? "" : " ") + words[currentWordIndex++];
incomingMessageDiv.querySelector(".icon").classList.add("hide");
// If all words are displayed
if (currentWordIndex === words.length) {
clearInterval(typingInterval);
isResponseGenerating = false;
incomingMessageDiv.querySelector(".icon").classList.remove("hide");
localStorage.setItem("saved-chats", chatContainer.innerHTML); //
Save chats to local storage
}
chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll to
the bottom
}, 75);
};
// Fetch response from the API based on user message
const generateAPIResponse = async (incomingMessageDiv) => {
const textElement = incomingMessageDiv.querySelector(".text"); //
Getting text element
try {
// Send a POST request to the API with the user's message and
conversation history
const response = await fetch(API_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
contents: [
...conversationHistory, // Include conversation history
{
role: "user",
parts: [{ text: userMessage }],
},
],
}),
});
const data = await response.json();
if (!response.ok) throw new Error(data.error.message);
// Get the API response text
let apiResponse = data?.candidates[0].content.parts[0].text;
// Bold headings and subheadings using Markdown syntax
apiResponse = apiResponse.replace(/\*\*(.*?)\*\*/g, "$1");
// Replace asterisks with real bullet points
apiResponse = apiResponse.replace(/^\* /gm, "• ");
// Render the Markdown properly in the UI
textElement.innerHTML = apiResponse
.replace(/(?:\r\n|\r|\n)/g, "<br>"); // Convert line breaks to
<br>
// Set line and paragraph spacing to 2.0
textElement.style.lineHeight = "1.5";
textElement.style.marginBottom = "1.9em";
// Show typing effect
showTypingEffect(apiResponse, textElement, incomingMessageDiv);
// Update conversation history
conversationHistory.push({
role: "user",
parts: [{ text: userMessage }],
}, {
role: "model",
parts: [{ text: apiResponse }],
});
} catch (error) {
// Handle error
isResponseGenerating = false;
textElement.innerText = error.message;
textElement.parentElement.closest(".message").classList.add("error");
} finally {
incomingMessageDiv.classList.remove("loading");
}
};
// Show a loading animation while waiting for the API response
const showLoadingAnimation = () => {
const html = `<div class="message-content">
<img class="avatar" src="images/logo.png"
alt="Assignment-Solver Logo">
<p class="text"></p>
<div class="loading-indicator">
<div class="loading-bar"></div>
<div class="loading-bar"></div>
<div class="loading-bar"></div>
<div class="loading-bar"></div>
</div>
</div>
<div class="end-buttons">
<button class="icon material-symbols-rounded"
onClick="copyMessage(this)">content_copy </button>
<button class="icon material-symbols-rounded"
onClick="likeMessage(this)">thumb_up</button>
<button class="icon material-symbols-rounded"
onClick="dislikeMessage(this)">thumb_down</button>
<button class="icon material-symbols-rounded"
onClick="reviewMessage(this)">rate_review</button>
</div>`;
const incomingMessageDiv = createMessageElement(html, "incoming",
"loading");
chatContainer.appendChild(incomingMessageDiv);
chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll to
the bottom
generateAPIResponse(incomingMessageDiv);
};
// Copy message text to the clipboard
const copyMessage = (copyButton) => {
const messageText =
copyButton.closest(".message").querySelector(".text").innerText;
navigator.clipboard.writeText(messageText).then(() => {
copyButton.innerText = "done"; // Show confirmation icon
setTimeout(() => (copyButton.innerText = "content_copy"), 1000); //
Revert icon after 1 second
}).catch(err => {
console.error("Failed to copy text: ", err);
});
};
// Like message
const likeMessage = (likeButton) => {
likeButton.classList.toggle("liked");
if (likeButton.classList.contains("liked")) {
likeButton.classList.remove("disliked");
}
showLikeModal(); // Show the like modal when the like button is
clicked
};
// Dislike message
const dislikeMessage = (dislikeButton) => {
dislikeButton.classList.toggle("disliked");
if (dislikeButton.classList.contains("disliked")) {
dislikeButton.classList.remove("liked");
}
showDislikeModal(); // Show the dislike modal when the dislike button
is clicked
};
// Review message
const reviewMessage = (reviewButton) => {
showReviewModal();
};
// Show like modal
const showLikeModal = () => {
const modal = document.getElementById("likeModal");
const modalMessage = document.getElementById("likeModalMessage");
const submitLike = document.getElementById("submitLike");
modalMessage.innerText = "You liked this message!";
modal.style.display = "block";
submitLike.onclick = () => {
modal.style.display = "none";
};
};
// Show dislike modal
const showDislikeModal = () => {
const modal = document.getElementById("dislikeModal");
const modalMessage = document.getElementById("dislikeModalMessage");
const submitDislike = document.getElementById("submitDislike");
modalMessage.innerText = "You disliked this message!";
modal.style.display = "block";
submitDislike.onclick = () => {
modal.style.display = "none";
};
};
// Show review modal
const showReviewModal = () => {
const modal = document.getElementById("customModal");
const modalMessage = document.getElementById("modalMessage");
const reviewInput = document.getElementById("reviewInput");
const submitReview = document.getElementById("submitReview");
modalMessage.innerText = "Please leave a review:";
reviewInput.style.display = "block";
submitReview.style.display = "block";
modal.style.display = "block";
submitReview.onclick = () => {
const review = reviewInput.value.trim();
if (review) {
const subject = encodeURIComponent("Review from User");
const body = encodeURIComponent(`Review: ${review}`);
const mailtoLink = `mailto:[email protected]?
subject=${subject}&body=${body}`;
// Open the user's default email client with the pre-filled email
window.location.href = mailtoLink;
modal.style.display = "none";
}
};
};
// Close the modal
const closeModal = (modalId) => {
const modal = document.getElementById(modalId);
modal.style.display = "none";
};
// Add event listener to close button
document.querySelectorAll(".close-button").forEach(button => {
button.addEventListener("click", () => {
closeModal(button.closest(".modal").id);
});
});
// Add event listener to close modal when clicking outside
window.addEventListener("click", (event) => {
const modals = document.querySelectorAll(".modal");
modals.forEach(modal => {
if (event.target === modal) {
closeModal(modal.id);
}
});
});
// Handle file upload
const handleFileUpload = (event) => {
const files = event.target.files;
uploadedFiles = Array.from(files).map(file => ({
name: file.name,
type: file.type,
size: file.size,
data: URL.createObjectURL(file)
}));
// Update the user message with file information
const fileNames = uploadedFiles.map(file => file.name).join(", ");
userMessage = `Uploaded files: ${fileNames}. `;
typingForm.querySelector(".typing-input").value = userMessage;
};
// Handle sending outgoing chat messages
// Handle sending outgoing chat messages
const handleOutgoingChat = () => {
userMessage = typingForm.querySelector(".typing-input").value.trim()
|| userMessage;
if (!userMessage || isResponseGenerating) return; // Exit if there is
no message or response is generating
isResponseGenerating = true;
const html = `<div class="message-content">
<div class="avatar" id="avatarCircle"></div>
<p class="text"></p>
</div>`;
const outgoingMessageDiv = createMessageElement(html, "outgoing");
outgoingMessageDiv.querySelector(".text").innerText = userMessage;
// Set the first letters of the first name and last name inside the
circle
const firstName =
document.getElementById('loggedUserFName').innerText;
const lastName =
document.getElementById('loggedUserLName').innerText;
const avatarCircle =
outgoingMessageDiv.querySelector('#avatarCircle');
avatarCircle.innerText = firstName.charAt(0).toUpperCase() +
lastName.charAt(0).toUpperCase();
chatContainer.appendChild(outgoingMessageDiv);
typingForm.reset(); // Clear input field
document.body.classList.add("hide-header");
chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll to
the bottom
setTimeout(showLoadingAnimation, 500); // Show loading animation
after a delay
// Save the conversation to local storage
const conversations =
JSON.parse(localStorage.getItem("conversations")) || [];
if (currentConversationIndex === -1) {
// If no current conversation, create a new one
conversations.push({
message: userMessage,
timestamp: new Date().toISOString(),
chatContent: chatContainer.innerHTML, // Save the current chat
content
history: conversationHistory // Save the conversation history
});
currentConversationIndex = conversations.length - 1;
} else {
// Update the existing conversation
conversations[currentConversationIndex].chatContent =
chatContainer.innerHTML;
conversations[currentConversationIndex].timestamp = new
Date().toISOString(); // Update the timestamp
conversations[currentConversationIndex].history =
conversationHistory; // Update the conversation history
}
localStorage.setItem("conversations", JSON.stringify(conversations));
localStorage.setItem("saved-chats", chatContainer.innerHTML); // Save
the current chat content to "saved-chats"
};
// Toggle between light and dark themes
toggleThemeButton.addEventListener("click", () => {
const isLightMode = document.body.classList.toggle("light_mode");
localStorage.setItem("themeColor", isLightMode ? "light_mode" :
"dark_mode");
toggleThemeButton.innerText = isLightMode ? "dark_mode" :
"light_mode";
});
// Delete all chats from local storage when button is clicked
deleteChatButton.addEventListener("click", () => {
if (confirm("Are you sure you want to delete all the chats?")) {
localStorage.removeItem("saved-chats");
localStorage.removeItem("conversations");
loadDataFromLocalstorage();
}
});
// Set userMessage and handle outgoing chat when a suggestion is
clicked
suggestions.forEach((suggestion) => {
suggestion.addEventListener("click", () => {
userMessage = suggestion.querySelector(".text").innerText;
handleOutgoingChat();
});
});
// Prevent default form submission and handle outgoing chat
typingForm.addEventListener("submit", (e) => {
e.preventDefault();
handleOutgoingChat();
});
// Handle send button click
sendButton.addEventListener("click", handleOutgoingChat);
// Handle file upload button click
fileUploadButton.addEventListener("change", handleFileUpload);
loadDataFromLocalstorage();
// for the sidebar
const sidebar = document.getElementById("mySidenav");
const mainContent = document.querySelector(".main-content");
function openNav() {
sidebar.classList.add("open");
mainContent.classList.add("sidebar-open");
}
function closeNav() {
sidebar.classList.remove("open");
mainContent.classList.remove("sidebar-open");
}
// Start a new conversation
const newConversationButton = document.getElementById("new-
conversation-btn");
newConversationButton.addEventListener("click", () => {
if (confirm("Are you sure you want to start a new conversation?")) {
// Clear the chat container and last conversation
localStorage.removeItem("saved-chats");
localStorage.removeItem("last-conversation");
currentConversationIndex = -1; // Reset the current conversation
index
conversationHistory = []; // Clear the conversation history
loadDataFromLocalstorage();
}
});
// for textarea for input
const textarea = document.querySelector("textarea");
textarea.addEventListener("keyup", e =>{
textarea.style.height = "45px";
let scHeight = e.target.scrollHeight;
textarea.style.height = `${scHeight}px`;
});
// Reset textarea height when it loses focus
textarea.addEventListener("blur", () => {
setTimeout(() => {
textarea.style.height = "45px";
}, 200); // Adjust the timeout as needed
});
// JavaScript to handle the file upload button click and display the
premium subscription modal
document.getElementById('file-upload').addEventListener('change',
function() {
document.getElementById('premiumModal').style.display = 'block';
});
// JavaScript to close the premium subscription modal
document.querySelector('#premiumModal .close-
button').addEventListener('click', function() {
document.getElementById('premiumModal').style.display = 'none';
});
// JavaScript to close the premium subscription modal when clicking
outside
window.addEventListener('click', function(event) {
const premiumModal = document.getElementById('premiumModal');
if (event.target === premiumModal) {
premiumModal.style.display = 'none';
}
});
// Set the first letters of the first name and last name inside the
circle
const avatarCircle = document.getElementById('avatarCircle');
avatarCircle.innerText = userData.firstName.charAt(0).toUpperCase() +
userData.lastName.charAt(0).toUpperCase();
Student Assignment Solver Web App
Concept:
A web application designed to assist students in solving their assignments using an advanced Gemini
language model that provides comprehensive answers to user inquiries.
Features:
* Assignment Input: Users can upload their assignments or paste the text directly into the app.
* Natural Language Queries: Students can ask questions related to their assignments using natural
language, similar to how they would ask a human tutor.
* Gemini Language Model: The app utilizes a robust Gemini language model that understands
complex queries and generates detailed, accurate responses.
* Step-by-Step Explanations: The app provides comprehensive explanations for each answer,
breaking down the solution into easy-to-follow steps.
* Multiple Subject Support: The app supports a wide range of subjects, including Math, Science,
History, Literature, and more.
* Personalized Learning: The app tailors responses to each user's individual learning style and
knowledge gaps.
* Progress Tracking: Students can track their progress on assignments and identify areas where they
need additional support.
Benefits:
* Improved Assignment Completion: Students can complete their assignments more efficiently and
effectively with the help of automated answers.
* Enhanced Understanding: The app provides thorough explanations that deepen students'
comprehension of the subject matter.
* Reduced Confusion: By eliminating misunderstandings, the app reduces frustration and makes
learning more enjoyable.
* Time Savings: Students can save time that would have been spent searching for answers or seeking
help from tutors.
* Personalized Support: The app provides tailored support that caters to each student's specific
needs.
Tech Stack:
* Front-end: React, Redux
* Back-end: Node.js, Express.js
* Language Model: Gemini
* Database: MongoDB
Target Audience:
* High school and college students
* Educators and tutors
* Parents seeking support for their children's education
Improving your grades requires a multifaceted approach. Here are some key tips covering various
aspects of academic success:
Classroom Habits & Study Skills:
• Active Listening & Participation: Pay close attention in class, ask questions when you're confused,
and participate in discussions. This reinforces learning and shows your teacher you're engaged.
• Effective Note-Taking: Develop a note-taking system that works for you. Consider methods like the
Cornell method, mind mapping, or sketching. Review and organize your notes regularly.
• Time Management & Organization: Create a realistic study schedule and stick to it. Break down
large assignments into smaller, manageable tasks. Use a planner or calendar to track deadlines and
appointments.
• Understanding Learning Style: Identify your learning style (visual, auditory, kinesthetic) and tailor
your study methods accordingly. Experiment with different techniques to find what works best for
you.
• Effective Studying Techniques: Don't just reread – actively engage with the material. Use
techniques like flashcards, practice problems, summarizing, teaching the material to someone else,
and creating mnemonics.
• Regular Review: Don't cram! Review material regularly, even if there isn't a test coming up. This
reinforces learning and helps you retain information long-term.
Seeking Help & Resources:
• Ask for Help: Don't be afraid to ask your teachers, classmates, or tutors for help when you're
struggling. Understanding your weaknesses is the first step to improving.
• Utilize Available Resources: Take advantage of resources like study groups, tutoring centers, online
resources, and library resources.
• Communicate with Teachers: Talk to your teachers about your progress and any challenges you're
facing. They can offer valuable insights and support.
Beyond the Classroom:
• Prioritize Sleep: Getting enough sleep is crucial for concentration, memory, and overall academic
performance. Aim for 8-10 hours of sleep per night.
• Healthy Diet & Exercise: A balanced diet and regular exercise can improve focus, energy levels,
and mood, which can positively impact your studies.
• Stress Management: Develop healthy coping mechanisms for stress, such as exercise, meditation,
or spending time in nature. High levels of stress can negatively impact academic performance.
• Growth Mindset: Believe in your ability to learn and improve. Don't let setbacks discourage you.
View challenges as opportunities for growth.
• Set Realistic Goals: Don't try to change everything at once. Start with small, achievable goals and
gradually work your way up. Celebrate your progress along the way.
By implementing these tips and consistently putting in the effort, you can significantly improve your
grades and achieve your academic goals. Remember that it's a marathon, not a sprint, and
consistency is key.
Hugging face key: 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
USING HUGGING FACE
const typingForm = document.querySelector(".typing-form");
const sendButton = document.getElementById("send-message-button");
const chatContainer = document.querySelector(".chat-list");
const suggestions = document.querySelectorAll(".suggestion");
const toggleThemeButton = document.querySelector("#theme-toggle-button");
const deleteChatButton = document.querySelector("#delete-chat-button");
const fileUploadButton = document.getElementById("file-upload");
// State variables
let userMessage = null;
let isResponseGenerating = false;
let currentConversationIndex = -1; // Track the index of the current conversation
let uploadedFiles = [];
let conversationHistory = []; // Store conversation history
// Hugging Face Inference API configuration
import { HfInference } from "@huggingface/inference";
const client = new HfInference("hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
// Load theme and chat data from local storage on page load
const loadDataFromLocalstorage = () => {
const savedChats = localStorage.getItem("saved-chats");
const isLightMode = localStorage.getItem("themeColor") === "light_mode";
// Apply the stored theme
document.body.classList.toggle("light_mode", isLightMode);
toggleThemeButton.innerText = isLightMode ? "dark_mode" : "light_mode";
// Restore saved chats or clear the chat container
chatContainer.innerHTML = savedChats || "";
document.body.classList.toggle("hide-header", savedChats);
chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll to the bottom
// Display the conversations in the sidebar
const conversations = JSON.parse(localStorage.getItem("conversations")) || [];
const conversationListElement = document.querySelector(".conversation-list");
// Clear the conversation list
conversationListElement.innerHTML = "";
// Add each conversation to the conversation list
conversations.reverse().forEach((conversation, index) => {
const conversationWrapper = document.createElement("div");
conversationWrapper.classList.add("conversation-wrapper");
// Format the timestamp
const timestamp = new Date(conversation.timestamp);
const options = {
day: "2-digit",
month: "2-digit",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
hour12: true,
};
const formattedTimestamp = new Intl.DateTimeFormat("en-GB", options).format(timestamp);
// Create the timestamp element
const timestampElement = document.createElement("p");
timestampElement.classList.add("conversation-timestamp");
timestampElement.innerText = formattedTimestamp;
// Create the conversation content element
const contentElement = document.createElement("p");
contentElement.classList.add("conversation-content");
contentElement.innerText = conversation.message.length > 25
? conversation.message.substring(0, 30) + "..."
: conversation.message;
// Create the delete button
const deleteButton = document.createElement("button");
deleteButton.classList.add("delete-button", "icon", "material-symbols-rounded");
deleteButton.innerText = "delete";
deleteButton.addEventListener("click", (e) => {
e.stopPropagation(); // Prevent the click event from bubbling up to the conversation wrapper
// Remove the conversation from the array and local storage
conversations.splice(index, 1);
localStorage.setItem("conversations", JSON.stringify(conversations));
loadDataFromLocalstorage();
});
// Append the elements to the conversation wrapper
conversationWrapper.appendChild(timestampElement);
conversationWrapper.appendChild(contentElement);
conversationWrapper.appendChild(deleteButton);
// Add click event listener to restore the conversation
conversationWrapper.addEventListener("click", () => {
chatContainer.innerHTML = conversation.chatContent;
chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll to the bottom
document.body.classList.add("hide-header"); // Hide the header
closeNav(); // Close the sidebar
currentConversationIndex = conversations.length - 1 - index; // Set the current conversation
index
conversationHistory = conversation.history || []; // Restore conversation history
});
conversationListElement.appendChild(conversationWrapper);
});
};
// Create a new message element and return it
const createMessageElement = (content, ...classes) => {
const div = document.createElement("div");
div.classList.add("message", ...classes);
div.innerHTML = content;
return div;
};
// Show typing effect by displaying words one by one
const showTypingEffect = (text, textElement, incomingMessageDiv) => {
textElement.innerText = ""; // Clear the text element before starting the typing effect
const words = text.split(" ");
let currentWordIndex = 0;
const typingInterval = setInterval(() => {
// Append each word to the text element with a space
textElement.innerText +=
(currentWordIndex === 0 ? "" : " ") + words[currentWordIndex++];
incomingMessageDiv.querySelector(".icon").classList.add("hide");
// If all words are displayed
if (currentWordIndex === words.length) {
clearInterval(typingInterval);
isResponseGenerating = false;
incomingMessageDiv.querySelector(".icon").classList.remove("hide");
localStorage.setItem("saved-chats", chatContainer.innerHTML); // Save chats to local storage
chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll to the bottom
}, 75);
};
// Fetch response from the Hugging Face API based on user message
const generateAPIResponse = async (incomingMessageDiv) => {
const textElement = incomingMessageDiv.querySelector(".text"); // Getting text element
try {
// Send a POST request to the API with the user's message and conversation history
const chatCompletion = await client.chatCompletion({
model: "cognitivecomputations/dolphin-2.9.2-qwen2-72b",
messages: [
...conversationHistory.map(message => ({
role: message.role,
content: message.parts[0].text
})),
role: "user",
content: userMessage
],
max_tokens: 500
});
// Get the API response text
const apiResponse = chatCompletion.choices[0].message.content;
// Render the response in the UI
textElement.innerText = apiResponse;
// Show typing effect
showTypingEffect(apiResponse, textElement, incomingMessageDiv);
// Update conversation history
conversationHistory.push({
role: "user",
parts: [{ text: userMessage }],
}, {
role: "model",
parts: [{ text: apiResponse }],
});
} catch (error) {
// Handle error
isResponseGenerating = false;
textElement.innerText = error.message;
textElement.parentElement.closest(".message").classList.add("error");
} finally {
incomingMessageDiv.classList.remove("loading");
};
// Show a loading animation while waiting for the API response
const showLoadingAnimation = () => {
const html = `<div class="message-content">
<div class="avatar" id="avatarCircle"></div>
<p class="text"></p>
<div class="loading-indicator">
<div class="loading-bar"></div>
<div class="loading-bar"></div>
<div class="loading-bar"></div>
<div class="loading-bar"></div>
</div>
</div>
<div class="end-buttons">
<button class="icon material-symbols-rounded"
onClick="copyMessage(this)">content_copy </button>
<button class="icon material-symbols-rounded"
onClick="likeMessage(this)">thumb_up</button>
<button class="icon material-symbols-rounded"
onClick="dislikeMessage(this)">thumb_down</button>
<button class="icon material-symbols-rounded"
onClick="reviewMessage(this)">rate_review</button>
</div>`;
const incomingMessageDiv = createMessageElement(html, "incoming", "loading");
chatContainer.appendChild(incomingMessageDiv);
chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll to the bottom
generateAPIResponse(incomingMessageDiv);
};
// Copy message text to the clipboard
const copyMessage = (copyButton) => {
const messageText = copyButton.closest(".message").querySelector(".text").innerText;
navigator.clipboard.writeText(messageText).then(() => {
copyButton.innerText = "done"; // Show confirmation icon
setTimeout(() => (copyButton.innerText = "content_copy"), 1000); // Revert icon after 1 second
}).catch(err => {
console.error("Failed to copy text: ", err);
});
};
// Like message
const likeMessage = (likeButton) => {
likeButton.classList.toggle("liked");
if (likeButton.classList.contains("liked")) {
likeButton.classList.remove("disliked");
showLikeModal(); // Show the like modal when the like button is clicked
};
// Dislike message
const dislikeMessage = (dislikeButton) => {
dislikeButton.classList.toggle("disliked");
if (dislikeButton.classList.contains("disliked")) {
dislikeButton.classList.remove("liked");
showDislikeModal(); // Show the dislike modal when the dislike button is clicked
};
// Review message
const reviewMessage = (reviewButton) => {
showReviewModal();
};
// Show like modal
const showLikeModal = () => {
const modal = document.getElementById("likeModal");
const modalMessage = document.getElementById("likeModalMessage");
const submitLike = document.getElementById("submitLike");
modalMessage.innerText = "You liked this message!";
modal.style.display = "block";
submitLike.onclick = () => {
modal.style.display = "none";
};
};
// Show dislike modal
const showDislikeModal = () => {
const modal = document.getElementById("dislikeModal");
const modalMessage = document.getElementById("dislikeModalMessage");
const submitDislike = document.getElementById("submitDislike");
modalMessage.innerText = "You disliked this message!";
modal.style.display = "block";
submitDislike.onclick = () => {
modal.style.display = "none";
};
};
// Show review modal
const showReviewModal = () => {
const modal = document.getElementById("customModal");
const modalMessage = document.getElementById("modalMessage");
const reviewInput = document.getElementById("reviewInput");
const submitReview = document.getElementById("submitReview");
modalMessage.innerText = "Please leave a review:";
reviewInput.style.display = "block";
submitReview.style.display = "block";
modal.style.display = "block";
submitReview.onclick = () => {
const review = reviewInput.value.trim();
if (review) {
const subject = encodeURIComponent("Review from User");
const body = encodeURIComponent(`Review: ${review}`);
const mailtoLink = `mailto:[email protected]?subject=${subject}&body=$
{body}`;
// Open the user's default email client with the pre-filled email
window.location.href = mailtoLink;
modal.style.display = "none";
};
};
// Close the modal
const closeModal = (modalId) => {
const modal = document.getElementById(modalId);
modal.style.display = "none";
};
// Add event listener to close button
document.querySelectorAll(".close-button").forEach(button => {
button.addEventListener("click", () => {
closeModal(button.closest(".modal").id);
});
});
// Add event listener to close modal when clicking outside
window.addEventListener("click", (event) => {
const modals = document.querySelectorAll(".modal");
modals.forEach(modal => {
if (event.target === modal) {
closeModal(modal.id);
});
});
// Handle file upload
const handleFileUpload = (event) => {
const files = event.target.files;
uploadedFiles = Array.from(files).map(file => ({
name: file.name,
type: file.type,
size: file.size,
data: URL.createObjectURL(file)
}));
// Update the user message with file information
const fileNames = uploadedFiles.map(file => file.name).join(", ");
userMessage = `Uploaded files: ${fileNames}. `;
typingForm.querySelector(".typing-input").value = userMessage;
};
// Handle sending outgoing chat messages
const handleOutgoingChat = () => {
userMessage = typingForm.querySelector(".typing-input").value.trim() || userMessage;
if (!userMessage || isResponseGenerating) return; // Exit if there is no message or response is
generating
isResponseGenerating = true;
const html = `<div class="message-content">
<div class="avatar" id="avatarCircle"></div>
<p class="text"></p>
</div>`;
const outgoingMessageDiv = createMessageElement(html, "outgoing");
outgoingMessageDiv.querySelector(".text").innerText = userMessage;
// Set the first letters of the first name and last name inside the circle
const firstName = document.getElementById('loggedUserFName').innerText;
const lastName = document.getElementById('loggedUserLName').innerText;
const avatarCircle = outgoingMessageDiv.querySelector('#avatarCircle');
avatarCircle.innerText = firstName.charAt(0).toUpperCase() + lastName.charAt(0).toUpperCase();
chatContainer.appendChild(outgoingMessageDiv);
typingForm.reset(); // Clear input field
document.body.classList.add("hide-header");
chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll to the bottom
setTimeout(showLoadingAnimation, 500); // Show loading animation after a delay
// Save the conversation to local storage
const conversations = JSON.parse(localStorage.getItem("conversations")) || [];
if (currentConversationIndex === -1) {
// If no current conversation, create a new one
conversations.push({
message: userMessage,
timestamp: new Date().toISOString(),
chatContent: chatContainer.innerHTML, // Save the current chat content
history: conversationHistory // Save the conversation history
});
currentConversationIndex = conversations.length - 1;
} else {
// Update the existing conversation
conversations[currentConversationIndex].chatContent = chatContainer.innerHTML;
conversations[currentConversationIndex].timestamp = new Date().toISOString(); // Update the
timestamp
conversations[currentConversationIndex].history = conversationHistory; // Update the
conversation history
localStorage.setItem("conversations", JSON.stringify(conversations));
localStorage.setItem("saved-chats", chatContainer.innerHTML); // Save the current chat content to
"saved-chats"
};
// Toggle between light and dark themes
toggleThemeButton.addEventListener("click", () => {
const isLightMode = document.body.classList.toggle("light_mode");
localStorage.setItem("themeColor", isLightMode ? "light_mode" : "dark_mode");
toggleThemeButton.innerText = isLightMode ? "dark_mode" : "light_mode";
});
// Delete all chats from local storage when button is clicked
deleteChatButton.addEventListener("click", () => {
if (confirm("Are you sure you want to delete all the chats?")) {
localStorage.removeItem("saved-chats");
localStorage.removeItem("conversations");
loadDataFromLocalstorage();
});
// Set userMessage and handle outgoing chat when a suggestion is clicked
suggestions.forEach((suggestion) => {
suggestion.addEventListener("click", () => {
userMessage = suggestion.querySelector(".text").innerText;
handleOutgoingChat();
});
});
// Prevent default form submission and handle outgoing chat
typingForm.addEventListener("submit", (e) => {
e.preventDefault();
handleOutgoingChat();
});
// Handle send button click
sendButton.addEventListener("click", handleOutgoingChat);
// Handle file upload button click
fileUploadButton.addEventListener("change", handleFileUpload);
loadDataFromLocalstorage();
// for the sidebar
const sidebar = document.getElementById("mySidenav");
const mainContent = document.querySelector(".main-content");
function openNav() {
sidebar.classList.add("open");
mainContent.classList.add("sidebar-open");
function closeNav() {
sidebar.classList.remove("open");
mainContent.classList.remove("sidebar-open");
// Start a new conversation
const newConversationButton = document.getElementById("new-conversation-btn");
newConversationButton.addEventListener("click", () => {
if (confirm("Are you sure you want to start a new conversation?")) {
// Clear the chat container and last conversation
localStorage.removeItem("saved-chats");
localStorage.removeItem("last-conversation");
currentConversationIndex = -1; // Reset the current conversation index
conversationHistory = []; // Clear the conversation history
loadDataFromLocalstorage();
});
// for textarea for input
const textarea = document.querySelector("textarea");
textarea.addEventListener("keyup", e =>{
textarea.style.height = "45px";
let scHeight = e.target.scrollHeight;
textarea.style.height = `${scHeight}px`;
});
// Reset textarea height when it loses focus
textarea.addEventListener("blur", () => {
setTimeout(() => {
textarea.style.height = "45px";
}, 200); // Adjust the timeout as needed
});
// JavaScript to handle the file upload button click and display the premium subscription modal
document.getElementById('file-upload').addEventListener('change', function() {
document.getElementById('premiumModal').style.display = 'block';
});
// JavaScript to close the premium subscription modal
document.querySelector('#premiumModal .close-button').addEventListener('click', function() {
document.getElementById('premiumModal').style.display = 'none';
});
// JavaScript to close the premium subscription modal when clicking outside
window.addEventListener('click', function(event) {
const premiumModal = document.getElementById('premiumModal');
if (event.target === premiumModal) {
premiumModal.style.display = 'none';
});
// Example variables for first name and last name
const firstName = "John";
const lastName = "Doe";
// Set the first name and last name in the profile section
document.getElementById('loggedUserFName').innerText = firstName;
document.getElementById('loggedUserLName').innerText = lastName;
// Set the first letters of the first name and last name inside the circle
const avatarCircle = document.getElementById('avatarCircle');
avatarCircle.innerText = firstName.charAt(0).toUpperCase() + lastName.charAt(0).toUpperCase();
Zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzz
const typingForm = document.querySelector(".typing-form");
const sendButton = document.getElementById("send-message-button");
const chatContainer = document.querySelector(".chat-list");
const suggestions = document.querySelectorAll(".suggestion");
const toggleThemeButton = document.querySelector("#theme-toggle-
button");
const deleteChatButton = document.querySelector("#delete-chat-button");
const fileUploadButton = document.getElementById("file-upload");
// State variables
let userMessage = null;
let isResponseGenerating = false;
let currentConversationIndex = -1; // Track the index of the current
conversation
let uploadedFiles = [];
let conversationHistory = []; // Store conversation history
// API configuration
const API_KEY = "AIzaSyBVDQxbstQsaL4p3Wp1e6U878CilqqRUyw"; // Your API
key here
const API_URL =
`https://generativelanguage.googleapis.com/v1/models/gemini-1.5-
pro:generateContent?key=${API_KEY}`;
// Load theme and chat data from local storage on page load
const loadDataFromLocalstorage = () => {
const savedChats = localStorage.getItem("saved-chats");
const isLightMode = localStorage.getItem("themeColor") ===
"light_mode";
// Apply the stored theme
document.body.classList.toggle("light_mode", isLightMode);
toggleThemeButton.innerText = isLightMode ? "dark_mode" :
"light_mode";
// Restore saved chats or clear the chat container
chatContainer.innerHTML = savedChats || "";
document.body.classList.toggle("hide-header", savedChats);
chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll to
the bottom
// Display the conversations in the sidebar
const conversations =
JSON.parse(localStorage.getItem("conversations")) || [];
const conversationListElement =
document.querySelector(".conversation-list");
// Clear the conversation list
conversationListElement.innerHTML = "";
// Add each conversation to the conversation list
conversations.reverse().forEach((conversation, index) => {
const conversationWrapper = document.createElement("div");
conversationWrapper.classList.add("conversation-wrapper");
// Format the timestamp
const timestamp = new Date(conversation.timestamp);
const options = {
day: "2-digit",
month: "2-digit",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
hour12: true,
};
const formattedTimestamp = new Intl.DateTimeFormat("en-GB",
options).format(timestamp);
// Create the timestamp element
const timestampElement = document.createElement("p");
timestampElement.classList.add("conversation-timestamp");
timestampElement.innerText = formattedTimestamp;
// Create the conversation content element
const contentElement = document.createElement("p");
contentElement.classList.add("conversation-content");
contentElement.innerText = conversation.message.length > 25
? conversation.message.substring(0, 30) + "..."
: conversation.message;
// Create the delete button
const deleteButton = document.createElement("button");
deleteButton.classList.add("delete-button", "icon", "material-
symbols-rounded");
deleteButton.innerText = "delete";
deleteButton.addEventListener("click", (e) => {
e.stopPropagation(); // Prevent the click event from bubbling up
to the conversation wrapper
// Remove the conversation from the array and local storage
conversations.splice(index, 1);
localStorage.setItem("conversations",
JSON.stringify(conversations));
loadDataFromLocalstorage();
});
// Append the elements to the conversation wrapper
conversationWrapper.appendChild(timestampElement);
conversationWrapper.appendChild(contentElement);
conversationWrapper.appendChild(deleteButton);
// Add click event listener to restore the conversation
conversationWrapper.addEventListener("click", () => {
chatContainer.innerHTML = conversation.chatContent;
chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll
to the bottom
document.body.classList.add("hide-header"); // Hide the header
closeNav(); // Close the sidebar
currentConversationIndex = conversations.length - 1 - index; //
Set the current conversation index
conversationHistory = conversation.history || []; // Restore
conversation history
});
conversationListElement.appendChild(conversationWrapper);
});
};
// Create a new message element and return it
const createMessageElement = (content, ...classes) => {
const div = document.createElement("div");
div.classList.add("message", ...classes);
div.innerHTML = content;
return div;
};
// Show typing effect by displaying words one by one
const showTypingEffect = (text, textElement, incomingMessageDiv) => {
textElement.innerText = ""; // Clear the text element before starting
the typing effect
const words = text.split(" ");
let currentWordIndex = 0;
const typingInterval = setInterval(() => {
// Append each word to the text element with a space
textElement.innerText +=
(currentWordIndex === 0 ? "" : " ") + words[currentWordIndex++];
incomingMessageDiv.querySelector(".icon").classList.add("hide");
// If all words are displayed
if (currentWordIndex === words.length) {
clearInterval(typingInterval);
isResponseGenerating = false;
incomingMessageDiv.querySelector(".icon").classList.remove("hide");
localStorage.setItem("saved-chats", chatContainer.innerHTML); //
Save chats to local storage
}
chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll to
the bottom
}, 75);
};
// Fetch response from the API based on user message
const generateAPIResponse = async (incomingMessageDiv) => {
const textElement = incomingMessageDiv.querySelector(".text"); //
Getting text element
try {
// Send a POST request to the API with the user's message and
conversation history
const response = await fetch(API_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
contents: [
...conversationHistory, // Include conversation history
{
role: "user",
parts: [{ text: userMessage }],
},
],
}),
});
const data = await response.json();
if (!response.ok) throw new Error(data.error.message);
// Get the API response text
let apiResponse = data?.candidates[0].content.parts[0].text;
// Bold headings and subheadings using Markdown syntax
apiResponse = apiResponse.replace(/\*\*(.*?)\*\*/g, "$1");
// Replace asterisks with real bullet points
apiResponse = apiResponse.replace(/^\* /gm, "• ");
// Render the Markdown properly in the UI
textElement.innerHTML = apiResponse
.replace(/(?:\r\n|\r|\n)/g, "<br>"); // Convert line breaks to
<br>
// Set line and paragraph spacing to 2.0
textElement.style.lineHeight = "1.5";
textElement.style.marginBottom = "1.9em";
// Show typing effect
showTypingEffect(apiResponse, textElement, incomingMessageDiv);
// Update conversation history
conversationHistory.push({
role: "user",
parts: [{ text: userMessage }],
}, {
role: "model",
parts: [{ text: apiResponse }],
});
} catch (error) {
// Handle error
isResponseGenerating = false;
textElement.innerText = error.message;
textElement.parentElement.closest(".message").classList.add("error");
} finally {
incomingMessageDiv.classList.remove("loading");
}
};
// Show a loading animation while waiting for the API response
const showLoadingAnimation = () => {
const html = `<div class="message-content">
<img class="avatar" src="images/logo.png"
alt="Assignment-Solver Logo">
<p class="text"></p>
<div class="loading-indicator">
<div class="loading-bar"></div>
<div class="loading-bar"></div>
<div class="loading-bar"></div>
<div class="loading-bar"></div>
</div>
</div>
<div class="end-buttons">
<button class="icon material-symbols-rounded"
onClick="copyMessage(this)">content_copy </button>
<button class="icon material-symbols-rounded"
onClick="likeMessage(this)">thumb_up</button>
<button class="icon material-symbols-rounded"
onClick="dislikeMessage(this)">thumb_down</button>
<button class="icon material-symbols-rounded"
onClick="reviewMessage(this)">rate_review</button>
</div>`;
const incomingMessageDiv = createMessageElement(html, "incoming",
"loading");
chatContainer.appendChild(incomingMessageDiv);
chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll to
the bottom
generateAPIResponse(incomingMessageDiv);
};
// Copy message text to the clipboard
const copyMessage = (copyButton) => {
const messageText =
copyButton.closest(".message").querySelector(".text").innerText;
navigator.clipboard.writeText(messageText).then(() => {
copyButton.innerText = "done"; // Show confirmation icon
setTimeout(() => (copyButton.innerText = "content_copy"), 1000); //
Revert icon after 1 second
}).catch(err => {
console.error("Failed to copy text: ", err);
});
};
// Like message
const likeMessage = (likeButton) => {
likeButton.classList.toggle("liked");
if (likeButton.classList.contains("liked")) {
likeButton.classList.remove("disliked");
}
showLikeModal(); // Show the like modal when the like button is
clicked
};
// Dislike message
const dislikeMessage = (dislikeButton) => {
dislikeButton.classList.toggle("disliked");
if (dislikeButton.classList.contains("disliked")) {
dislikeButton.classList.remove("liked");
}
showDislikeModal(); // Show the dislike modal when the dislike button
is clicked
};
// Review message
const reviewMessage = (reviewButton) => {
showReviewModal();
};
// Show like modal
const showLikeModal = () => {
const modal = document.getElementById("likeModal");
const modalMessage = document.getElementById("likeModalMessage");
const submitLike = document.getElementById("submitLike");
modalMessage.innerText = "You liked this message!";
modal.style.display = "block";
submitLike.onclick = () => {
modal.style.display = "none";
};
};
// Show dislike modal
const showDislikeModal = () => {
const modal = document.getElementById("dislikeModal");
const modalMessage = document.getElementById("dislikeModalMessage");
const submitDislike = document.getElementById("submitDislike");
modalMessage.innerText = "You disliked this message!";
modal.style.display = "block";
submitDislike.onclick = () => {
modal.style.display = "none";
};
};
// Show review modal
const showReviewModal = () => {
const modal = document.getElementById("customModal");
const modalMessage = document.getElementById("modalMessage");
const reviewInput = document.getElementById("reviewInput");
const submitReview = document.getElementById("submitReview");
modalMessage.innerText = "Please leave a review:";
reviewInput.style.display = "block";
submitReview.style.display = "block";
modal.style.display = "block";
submitReview.onclick = () => {
const review = reviewInput.value.trim();
if (review) {
const subject = encodeURIComponent("Review from User");
const body = encodeURIComponent(`Review: ${review}`);
const mailtoLink = `mailto:[email protected]?
subject=${subject}&body=${body}`;
// Open the user's default email client with the pre-filled email
window.location.href = mailtoLink;
modal.style.display = "none";
}
};
};
// Close the modal
const closeModal = (modalId) => {
const modal = document.getElementById(modalId);
modal.style.display = "none";
};
// Add event listener to close button
document.querySelectorAll(".close-button").forEach(button => {
button.addEventListener("click", () => {
closeModal(button.closest(".modal").id);
});
});
// Add event listener to close modal when clicking outside
window.addEventListener("click", (event) => {
const modals = document.querySelectorAll(".modal");
modals.forEach(modal => {
if (event.target === modal) {
closeModal(modal.id);
}
});
});
// Handle file upload
const handleFileUpload = (event) => {
const files = event.target.files;
uploadedFiles = Array.from(files).map(file => ({
name: file.name,
type: file.type,
size: file.size,
data: URL.createObjectURL(file)
}));
// Update the user message with file information
const fileNames = uploadedFiles.map(file => file.name).join(", ");
userMessage = `Uploaded files: ${fileNames}. `;
typingForm.querySelector(".typing-input").value = userMessage;
};
// Handle sending outgoing chat messages
// Handle sending outgoing chat messages
const handleOutgoingChat = () => {
userMessage = typingForm.querySelector(".typing-input").value.trim()
|| userMessage;
if (!userMessage || isResponseGenerating) return; // Exit if there is
no message or response is generating
isResponseGenerating = true;
const html = `<div class="message-content">
<div class="avatar" id="avatarCircle"></div>
<p class="text"></p>
</div>`;
const outgoingMessageDiv = createMessageElement(html, "outgoing");
outgoingMessageDiv.querySelector(".text").innerText = userMessage;
// Set the first letters of the first name and last name inside the
circle
const firstName =
document.getElementById('loggedUserFName').innerText;
const lastName =
document.getElementById('loggedUserLName').innerText;
const avatarCircle =
outgoingMessageDiv.querySelector('#avatarCircle');
avatarCircle.innerText = firstName.charAt(0).toUpperCase() +
lastName.charAt(0).toUpperCase();
chatContainer.appendChild(outgoingMessageDiv);
typingForm.reset(); // Clear input field
document.body.classList.add("hide-header");
chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll to
the bottom
setTimeout(showLoadingAnimation, 500); // Show loading animation
after a delay
// Save the conversation to local storage
const conversations =
JSON.parse(localStorage.getItem("conversations")) || [];
if (currentConversationIndex === -1) {
// If no current conversation, create a new one
conversations.push({
message: userMessage,
timestamp: new Date().toISOString(),
chatContent: chatContainer.innerHTML, // Save the current chat
content
history: conversationHistory // Save the conversation history
});
currentConversationIndex = conversations.length - 1;
} else {
// Update the existing conversation
conversations[currentConversationIndex].chatContent =
chatContainer.innerHTML;
conversations[currentConversationIndex].timestamp = new
Date().toISOString(); // Update the timestamp
conversations[currentConversationIndex].history =
conversationHistory; // Update the conversation history
}
localStorage.setItem("conversations", JSON.stringify(conversations));
localStorage.setItem("saved-chats", chatContainer.innerHTML); // Save
the current chat content to "saved-chats"
};
// Toggle between light and dark themes
toggleThemeButton.addEventListener("click", () => {
const isLightMode = document.body.classList.toggle("light_mode");
localStorage.setItem("themeColor", isLightMode ? "light_mode" :
"dark_mode");
toggleThemeButton.innerText = isLightMode ? "dark_mode" :
"light_mode";
});
// Delete all chats from local storage when button is clicked
deleteChatButton.addEventListener("click", () => {
if (confirm("Are you sure you want to delete all the chats?")) {
localStorage.removeItem("saved-chats");
localStorage.removeItem("conversations");
loadDataFromLocalstorage();
}
});
// Set userMessage and handle outgoing chat when a suggestion is
clicked
suggestions.forEach((suggestion) => {
suggestion.addEventListener("click", () => {
userMessage = suggestion.querySelector(".text").innerText;
handleOutgoingChat();
});
});
// Prevent default form submission and handle outgoing chat
typingForm.addEventListener("submit", (e) => {
e.preventDefault();
handleOutgoingChat();
});
// Handle send button click
sendButton.addEventListener("click", handleOutgoingChat);
// Handle file upload button click
fileUploadButton.addEventListener("change", handleFileUpload);
loadDataFromLocalstorage();
// for the sidebar
const sidebar = document.getElementById("mySidenav");
const mainContent = document.querySelector(".main-content");
function openNav() {
sidebar.classList.add("open");
mainContent.classList.add("sidebar-open");
}
function closeNav() {
sidebar.classList.remove("open");
mainContent.classList.remove("sidebar-open");
}
// Start a new conversation
const newConversationButton = document.getElementById("new-
conversation-btn");
newConversationButton.addEventListener("click", () => {
if (confirm("Are you sure you want to start a new conversation?")) {
// Clear the chat container and last conversation
localStorage.removeItem("saved-chats");
localStorage.removeItem("last-conversation");
currentConversationIndex = -1; // Reset the current conversation
index
conversationHistory = []; // Clear the conversation history
loadDataFromLocalstorage();
}
});
// for textarea for input
const textarea = document.querySelector("textarea");
textarea.addEventListener("keyup", e =>{
textarea.style.height = "45px";
let scHeight = e.target.scrollHeight;
textarea.style.height = `${scHeight}px`;
});
// Reset textarea height when it loses focus
textarea.addEventListener("blur", () => {
setTimeout(() => {
textarea.style.height = "45px";
}, 200); // Adjust the timeout as needed
});
// JavaScript to handle the file upload button click and display the
premium subscription modal
document.getElementById('file-upload').addEventListener('change',
function() {
document.getElementById('premiumModal').style.display = 'block';
});
// JavaScript to close the premium subscription modal
document.querySelector('#premiumModal .close-
button').addEventListener('click', function() {
document.getElementById('premiumModal').style.display = 'none';
});
// JavaScript to close the premium subscription modal when clicking
outside
window.addEventListener('click', function(event) {
const premiumModal = document.getElementById('premiumModal');
if (event.target === premiumModal) {
premiumModal.style.display = 'none';
}
});
// Set the first letters of the first name and last name inside the
circle
const avatarCircle = document.getElementById('avatarCircle');
avatarCircle.innerText = userData.firstName.charAt(0).toUpperCase() +
userData.lastName.charAt(0).toUpperCase();