-
Notifications
You must be signed in to change notification settings - Fork 116
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#360 Add mini chattbot issue fixed , This chatbot gives quike response to the users questions and runs smoothly , @GarimaSingh0109 Add gssoc-ext, Hactoberfest-accepted and level 3 to this PR , Screenrecording https://github.com/user-attachments/assets/bca37898-58ab-4c8a-b418-fcbb76c31819 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a web-based chat interface for waste management chatbot. - Added a chatbot button linking to the new chat interface on the main page. - **Enhancements** - Improved user interface with new styles for the chatbot button and tooltip. - Adjusted the position and appearance of the scroll-to-top button. These changes enhance user interaction and accessibility within the waste management application. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Loading branch information
Showing
4 changed files
with
419 additions
and
2 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,366 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Waste Management-Chat Bot</title> | ||
<link | ||
href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" | ||
rel="stylesheet" | ||
/> | ||
<link | ||
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" | ||
rel="stylesheet" | ||
/> | ||
<link href="Style.css" rel="stylesheet" /> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script> | ||
<link | ||
rel="stylesheet" | ||
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/a11y-dark.min.css" | ||
/> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/12.0.1/marked.min.js"></script> | ||
</head> | ||
<body class="bg-[#1B63AC] flex items-center justify-center min-h-screen"> | ||
<div id="Loader"></div> | ||
<div | ||
class="flex flex-col items-center justify-center w-full max-w-xl space-y-4" | ||
> | ||
<div class="w-full flex justify-center"> | ||
<img | ||
src="bot.jpg" | ||
alt="Chat Bot" | ||
class="h-42 w-42 object-cover" | ||
/> | ||
</div> | ||
|
||
<div class="chat-container w-full bg-white p-4 rounded-lg shadow-md"> | ||
<div id="output-field" class="text-center text-lg font-semibold mb-3"> | ||
How can I help you today? | ||
</div> | ||
<div | ||
id="output-container" | ||
class="mb-3 overflow-auto" | ||
style="max-height: 300px" | ||
></div> | ||
<div class="input-group mb-3"> | ||
<div id="image-preview-container" class="input-group-prepend mr-1"> | ||
<span | ||
id="image-preview" | ||
class="flex items-center" | ||
style="display: none" | ||
> | ||
<img src="" alt="Image preview" class="h-10 mr-2" /> | ||
<button | ||
type="button" | ||
id="clear-image" | ||
class="close text-red-600 text-2xl leading-none" | ||
aria-label="Close" | ||
> | ||
× | ||
</button> | ||
</span> | ||
</div> | ||
<input | ||
type="text" | ||
id="prompt-input" | ||
class="form-control flex-1" | ||
placeholder="Type your prompt here..." | ||
aria-label="Message input" | ||
/> | ||
<button | ||
class="input-group-text bg-gray-200" | ||
id="inputGroupFileAddon" | ||
onclick="document.getElementById('image-input').click();" | ||
> | ||
<svg | ||
xmlns="http://www.w3.org/2000/svg" | ||
width="25" | ||
height="25" | ||
fill="currentColor" | ||
class="bi bi-image" | ||
viewBox="0 0 16 16" | ||
> | ||
<path d="M6.002 5.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0" /> | ||
<path | ||
d="M2.002 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm12 1a1 1 0 0 1 1 1v6.5l-3.777-1.947a.5.5 0 0 0-.577.093l-3.71 3.71-2.66-1.772a.5.5 0 0 0-.63.062L1.002 12V3a1 1 0 0 1 1-1z" | ||
/> | ||
</svg> | ||
</button> | ||
<input type="file" id="image-input" accept="image/*" class="hidden" /> | ||
<button id="generate-btn" class="btn btn-primary">Send</button> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<style> | ||
.chat-container { | ||
width: 100%; | ||
max-width: 500px; | ||
} | ||
|
||
body, | ||
html { | ||
margin: 0; | ||
padding: 0; | ||
background-color: #42c553; /* Optional: to visualize the centering */ | ||
} | ||
</style> | ||
|
||
<script type="importmap"> | ||
{ | ||
"imports": { | ||
"@google/generative-ai": "https://esm.run/@google/generative-ai" | ||
} | ||
} | ||
</script> | ||
|
||
<script type="module"> | ||
import { | ||
GoogleGenerativeAI, | ||
HarmBlockThreshold, | ||
HarmCategory, | ||
} from "@google/generative-ai"; | ||
|
||
const API_KEY = "AIzaSyBF265bY6o63VuPypal-5w0-b7sr0N_O3A"; // Replace with your gemini-api actual API key | ||
const genAI = new GoogleGenerativeAI(API_KEY); | ||
let chat; | ||
|
||
const safetySettings = [ | ||
{ | ||
category: HarmCategory.HARM_CATEGORY_HARASSMENT, | ||
threshold: HarmBlockThreshold.BLOCK_ONLY_HIGH, | ||
}, | ||
]; | ||
|
||
async function fileToGenerativePart(file) { | ||
return new Promise((resolve) => { | ||
const reader = new FileReader(); | ||
reader.onloadend = () => { | ||
const base64Data = reader.result.split(",")[1]; | ||
resolve({ inlineData: { data: base64Data, mimeType: file.type } }); | ||
}; | ||
reader.readAsDataURL(file); | ||
}); | ||
} | ||
|
||
async function sendMessage(prompt, imageParts = []) { | ||
let model; | ||
let result; | ||
clearGreeting(); // Clear the greeting after sending the message | ||
|
||
if (imageParts.length > 0) { | ||
model = genAI.getGenerativeModel({ | ||
model: "gemini-pro-vision", | ||
safetySettings, | ||
}); | ||
} else { | ||
if (!chat) { | ||
chat = await genAI | ||
.getGenerativeModel({ model: "gemini-pro", safetySettings }) | ||
.startChat({ | ||
history: [], | ||
generationConfig: { | ||
maxOutputTokens: 4000, // maxOutputTokens Limit around 4096 | ||
}, | ||
}); | ||
} | ||
model = chat; | ||
} | ||
|
||
try { | ||
if (imageParts.length > 0) { | ||
result = await model.generateContent([prompt, ...imageParts]); | ||
} else { | ||
result = await model.sendMessage(prompt); | ||
} | ||
|
||
const response = await result.response; | ||
if (response) { | ||
const text = await response.text(); | ||
displayMessage(text, "ai"); | ||
} else { | ||
// This block handles a null response, suggesting blocked content | ||
displayMessage( | ||
"This content is not safe for display based on current settings.", | ||
"ai" | ||
); | ||
} | ||
} catch (error) { | ||
console.error("Error during message generation:", error); | ||
displayMessage( | ||
"This content is not safe for display based on current settings. or an internal error.", | ||
"ai" | ||
); | ||
} | ||
clearInputs(); | ||
} | ||
|
||
function displayMessage(message, sender) { | ||
const outputContainer = document.getElementById("output-container"); | ||
const msgDiv = document.createElement("div"); | ||
msgDiv.classList.add( | ||
"chat-message", | ||
sender === "user" ? "user-message" : "ai-message" | ||
); | ||
|
||
if (sender === "ai") { | ||
// Show loading animation for AI messages | ||
msgDiv.innerHTML = | ||
'<div class="loading">' + | ||
'<div class="loading-dot"></div>' + | ||
'<div class="loading-dot"></div>' + | ||
'<div class="loading-dot"></div>' + | ||
"</div>"; | ||
outputContainer.appendChild(msgDiv); | ||
|
||
// Simulate processing delay | ||
setTimeout(() => { | ||
// Clear loading animation | ||
msgDiv.innerHTML = ""; | ||
|
||
if (message.startsWith("```") && message.endsWith("```")) { | ||
// Code block handling | ||
const codeContent = message.substring(3, message.length - 3); | ||
const escapedCode = codeContent | ||
.replace(/</g, "<") | ||
.replace(/>/g, ">"); | ||
msgDiv.innerHTML = `<pre><code class="hljs">${escapedCode}</code></pre>`; | ||
window.hljs.highlightBlock(msgDiv.querySelector("code")); | ||
|
||
// Add Copy button | ||
const copyButton = document.createElement("button"); | ||
copyButton.innerText = "Copy code"; | ||
copyButton.onclick = function () { | ||
navigator.clipboard.writeText(codeContent).then( | ||
() => { | ||
// Change text to show confirmation instead of using alert | ||
copyButton.innerText = "Copied!"; | ||
// Optional: revert the button text back to "Copy code" after 2 seconds | ||
setTimeout(() => { | ||
copyButton.innerText = "Copy code"; | ||
}, 2000); | ||
}, | ||
(err) => { | ||
console.error("Failed to copy text: ", err); | ||
} | ||
); | ||
}; | ||
|
||
msgDiv.appendChild(copyButton); | ||
} else { | ||
// For regular messages | ||
msgDiv.innerHTML = marked.parse(message); | ||
} | ||
|
||
// Scroll the output container to the bottom to ensure the latest message is visible | ||
outputContainer.scrollTop = outputContainer.scrollHeight; | ||
}, 1500); // Adjust the delay as needed | ||
} else { | ||
// User messages are displayed immediately without the loading animation | ||
msgDiv.innerHTML = | ||
message.startsWith("```") && message.endsWith("```") | ||
? `<pre><code class="hljs">${message.substring( | ||
3, | ||
message.length - 3 | ||
)}</code></pre>` | ||
: marked.parse(message); | ||
|
||
// If it's a code block, enable syntax highlighting and add a copy button | ||
if (message.startsWith("```") && message.endsWith("```")) { | ||
const codeBlock = msgDiv.querySelector("pre code"); | ||
window.hljs.highlightBlock(codeBlock); | ||
const copyButton = document.createElement("button"); | ||
copyButton.innerText = "Copy code"; | ||
copyButton.onclick = function () { | ||
navigator.clipboard.writeText(codeBlock.textContent).then( | ||
() => { | ||
alert("Code copied to clipboard!"); | ||
}, | ||
(err) => { | ||
alert("Failed to copy text: ", err); | ||
} | ||
); | ||
}; | ||
msgDiv.appendChild(copyButton); | ||
} | ||
|
||
outputContainer.appendChild(msgDiv); | ||
} | ||
|
||
// Ensure the latest message is visible | ||
outputContainer.scrollTop = outputContainer.scrollHeight; | ||
} | ||
|
||
function clearInputs() { | ||
document.getElementById("prompt-input").value = ""; | ||
document.getElementById("image-input").value = ""; | ||
clearImagePreview(); | ||
} | ||
|
||
document | ||
.getElementById("generate-btn") | ||
.addEventListener("click", async () => { | ||
const prompt = document.getElementById("prompt-input").value; | ||
const files = document.getElementById("image-input").files; | ||
const imageParts = await Promise.all( | ||
[...files].map(fileToGenerativePart) | ||
); | ||
if (prompt.trim() !== "") { | ||
displayMessage(prompt, "user"); | ||
await sendMessage(prompt, imageParts); | ||
} | ||
}); | ||
|
||
function clearGreeting() { | ||
const outputField = document.getElementById("output-field"); | ||
if (outputField) { | ||
outputField.style.display = "none"; // Hide the field completely | ||
} | ||
} | ||
|
||
document | ||
.getElementById("image-input") | ||
.addEventListener("change", function (event) { | ||
const [file] = event.target.files; | ||
if (file) { | ||
const reader = new FileReader(); | ||
reader.onload = function (e) { | ||
const previewContainer = document.getElementById("image-preview"); | ||
const previewImage = | ||
previewContainer.getElementsByTagName("img")[0]; | ||
previewImage.src = e.target.result; | ||
previewContainer.style.display = "flex"; | ||
}; | ||
reader.readAsDataURL(file); | ||
} | ||
}); | ||
|
||
document | ||
.getElementById("clear-image") | ||
.addEventListener("click", function () { | ||
// Clear the preview | ||
const previewContainer = document.getElementById("image-preview"); | ||
const previewImage = previewContainer.getElementsByTagName("img")[0]; | ||
previewImage.src = ""; | ||
previewContainer.style.display = "none"; | ||
// Clear the file input | ||
document.getElementById("image-input").value = ""; | ||
}); | ||
|
||
function clearImagePreview() { | ||
const previewContainer = document.getElementById("image-preview"); | ||
if (previewContainer) { | ||
const previewImage = previewContainer.getElementsByTagName("img")[0]; | ||
previewImage.src = ""; | ||
previewContainer.style.display = "none"; | ||
} | ||
} | ||
</script> | ||
<script> | ||
var loader = document.getElementById("Loader"); | ||
window.addEventListener("load", function () { | ||
loader.style.display = "none"; | ||
}); | ||
</script> | ||
</body> | ||
</html> |
Oops, something went wrong.