myemma / index.html
lroggendorff's picture
Reduce width of iframe in embed code.
3fe3ba2 verified
raw
history blame
7.71 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Emma's Genie</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
min-height: 100vh;
margin: 0;
font-family: "Inter", system-ui, -apple-system, sans-serif;
background: linear-gradient(135deg, #f6f8fb 0%, #e9eef5 100%);
}
.chat-container {
width: 100%;
max-width: 400px;
border-radius: 16px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12),
0 2px 8px rgba(0, 0, 0, 0.08);
overflow: hidden;
display: flex;
flex-direction: column;
background-color: white;
height: 600px;
transition: transform 0.2s ease;
}
.chat-container:hover {
transform: translateY(-2px);
}
.messages {
flex-grow: 1;
padding: 20px;
overflow-y: auto;
background-color: #ffffff;
scroll-behavior: smooth;
}
.messages::-webkit-scrollbar {
width: 6px;
}
.messages::-webkit-scrollbar-thumb {
background-color: #cbd5e1;
border-radius: 3px;
}
.message {
margin-bottom: 16px;
max-width: 80%;
padding: 12px 16px;
border-radius: 12px;
font-size: 14px;
line-height: 1.5;
animation: fadeIn 0.3s ease;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.message.user {
margin-left: auto;
background-color: #2563eb;
color: white;
border-bottom-right-radius: 4px;
}
.message.ai {
background-color: #f3f4f6;
color: #1f2937;
border-bottom-left-radius: 4px;
}
.typing-indicator {
margin-bottom: 16px;
padding: 12px 16px;
background-color: #f3f4f6;
border-radius: 12px;
border-bottom-left-radius: 4px;
width: fit-content;
}
.typing-indicator span {
display: inline-block;
width: 8px;
height: 8px;
background-color: #94a3b8;
border-radius: 50%;
margin-right: 4px;
animation: bounce 1.4s infinite ease-in-out;
}
.typing-indicator span:nth-child(1) {
animation-delay: -0.32s;
}
.typing-indicator span:nth-child(2) {
animation-delay: -0.16s;
}
.typing-indicator span:nth-child(3) {
animation-delay: 0s;
}
@keyframes bounce {
0%,
80%,
100% {
transform: translateY(0);
}
40% {
transform: translateY(-6px);
}
}
@keyframes subtleBounce {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-1px);
}
}
.subtle-bounce {
animation: subtleBounce 0.1s ease;
}
#chat-form {
display: flex;
padding: 16px;
gap: 8px;
background-color: #fff;
border-top: 1px solid #eef2f6;
}
#user-input {
flex-grow: 1;
padding: 12px 16px;
border: 2px solid #e5e7eb;
border-radius: 8px;
font-size: 14px;
transition: border-color 0.2s ease;
outline: none;
}
#user-input:focus {
border-color: #2563eb;
}
button {
padding: 12px 24px;
background-color: #2563eb;
color: white;
border: none;
border-radius: 8px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
}
button:hover {
background-color: #1d4ed8;
transform: translateY(-1px);
}
button:active {
transform: translateY(0);
}
#copy-iframe-btn {
margin-top: 20px;
cursor: pointer;
color: #6b7280;
font-size: 14px;
display: inline-flex;
align-items: center;
transition: all 0.3s ease;
}
#copy-iframe-btn:hover {
background-color: rgba(0, 0, 0, 0.1);
color: #2563eb;
padding: 4px;
border-radius: 4px;
}
@media (width <= 300px) {
.chat-container {
border-radius: 16px;
}
}
</style>
</head>
<body>
<div id="app">
<div class="chat-container" id="chat-container">
<div id="messages" class="messages"></div>
<form id="chat-form">
<input
type="text"
id="user-input"
placeholder="Ask anything.."
autocomplete="off"
required
/>
<button type="submit">Send</button>
</form>
</div>
</div>
<div id="copy-iframe-btn"><img src="https://cdn-icons-png.flaticon.com/512/10146/10146565.png" style="width: 21px; padding-right: 4px; filter: opacity(0.6);">Copy embed code</div>
<script type="module">
import { Client } from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js";
document.addEventListener("DOMContentLoaded", async () => {
const chatContainer = document.getElementById("chat-container");
const messagesDiv = document.getElementById("messages");
const chatForm = document.getElementById("chat-form");
const userInput = document.getElementById("user-input");
const client = await Client.connect("nroggendorff/not-my-emma");
chatForm.addEventListener("submit", async (e) => {
e.preventDefault();
const userMessage = userInput.value;
if (!userMessage) return;
userInput.value = "";
addMessage(userMessage, "user");
const typingIndicator = document.createElement("div");
typingIndicator.className = "typing-indicator";
typingIndicator.innerHTML = `
<span></span>
<span></span>
<span></span>
`;
messagesDiv.appendChild(typingIndicator);
messagesDiv.scrollTop = messagesDiv.scrollHeight;
try {
const result = await client.predict("/chat", {
message: userMessage,
});
typingIndicator.remove();
addMessage(result.data, "ai");
} catch (error) {
typingIndicator.remove();
addMessage("Sorry, I encountered an error. Please try again.", "ai");
}
});
function addMessage(message, sender) {
const messageElement = document.createElement("div");
messageElement.classList.add("message", sender);
messageElement.textContent = message;
messagesDiv.appendChild(messageElement);
messagesDiv.scrollTop = messagesDiv.scrollHeight;
}
userInput.addEventListener("input", () => {
chatContainer.classList.add("subtle-bounce");
setTimeout(() => chatContainer.classList.remove("subtle-bounce"), 100);
});
const copyButton = document.getElementById("copy-iframe-btn");
copyButton.addEventListener("click", () => {
const iframeCode = `<iframe src="https://emma.eduzs.link" width="300" height="600" frameborder="0" scrolling="no"></iframe>`;
navigator.clipboard.writeText(iframeCode).then(() => {
alert("Embed code copied to clipboard!");
});
});
});
</script>
</body>
</html>