-
Notifications
You must be signed in to change notification settings - Fork 364
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of https://github.com/Bhum-ika/BuddyTrail into ed…
…itReviewSection
- Loading branch information
Showing
11 changed files
with
1,003 additions
and
9 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,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" | ||
> | ||
× | ||
</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, "<") | ||
.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.