DEV Community

Cover image for Daily Emoji - My first NextJS project
Lucas Lima do Nascimento
Lucas Lima do Nascimento

Posted on • Updated on

Daily Emoji - My first NextJS project

You can check it live here
You can check the full code here

Intro

The idea of this website, is just to randomize an emoji for the user and make it copiable. It is my first NextJS project.

Steps

So, there are a few steps I followed to create this project:

  • Fetch a few emojis from the https://emojihub.herokuapp.com/
  • Create a "rolling" animation, after the used click the randomize button
  • Show the randomized emoji
  • Make it copiable for the user
  • Signal if the user copied

Fetching from the API


import { useState, useEffect } from "react";

 const UrlToFetch =
"https://emojihub.herokuapp.com/api/all/category_smileys_and_people";

  const [emoji, setEmoji] = useState([{ htmlCode: "" }]);

  const [isLoaded, setIsLoaded] = useState(false);

  const fetchEmoji = () => {
    fetch(UrlToFetch)
      .then((res) => res.json())
      .then((emoji) => setEmoji(emoji))
      .then(() => setIsLoaded(true));
  };



Enter fullscreen mode Exit fullscreen mode

Here is the snippet of code that fetches from the API. After the fetch, it stores all emojis in a state called emoji and set the variable isLoaded to true, making the UI show the loaded emoji.

The "rolling" animation and showing the randomized animation

So, initially, I was thinking to create an animation like a casino-styled roll, but, after searching a little bit (and realizing I would probably need to create a LOT by hand) I decided to make an easier animation, that would just rapidly change between a few emojis.


  const [loadingEmoji, setLoadingEmoji] = useState("😀");
  const [finishedAnimation, setFinishedAnimation] = useState(false);
  const [timeLeft, setTimeLeft] = useState(5);

  useEffect(() => {
    const loadingEmojis = [
      { htmlCode: ["🤣"] },
      { htmlCode: ["😚"] },
      { htmlCode: ["👇"] },
      { htmlCode: ["✌"] },
      { htmlCode: ["🤞"] },
      { htmlCode: ["🖖"] },
    ];
    if (timeLeft === 0) {
      setFinishedAnimation(true);
      setTimeLeft(null);
    }
    if (!timeLeft) return;
    const intervalId = setInterval(() => {
      setLoadingEmoji(getRandomEmoji(loadingEmojis));
      setTimeLeft((timeLeft) => timeLeft - 1);
    }, 333);
    return () => clearInterval(intervalId);
  }, [getRandomEmoji, timeLeft]);


Enter fullscreen mode Exit fullscreen mode

This snippet represents the general idea of the animation, we have a set of emojis and a variable called timeLeft (which represents the time left for the animation to run) initialized with 5. If there is still time left, we create a interval function, that will set a new loadingEmoji and decrease the timeLeft by 1.

If all that is executed and there is no time left, we set finishedAnimation to true and the UI reacts to that.

To animate the showing of the result, I used animate.css


import "animate.css";

<div
  className={
     styles.description +
     " animate__animated animate__tada animate__delay-2s"
     }
     dangerouslySetInnerHTML={{
     __html: emoji,
     }}
></div>
Enter fullscreen mode Exit fullscreen mode

This is the final result:
GIF of the final result

Making it copiable for the user

I used copy-to-clipboard to make it easier to copy into the clipboard of the user.


  const copyToClipboard = () => {
    copy(document.querySelector("#emoji").innerHTML);
  };

  <div
        onClick={() => copyToClipboard()}
        className={
          styles.description +
          " animate__animated animate__tada animate__delay-2s"
        }
        dangerouslySetInnerHTML={{
          __html: emoji,
        }}
        id="emoji"
        data-tip="Click on it to copy <br>to your clipboard!"
      ></div>

Enter fullscreen mode Exit fullscreen mode

Signal for the user that the emoji was copied

For showing the user that the emoji was copied to his clipboard, I used the React-toastify, to create an easy and beautiful notification.


import { ToastContainer, toast } from "react-toastify";

  const notify = () => toast("Copied to clipboard!");

  const copyToClipboard = () => {
    copy(document.querySelector("#emoji").innerHTML);
    notify();
  };


      <ToastContainer
        position="top-right"
        autoClose={2000}
        theme="dark"
        pauseOnHover={false}
      />

Enter fullscreen mode Exit fullscreen mode

And that's it! I also added a few tooltips, to make it more user friendly using react-tooltip, but that is completely optional.

I deployed it to Vercel with a lot of ease and that's all!

Thanks for reading!

Top comments (0)