Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/Bhum-ika/BuddyTrail into ed…
Browse files Browse the repository at this point in the history
…itReviewSection
  • Loading branch information
Bhum-ika committed Oct 7, 2024
2 parents 48a08ce + 774ea33 commit 107a778
Show file tree
Hide file tree
Showing 11 changed files with 1,003 additions and 9 deletions.
Binary file added boy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added chatbot.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
367 changes: 367 additions & 0 deletions chatbot.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,367 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>canvas Editor- Chat Bot</title>
<link rel="icon" href="images/Screenshot (97).png" type="image/png" />
<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="boy.png"
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"
>
&times;
</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: #1b63ac; /* 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, "&lt;")
.replace(/>/g, "&gt;");
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>
Loading

0 comments on commit 107a778

Please sign in to comment.