Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pink Magic 8 Ball #279

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# Project Name

Replace this readme with your own information about your project.

Start by briefly describing the assignment in a sentence or two. Keep it short and to the point.
This is a chatbot that is a digital version of a Magic 8 Ball. It gives random answers to the users questions.

## The problem

Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next?
I wanted to start with a greeting and personalized welcome message with the username. Then i wanted the chatbot to give randomized answers to the users questions. Only questions that ends with a ? are valid.

I think the code could be structured a bit better, but It's organically arranged based on my work process. I first struggeled with how to make the chatbot start giving the Magic 8 Ball answers AFTER the first greeting. Once I figured that out, it was pretty much done. I wanted to keep it simple, so no more features were added. I'm very happy with the end result and my kids loved asking the chatbot different questions!

## View it live

Have you deployed your project somewhere? Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about.
https://pink-magic-8-ball.netlify.app/
Your future awaits
Binary file added code/assets/ask.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 removed code/assets/bot.png
Binary file not shown.
Binary file added code/assets/pink-8-ball.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 removed code/assets/user.png
Binary file not shown.
65 changes: 39 additions & 26 deletions code/index.html
Original file line number Diff line number Diff line change
@@ -1,32 +1,45 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./style.css" />
<link
href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"
rel="stylesheet" />
<title>Chatbot</title>
</head>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./style.css" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Josefin+Sans:ital,wght@0,100..700;1,100..700&display=swap"
rel="stylesheet">

<body>
<h1>Welcome to my chatbot!</h1>
<main>
<section class="chat" id="chat"></section>
<div class="input-wrapper" id="input-wrapper">
<form id="name-form">
<label for="name-input">Name</label>
<input id="name-input" type="text" />
<button class="send-btn" type="submit">
Send
</button>
</form>
</div>
</main>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Baloo+2:[email protected]&display=swap" rel="stylesheet">
<title>Chatbot</title>
</head>

<script src="./script.js"></script>
</body>
<body>
<h1>Ask Your Fate:</h1>
<h2>The Magic 8 Ball ✨ Knows</h2>
<p class="info-text">Welcome to the Magic 8 Ball Chatbot!
<br>
Ask me any <span>YES</span> or <span>NO</span> question,
<br>
and I'll provide you
with a wise and prophetic
response.
</p>
<main>
<section class="chat" id="chat"></section>
<div class="input-wrapper" id="input-wrapper">
<form id="name-form">
<input id="name-input" type="text" />
<button class="send-btn" type="submit">
Send
</button>
</form>
</div>
</main>

</html>
<script src="./script.js"></script>
</body>

</html>
92 changes: 85 additions & 7 deletions code/script.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
console.log(`let's chat`)

// DOM selectors (variables that point to selected DOM elements) goes here 👇
const chat = document.getElementById('chat')
const chat = document.getElementById('chat');
const nameForm
= document.getElementById('name-form');
Comment on lines +5 to +6
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slight error here (unnecessary newline):
const nameForm = document.getElementById('name-form');

const nameInput = document.getElementById('name-input');


// Functions goes here 👇

Expand All @@ -13,41 +19,113 @@ const showMessage = (message, sender) => {
<div class="bubble user-bubble">
<p>${message}</p>
</div>
<img src="assets/user.png" alt="User" />
<img src="assets/ask.png" alt="User" />
</section>
`
// The else if statement checks if the sender is the bot and if that's the case it inserts
// an HTML section inside the chat with the posted message from the bot
} else if (sender === 'bot') {
console.log('bot says:', message)
chat.innerHTML += `
<section class="bot-msg">
<img src="assets/bot.png" alt="Bot" />
<img src="assets/pink-8-ball.png" alt="Bot" />
<div class="bubble bot-bubble">
<p>${message}</p>
</div>
</section>
`
}
};

// A function to save the user's name and respond
const saveNameAndRespond = (name) => {
// Save the name to local storage for future use
localStorage.setItem('userName', name);


// Convert the name to uppercase
const capitalizedName = name.toUpperCase();

// Respond to the user with their name
showMessage(`Hello ${capitalizedName}! Do you have a question for me?`, 'bot');
};

// Event listeners
// Flag to track if the bot has asked for the name
let hasAskedName = false;
nameForm.addEventListener('submit', (event) => {
event.preventDefault();

const userName = nameInput.value;
nameInput.value = '';

// Display the user's message
showMessage(userName, 'user');

// Check if the bot has already asked for the // Check if the bot has already asked for the name
if (hasAskedName) {
// If yes, validate the question
if (userName.endsWith('?')) {
// If the question is valid, respond
showMessage(generateMagic8BallResponse(userName), 'bot');
} else {
// If not, prompt the user to ask a question
showMessage("I can only answer questions that end with a question mark. Please try again.", 'bot');
}
} else {
// If not, save the name and respond with the greeting
saveNameAndRespond(userName);
hasAskedName = true;
}
// This little thing makes the chat scroll to the last message when there are too many to
// be shown in the chat box
chat.scrollTop = chat.scrollHeight
}
});




// A function to start the conversation
const greetUser = () => {

// Here we call the function showMessage, that we declared earlier with the argument:
// "Hello there, what's your name?" for message, and the argument "bot" for sender
showMessage("Hello there, what's your name?", 'bot')
// Just to check it out, change 'bot' to 'user' here 👆 and see what happens
}

// Eventlisteners goes here 👇

const magic8BallResponses = [
"Yes, definitely.",
"It is certain.",
"Without a doubt.",
"Yes.",
"Absolutely.",
"As I see it, yes.",
"Most likely.",
"It's possible.",
"Signs point to yes.",
"Yes, indeed.",
"Probably not.",
"Maybe.",
"Time will tell.",
"Cannot predict now.",
"Don't count on it.",
"No.",
"Absolutely not.",
"My sources say no.",
"That's a tough one.",
"Very doubtful."
];

function generateMagic8BallResponse() {
const randomIndex = Math.floor(Math.random() * magic8BallResponses.length);
return magic8BallResponses[randomIndex];
}

// Here we invoke the first function to get the chatbot to ask the first question when
// the website is loaded. Normally we invoke functions like this: greeting()
// To add a little delay to it, we can wrap it in a setTimeout (a built in JavaScript function):
// and pass along two arguments:
// 1.) the function we want to delay, and 2.) the delay in milliseconds
// This means the greeting function will be called one second after the website is loaded.
setTimeout(greetUser, 1000)
setTimeout(greetUser, 2000)
Loading