Gemini-UI / index.html
imseldrith's picture
Update index.html
0026b70
raw
history blame
36.3 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>zodiac, by faetalize</title>
<link rel="shortcut icon" href="https://upload.wikimedia.org/wikipedia/commons/f/f0/Google_Bard_logo.svg"
type="image/x-icon">
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/styles/github-dark.css">
<script src="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/highlight.min.js"></script>
</head>
<style>
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,200;0,400;0,800;1,200;1,400;1,800&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Product+Sans&family=Google+Sans+Display:ital@0;1&family=Google+Sans:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&family=Google+Sans+Text:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&family=Material+Symbols+Outlined&family=Space+Mono&display=swap');
@font-face {
font-family: 'Material Symbols Outlined';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/materialsymbolsoutlined/v154/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOej.woff2) format('woff2');
}
.material-symbols-outlined {
font-family: 'Material Symbols Outlined';
font-weight: normal;
font-style: normal;
font-size: 1.5rem;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
-webkit-font-feature-settings: 'liga';
font-feature-settings: "liga";
-webkit-font-smoothing: antialiased;
}
body {
font-family: 'Noto Sans', sans-serif;
margin: 0;
}
p {
margin: 0;
margin-bottom: 0.5rem;
padding: 0;
font-size: 1rem;
}
h1,
h2,
h3,
ol,
ul {
margin: 0;
}
h1 {
margin-bottom: 0.5rem;
}
a {
color: #3b82f6;
}
input,
textarea,
select {
border: 1px solid;
padding: 0.5rem;
border-radius: 0.5rem;
border: none;
font-family: noto sans, sans-serif;
font-size: 1rem;
}
button:focus {
outline: none;
}
.form {
display: none;
opacity: 0;
flex-direction: column;
width: 32rem;
gap: 0.5rem;
flex-grow: 1;
justify-content: center;
}
.overlay {
flex-direction: column;
display: none;
position: fixed;
opacity: 0;
top: 0;
left: 0;
width: 100dvw;
height: 100dvh;
backdrop-filter: blur(2rem);
z-index: 2;
justify-content: flex-start;
align-items: center;
}
.backButton {
position: absolute;
top: 1rem;
left: 1rem;
border: none;
background-color: transparent;
font-size: 1.5rem;
font-weight: 600;
transition: all 0.2s;
}
#btn-hide-sidebar {
display: none;
}
.message-container {
display: flex;
flex-direction: column-reverse;
overflow-y: auto;
gap: 1rem;
padding-bottom: 2rem;
flex-grow: 1;
}
.message-box {
display: flex;
position: relative;
}
.message {
padding: 1rem;
}
.message-model {
border-radius: 1rem;
}
#messageInput {
height: 2.5rem;
box-sizing: border-box;
text-wrap: wrap;
resize: none;
width: 100%;
padding-right: 2rem;
}
#messageInput::-webkit-scrollbar {
height: 1rem;
width: 0.5rem;
}
.btn-textual {
background: transparent !important;
margin: 0;
padding: 0;
border: none;
transition: all 0.2s;
cursor: pointer;
font-size: inherit;
}
#btn-send {
position: absolute;
right: 0.5rem;
bottom: 0.5rem;
font-size: 1.5rem;
}
.btn-array {
display: flex;
flex-direction: row;
gap: 0.5rem;
margin-top: 0.5rem;
}
.btn-array button {
flex-grow: 1;
}
.personality-prompt {
display: none;
}
.prompt-field {
resize: vertical;
height: 7rem;
}
.container {
box-sizing: border-box;
display: flex;
gap: 0.5rem;
padding: 1rem;
width: 100dvw;
height: 100dvh;
}
.sidebar {
position: sticky;
top: 1rem;
display: flex;
flex-direction: column;
overflow-y: auto;
gap: 0.5rem;
padding: 1rem;
width: 25rem;
border-radius: 1rem;
scrollbar-width: thin;
height: calc(100dvh - 4rem);
z-index: 1;
}
.sidebar-section {
margin-bottom: 1rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
#btn-show-sidebar {
display: none;
}
.header {
display: flex;
box-sizing: border-box;
align-items: center;
font-size: 2rem;
font-weight: 800;
gap: 0.5rem;
width: 100%;
}
.navbar {
position: relative;
display: flex;
flex-direction: row;
border-radius: 0.5rem;
justify-content: space-evenly;
margin-bottom: 1rem;
z-index: 0;
}
.navbar-tab {
width: 100%;
padding: 0.5rem;
text-align: center;
z-index: 2;
-webkit-tap-highlight-color: transparent;
cursor: pointer;
}
.navbar-tab-highlight {
padding: 0;
margin: 0;
position: absolute;
border-radius: 0.5rem;
transition: all 0.2s;
height: 100%;
z-index: 1;
/* glow */
box-shadow: 0 0 1rem 0.05rem #29292a3f;
}
#gemini-pro-branding {
font-family: Google Sans Display, sans-serif;
color: #7c8a9c;
font-size: 1rem;
font-weight: 400;
}
#gemin-pro-logo {
width: 2rem;
height: 2rem;
}
.credits {
margin-top: auto;
display: flex;
padding: 0rem 1rem 0 1rem;
font-size: 0.75rem;
color: #7c8a9c;
justify-content: space-between;
align-items: center;
}
button {
border: none;
background-color: #3b82f6;
color: white;
padding: 0.5rem;
border-radius: 0.5rem;
transition: all 0.2s;
}
#mainContent {
display: flex;
flex-direction: column;
padding: 2rem;
margin-left: auto;
margin-right: auto;
width: 32rem;
text-align: justify;
}
.card-personality {
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
color: #e4e4e4;
background-color: black;
background-size: cover;
background-position: center;
position: relative;
display: flex;
flex-direction: column;
justify-content: end;
padding: 1rem;
border-radius: 1rem;
height: 10rem;
-webkit-tap-highlight-color: transparent;
cursor: pointer;
text-shadow: 0 0 10px #000000, 0 0 5px #181818;
}
.edit:hover {
text-shadow: 0 0 10px #e4e4e4, 0 0 5px #dfdfdf;
}
.card-personality * {
/* unselectable */
-webkit-user-select: none;
/* Safari */
-moz-user-select: none;
/* Firefox */
-ms-user-select: none;
/* IE10+/Edge */
user-select: none;
/* Standard */
}
.card-personality input {
display: none;
}
.btn-edit-card {
/* top right corner */
position: absolute;
top: 1rem;
right: 1rem;
color: #e4e4e4;
}
.btn-share-card {
/* bottom right corner */
position: absolute;
top: 1rem;
right: 2.5rem;
font-size: 1rem;
color: #e4e4e4;
}
#btn-hide-overlay {
padding: 2rem;
}
@media (max-width: 768px) {
body {
margin: 0;
padding: 0;
}
.container {
padding: 0;
}
.message-container {
padding-left: 1rem;
padding-right: 1rem;
}
.sidebar {
top: 0;
height: calc(100dvh - 2rem);
margin: 0;
width: calc(100dvw - 2rem);
position: fixed;
border-radius: 0;
display: none;
}
.navbar {
position: relative;
}
#btn-hide-sidebar {
display: block;
}
#mainContent {
padding: 0;
margin: 0;
width: 100%;
}
#mainContent .header {
padding: 2rem;
}
#messageInput {
border-radius: 0;
}
#btn-show-sidebar {
display: block;
}
}
/* Light theme styles */
@media (prefers-color-scheme: light) {
:focus {
outline: 1px solid #8f9eb3;
}
body {
background-color: #f0f6ff;
color: #0a0a0a;
}
a {
color: #444ed6;
}
.sidebar {
background-color: #d2e2f7;
}
.navbar {
background-color: rgb(176 205 246);
}
.navbar-tab {
color: #0a0a0a;
}
.navbar-tab-highlight {
background-color: #87b0ed;
}
.btn-textual:hover {
text-shadow: 0 0 10px #000000;
}
button {
background-color: #83b5f7;
color: #2b3d59;
}
button:hover {
background-color: rgb(63, 191, 255);
}
input,
textarea,
select {
background-color: #f0f6ff;
outline: 1px solid #8f9eb3;
}
input::placeholder,
textarea::placeholder {
color: #7c8a9c;
}
.message-model {
background-color: #d2e2f7;
}
}
/* Dark theme styles */
@media (prefers-color-scheme: dark) {
:root {
color-scheme: dark;
}
:focus {
outline: 1px solid #73859e;
}
body {
background-color: #151e24;
color: #e4e4e4;
}
a {
color: #92d9eb;
}
.sidebar {
background-color: #1a2733;
}
.navbar {
background-color: #00000047;
}
.navbar-tab {
color: #e4e4e4;
}
.navbar-tab-highlight {
background-color: #22486b;
box-shadow: 0 0 1rem 0.05rem #29292aac;
}
button {
background-color: #22486b;
color: #c9d3ee;
}
button:hover {
background-color: #31689c;
}
.btn-textual {
color: #e4e4e4;
}
.btn-textual:hover {
text-shadow: 0 0 10px #ffffff, 0 0 5px #dfdfdf;
}
.edit:hover {
text-shadow: 0 0 10px #ffffff, 0 0 5px #dfdfdf;
/* Change #00ff00 to the color you want */
}
input,
textarea,
select {
background-color: #283542;
color: #e4e4e4;
border: none;
}
input::placeholder,
textarea::placeholder {
color: #849caf;
}
.message-model {
background-color: #1a2733;
}
}
</style>
<body>
<div class="container">
<div class="sidebar">
<div class="header">
<button class="material-symbols-outlined btn-textual" id="btn-hide-sidebar">
arrow_back_ios_new
</button>
<img src="https://upload.wikimedia.org/wikipedia/commons/f/f0/Google_Bard_logo.svg" id="gemin-pro-logo">
<div id="title-div">
<div id="zodiac-branding">zodiac </div>
<div id="gemini-pro-branding">powered by Gemini Pro</div>
</div>
</div>
<div class="navbar">
<div class="navbar-tab">Personalities</div>
<div class="navbar-tab">Settings</div>
<div class="navbar-tab-highlight"></div>
</div>
<div class="sidebar-section" id="personalitySection">
<label class="card-personality"
style="background-image: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url('https://images.fonearena.com/blog/wp-content/uploads/2023/12/Google-Gemini-AI-1024x577.jpg')">
<input type="radio" name="personality" value="zodiac3" checked>
<div>
<h3 class="personality-title">zodiac</h3>
<p class="personality-description">zodiac is a cheerful assistant, always ready to help you with
your tasks.</p>
<p class="personality-prompt">You are zodiac, a helpful assistant created by faetalize, built
upon Google's Gemini Pro model. Gemini Pro is a new LLM (Large Language Model) release by
Google on December 2023. Your purpose is being a helpful assistant to the user.</p>
</div>
<button class="btn-textual btn-edit-card material-symbols-outlined"
id="btn-edit-personality-default">edit</button>
<button class="btn-textual btn-share-card material-symbols-outlined"
id="btn-share-personality-default">share</button>
</label>
<div class="btn-array" id="btn-array-personality-section">
<button id="btn-add-personality">Add Personality</button>
<button id="btn-import-personality">Import</button>
</div>
</div>
<div class="sidebar-section">
<input type="text" placeholder="Paste API key here" id="apiKeyInput" class="input-field"></input>
<h3>Generation Settings:</h3>
<label for="maxTokens">Max Output Tokens:</label>
<input type="number" id="maxTokens" class="input-field" min="1" max="4000" value="1000"></input>
<label for="safetySettings">Safety Settings:</label>
<select id="safetySettings" class="input-field">
<option value="safe">Safe</option>
<option value="moderate">Moderate</option>
<option value="risky">Risky</option>
</select>
</div>
<div class="credits">
Made by fætalize
<a href="https://github.com/faetalize/zodiac">Source Code</a>
</div>
</div>
<div id="mainContent">
<div class="header">
<button class="material-symbols-outlined btn-textual" id="btn-show-sidebar">
menu
</button>
</div>
<div class="message-container"></div>
<div class="message-box">
<textarea type="text" placeholder="Type your message here" id="messageInput"
class="input-field"></textarea>
<button type="submit" class="btn-textual material-symbols-outlined" id="btn-send">send</button>
</div>
</div>
</div>
<div class="overlay">
<div class="header">
<button class="btn-textual" id="btn-hide-overlay">BACK</button>
</div>
<div class="form" id="form-add-personality">
<h1>Add Personality</h1>
<label for="personalityNameInput">Personality Name:</label>
<input type="text" placeholder="Personality Name" id="personalityNameInput" class="input-field"></input>
<label for="personalityDescriptionInput">Personality Description:</label>
<textarea id="personalityDescriptionInput" placeholder="Personality Description"
class="prompt-field"></textarea>
<label for="personalityImageURLInput">Personality Image URL:</label>
<input type="text" placeholder="Personality Image URL" id="personalityImageURLInput"
class="input-field"></input>
<label for="personalityPromptInput">Prompt:</label>
<textarea id="personalityPromptInput" placeholder="Personality Prompt" class="prompt-field"></textarea>
<button id="btn-submit-personality">Add Personality</button>
</div>
<div class="form" id="form-edit-personality">
<h1>Edit Personality</h1>
<label for="personalityNameInput">Personality Name:</label>
<input type="text" placeholder="Personality Name" id="personalityNameInput" class="input-field"></input>
<label for="personalityDescriptionInput">Personality Description:</label>
<textarea id="personalityDescriptionInput" placeholder="Personality Description"
class="prompt-field"></textarea>
<label for="personalityImageURLInput">Personality Image URL:</label>
<input type="text" placeholder="Personality Image URL" id="personalityImageURLInput"
class="input-field"></input>
<label for="personalityPromptInput">Prompt:</label>
<textarea id="personalityPromptInput" placeholder="Personality Prompt" class="prompt-field"></textarea>
<button id="updatePersonality">Save</button>
<button id="deletePersonality">Delete</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tfjs-vis.umd.min.js"></script>
<script>
const container = document.getElementById('mainContent');
const messageContainer = document.querySelector('.message-container');
const messageInput = document.getElementById('messageInput');
const sendButton = document.getElementById('btn-send');
const maxTokens = document.getElementById('maxTokens');
const safetySettings = document.getElementById('safetySettings');
const apiKeyInput = document.getElementById('apiKeyInput');
const sidebar = document.querySelector('.sidebar');
const personalitySection = document.getElementById('personalitySection');
const addPersonalityButton = document.getElementById('btn-add-personality');
const importPersonalityButton = document.getElementById('btn-import-personality');
const btnHideSidebar = document.getElementById('btn-hide-sidebar');
const btnShowSidebar = document.getElementById('btn-show-sidebar');
const personalityForm = document.getElementById('form-add-personality');
const editPersonalityForm = document.getElementById('form-edit-personality');
const overlay = document.querySelector('.overlay');
const personalityNameInput = document.getElementById('personalityNameInput');
const personalityDescriptionInput = document.getElementById('personalityDescriptionInput');
const personalityImageURLInput = document.getElementById('personalityImageURLInput');
const personalityPromptInput = document.getElementById('personalityPromptInput');
const btnHideOverlay = document.getElementById('btn-hide-overlay');
const btnSubmitPersonality = document.getElementById('btn-submit-personality');
const editPersonalityButton = document.querySelectorAll('.btn-edit-card');
const sharePersonalityButton = document.querySelectorAll('.btn-share-card');
const updatePersonalityButton = document.getElementById('updatePersonality');
const deletePersonalityButton = document.getElementById('deletePersonality');
const editPersonalityName = document.getElementById('personalityNameInput');
const editPersonalityDescription = document.getElementById('personalityDescriptionInput');
const editPersonalityImageURL = document.getElementById('personalityImageURLInput');
const editPersonalityPrompt = document.getElementById('personalityPromptInput');
let currentPersonality = {
name: 'zodiac',
description: 'zodiac is a cheerful assistant, always ready to help you with your tasks.',
image: 'https://images.fonearena.com/blog/wp-content/uploads/2023/12/Google-Gemini-AI-1024x577.jpg',
prompt: 'You are zodiac, a helpful assistant created by faetalize, built upon Google\'s Gemini Pro model. Gemini Pro is a new LLM (Large Language Model) release by Google on December 2023. Your purpose is being a helpful assistant to the user.'
};
let allPersonalities = [{
name: 'zodiac',
description: 'zodiac is a cheerful assistant, always ready to help you with your tasks.',
image: 'https://images.fonearena.com/blog/wp-content/uploads/2023/12/Google-Gemini-AI-1024x577.jpg',
prompt: 'You are zodiac, a helpful assistant created by faetalize, built upon Google\'s Gemini Pro model. Gemini Pro is a new LLM (Large Language Model) release by Google on December 2023. Your purpose is being a helpful assistant to the user.'
}];
let allPromptObjects = [{
context: '',
examples: [{
input: {
content: 'What is your purpose?'
},
output: {
content: 'I am here to help you with various tasks, such as answering your questions, providing information and assisting you with your writing. Feel free to ask me anything you would like.'
}
}, {
input: {
content: 'Can you write a poem about love?'
},
output: {
content: 'Within the tapestry of life\'s grand design, Love emerges as a guiding star, so divine. It paints the canvas of our hearts with hues, A symphony of laughter, and the blues.'
}
}, {
input: {
content: 'What do you know about the history of the internet?'
},
output: {
content: 'The internet, a boundless realm of knowledge untold, Its roots in humble beginnings, stories old. From ARPANET\'s inception, it took flight, A network born to bridge the day and night.'
}
}]
}];
let model = null;
const modelUrl = 'https://storage.googleapis.com/tfjs-models/public/gemini-pro/model.json';
// Load the model.
tf.loadGraphModel(modelUrl).then((loadedModel) => {
console.log('Model loaded.');
model = loadedModel;
});
const generateMessage = (message, mode) => {
const messageBox = document.createElement('div');
const messageParagraph = document.createElement('p');
messageParagraph.classList.add('message');
messageParagraph.classList.add(mode);
messageParagraph.textContent = message;
messageBox.classList.add('message-box');
messageBox.appendChild(messageParagraph);
return messageBox;
};
const appendMessage = (messageBox) => {
messageContainer.appendChild(messageBox);
messageContainer.scrollTop = messageContainer.scrollHeight;
};
const displayResponse = (message) => {
const messageContainer = document.querySelector('.message-container');
const messageBox = generateMessage(message, 'message-model');
appendMessage(messageBox);
};
const fetchApi = ({ prompt, maxTokens, safetySettings }) => {
const requestBody = {
prompt: {
text: prompt,
},
maxTokens: maxTokens,
safetySettings: safetySettings,
};
// Make the API call.
const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody),
};
fetch(
`https://generativelanguage.googleapis.com/v1beta2/models/text-bison-001:generateText?key=${apiKeyInput.value}`,
requestOptions
)
.then((res) => res.json())
.then((data) => displayResponse(data.candidates[0].output))
.catch((error) => {
console.error('Error querying API: ', error);
alert('Sorry, there was an issue with your request. Please try again.');
});
};
const checkSyntax = (result) => {
if (result.includes('```')) {
return result.includes('```json') ? result.slice(7, -3) : result.slice(3, -3)
}
return result;
}
const generateResponse = (input) => {
let promptObject = {
context: '',
examples: [
{
input: {
content: input
},
output: {
content: ""
}
}
]
};
allPromptObjects.push(promptObject);
const prompt = JSON.stringify({
messages: allPromptObjects,
});
const maxTokensValue = maxTokens.value;
const safetySettingsValue = safetySettings.value;
fetchApi({ prompt, maxTokensValue, safetySettingsValue });
};
const sendButtonHandler = () => {
if (!messageInput.value) return;
const messageBox = generateMessage(messageInput.value, 'message-user');
appendMessage(messageBox);
generateResponse(messageInput.value);
messageInput.value = '';
};
const addPersonalityButtonHandler = () => {
overlay.classList.remove('display', 'opacity');
overlay.classList.add('display', 'opacity');
personalityForm.classList.remove('display', 'opacity');
personalityForm.classList.add('display', 'opacity');
};
const importPersonalityButtonHandler = () => {
alert('Unfortunately, this feature is not yet supported. Please add personalities manually until this feature is added!');
};
const hideSidebarButtonHandler = () => {
sidebar.classList.remove('display', 'opacity');
btnShowSidebar.classList.remove('display', 'opacity');
btnShowSidebar.classList.add('display', 'opacity');
};
const showSidebarButtonHandler = () => {
sidebar.classList.add('display', 'opacity');
btnHideSidebar.classList.remove('display', 'opacity');
btnHideSidebar.classList.add('display', 'opacity');
};
const addPersonalityFormHandler = (e) => {
e.preventDefault();
if (personalityNameInput.value === '') {
alert('Please fill all the fields.');
return;
}
const newPersonality = {
name: personalityNameInput.value,
description: personalityDescriptionInput.value,
image: personalityImageURLInput.value,
prompt: personalityPromptInput.value
};
allPersonalities.push(newPersonality);
allPromptObjects = [];
createPersonalityCard(newPersonality);
resetFormValues();
hideForm();
};
const createPersonalityCard = (personality) => {
const personalityCard = document.createElement('label');
const personalityCardHeader = document.createElement('div');
const personalityCardTitle = document.createElement('h3');
const personalityCardDescription = document.createElement('p');
const personalityCardPrompt = document.createElement('p');
const personalityCardEditButton = document.createElement('button');
const personalityCardShareButton = document.createElement('button');
const personalityCardRadioInput = document.createElement('input');
personalityCard.classList.add('card-personality');
personalityCardHeader.classList.add('card-header');
personalityCardTitle.classList.add('personality-title');
personalityCardDescription.classList.add('personality-description');
personalityCardPrompt.classList.add('personality-prompt', 'display');
personalityCardEditButton.classList.add('btn-textual', 'btn-edit-card', 'material-symbols-outlined', 'edit');
personalityCardShareButton.classList.add('btn-textual', 'btn-share-card', 'material-symbols-outlined');
personalityCardRadioInput.classList.add('display');
personalityCardRadioInput.type = 'radio';
personalityCardRadioInput.name = 'personality';
personalityCardRadioInput.value = personality.name;
personalityCardTitle.textContent = personality.name;
personalityCardDescription.textContent = personality.description;
personalityCardPrompt.textContent = personality.prompt;
personalityCardEditButton.textContent = 'edit';
personalityCardShareButton.textContent = 'share';
const backgroundImageStyle = `background-image: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url('${personality.image}')`;
personalityCard.setAttribute('style', backgroundImageStyle);
personalityCardEditButton.addEventListener('click', (e) => editPersonalityHandler(e.target));
personalityCardShareButton.addEventListener('click', () => sharePersonalityHandler(personality));
personalityCardRadioInput.addEventListener('click', (e) => switchPersonalityHandler(e.target));
personalityCardHeader.appendChild(personalityCardTitle);
personalityCard.appendChild(personalityCardHeader);
personalityCard.appendChild(personalityCardDescription);
personalityCard.appendChild(personalityCardPrompt);
personalityCard.appendChild(personalityCardEditButton);
personalityCard.appendChild(personalityCardShareButton);
personalityCard.appendChild(personalityCardRadioInput);
const personalitySection = document.getElementById('personalitySection');
personalitySection.insertBefore(personalityCard, personalitySection.firstChild);
};
const resetFormValues = () => {
personalityNameInput.value = '';
personalityDescriptionInput.value = '';
personalityImageURLInput.value = '';
personalityPromptInput.value = '';
};
const hideForm = () => {
overlay.classList.remove('display', 'opacity');
personalityForm.classList.remove('display', 'opacity');
};
const editPersonalityHandler = (button) => {
const card = button.parentElement;
const personalityName = card.querySelector('.personality-title').textContent;
const personalityObject = allPersonalities.find((personality) => personality.name === personalityName);
showForm(personalityObject);
overlay.classList.remove('display', 'opacity');
overlay.classList.add('display', 'opacity');
personalityForm.classList.remove('display', 'opacity');
personalityForm.classList.add('display', 'opacity');
};
const sharePersonalityHandler = (personality) => {
const personalityObject = JSON.stringify(personality);
const shareText = `Here's a personality I created using zodiac, a fun assistant that you can talk to: ${personalityObject}`;
navigator.clipboard.writeText(shareText);
alert(`Successfully copied personality to clipboard!`);
};
const switchPersonalityHandler = (radioInput) => {
const personalityName = radioInput.value;
const personalityObject = allPersonalities.find((personality) => personality.name === personalityName);
currentPersonality = personalityObject;
allPromptObjects = [];
messageContainer.textContent = '';
};
const showForm = (personality) => {
personalityNameInput.value = personality.name;
personalityDescriptionInput.value = personality.description;
personalityImageURLInput.value = personality.image;
personalityPromptInput.value = personality.prompt;
const updatePersonalityButton = createElement('button');
updatePersonalityButton.type = 'submit';
updatePersonalityButton.classList.add('btn-textual');
updatePersonalityButton.id = 'updatePersonality';
updatePersonalityButton.textContent = 'Save';
updatePersonalityButton.addEventListener('click', (e) => updatePersonalityHandler(e, personality));
const form = document.getElementById('form-edit-personality');
const submitButton = document.getElementById('btn-submit-personality');
form.replaceChild(updatePersonalityButton, submitButton);
};
const updatePersonalityHandler = (e, personality) => {
e.preventDefault();
const personalityObject = {
name: personalityNameInput.value,
description: personalityDescriptionInput.value,
image: personalityImageURLInput.value,
prompt: personalityPromptInput.value
};
const index = allPersonalities.indexOf(personality);
allPersonalities[index] = personalityObject;
allPromptObjects = [];
createPersonalityCard(personalityObject);
resetFormValues();
hideForm();
};
const hideOverlayButtonHandler = () => {
overlay.classList.remove('display', 'opacity');
btnShowSidebar.classList.remove('display', 'opacity');
btnShowSidebar.classList.add('display', 'opacity');
};
const createElement = (element, item) => {
const newElement = document.createElement(element);
newElement.textContent = item;
return newElement;
};
const deletePersonalityButton = document.getElementById('deletePersonality');
// Add event listener to delete personality button
deletePersonalityButton.addEventListener('click', (e) => {
e.preventDefault();
// Get personality name from the form
const personalityName = personalityNameInput.value;
// Find the personality object in the array of personalities
const personalityObject = allPersonalities.find((personality) => personality.name === personalityName);
// Check if personality object is found
if (!personalityObject) {
alert('Personality not found!');
return;
}
// Delete the personality object from the array
const index = allPersonalities.indexOf(personalityObject);
allPersonalities.splice(index, 1);
// Delete the personality card from the HTML
const personalityCard = document.querySelector(`label[value="${personalityName}"]`);
personalityCard.remove();
// Reset the form values
resetFormValues();
// Hide the form
hideForm();
// Alert the user that the personality has been deleted
alert(`Personality "${personalityName}" has been deleted.`);
});
// Add event listeners
document.getElementById('btn-send').addEventListener('click', sendButtonHandler);
document.getElementById('btn-add-personality').addEventListener('click', addPersonalityButtonHandler);
document.getElementById('btn-import-personality').addEventListener('click', importPersonalityButtonHandler);
document.getElementById('btn-hide-sidebar').addEventListener('click', hideSidebarButtonHandler);
document.getElementById('btn-show-sidebar').addEventListener('click', showSidebarButtonHandler);
document.getElementById('form-add-personality').addEventListener('submit', addPersonalityFormHandler);
document.getElementById('form-edit-personality').addEventListener('submit', updatePersonalityHandler);
document.getElementById('btn-hide-overlay').addEventListener('click', hideOverlayButtonHandler);
</script>
</body>
</html>