Making a chrome extension part 1 (1 of 100DaysOfCode)
Tags: 100daysofcode, javascript
Published: 2022-01-15 18:07:48

Soo... I decided to try #100DaysOfCode challenge, but with a little twist. I will add two of my own rules.

1. Every day before 23:59 I will complete one project. It must be presentable.
2. Every week I will create something that has market value (i.e. can be billed)

**Explanation of rules:**
The project can be anything from a cool looking button to mobile app. But it has to be presentable. Meaning I need to be able to show it to someone and say: "See, it does that".

# The ultimate WHY of this challenge
I have been stuck in tutorial hell. I am having a impostor syndrome. I generally want to feel that I made something. And I think jumping into a project not knowing everything is great way to learn important things.

As for the second rule. I met an family friend that is self taught in many fields besides his degree. We talked about some of our projects and ideas. And he told me that at this point in my education and life it is important for me to learn how to make money. And he is so right. You can go only so far without money. And when you really think about it, projects that generate money are the ones that people will actually want/need.


So lets see today's project.


## The WHY
Lots of jobs include sitting. But sitting for hours is bad. And your body will pay the price, sooner or later. But what if we pay the price before we sit down, would we be safer than. That's why I made **THE PRICE OF SITTING extension**.

## The WHAT

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s9zxy7462opm1hz7ik5v.png)

_**Chrome extension - The Price of Sitting**_

Idea is that you will get x minutes for y repetitions of some exercise. If you are out of minutes just do some exercises.

## The HOW
So making the chrome extension is actually pretty simple. One thing you must have is _manifest.json_ file. Its a file that tells browser how to use other files.
Lets look at our _manifest.json_

```json
{
  "name": "The Price of sitting",
  "description": "The idea is that you buy sitting time with exercise. For every X repetitions you will get Y of minutes of sitting.",
  "version": "1.0.0",
  "manifest_version": 3,
  "author": "Filip Ilić",
  "action": {
    "default_icon": {
      "16": "./images/chair16.png",
      "24": "images/chair24.png",
      "32": "images/chair32.png"
    },
    "default_title": "Price of Sitting",
    "default_popup": "popup.html"
  },
  "background": {
    "service_worker": "background.js"
  },
  "permissions": ["storage"]
}
```

Everything up to action is mandatory. Permissions in this case is needed for storage that we will use for storing time and whether user is sitting info in google sync. Default popup is popup.html where all content is located.

Then we have:
- _popup.css_
- _popup.js_

They are called from _popup.html_.

_background.js_ is setting initial values if its first time you are ussing this extension.

```js
chrome.runtime.onInstalled.addListener(() => {
  chrome.storage.sync.get(["sitting", "timeLeft"], ({ sitting, timeLeft }) => {
    if(sitting === undefined || timeLeft === undefined){
      chrome.storage.sync.set({sitting : false, timeLeft : 0});
    }
  });
});
```
And finaly _popup.js_ is where the magic happens.
First we define variables, bind elements to variables and call event listeners. Plus make popup format and display time when opened.

```js
//variables
let counting;

//selecting elements
const headline = document.getElementById("headline"),
    countdown = document.getElementById("countdown"),
    button = document.getElementById("toggleButton"),
    reset = document.getElementById("resetButton"),
    add1 = document.getElementById("add-time-1"),
    add2 = document.getElementById("add-time-2"),
    add3 = document.getElementById("add-time-3");

//listen to this events
button.addEventListener("click", toggleTimer);
reset.addEventListener("click", resetTimer);
add1.addEventListener("click", addTime1);
add2.addEventListener("click", addTime2);
add3.addEventListener("click", addTime3);

displayTime();
```

Next we use seconds left to format it to display in _00:00_ format.
```js
function displayTime() {
    chrome.storage.sync.get("timeLeft", ({timeLeft}) =>{
        let sec = timeLeft % 60;
        let min = Math.floor(timeLeft / 60);
        if(timeLeft > 0){
            countdown.innerText = min + ":" + sec;
        }else{
            countdown.innerText = min + ":" + sec * -1;
        }
    });    
}
```
Then we make toggle timer function.

```js
//on button click toggle timer
function toggleTimer() {
    chrome.storage.sync.get(["sitting", "timeLeft"], ({sitting, timeLeft}) => {
        if(!sitting){
            headline.innerText = "You are sitting now.";
            button.innerText = "Stand Up";
            chrome.storage.sync.set({sitting : true});
            counting = setInterval(() => {
                chrome.storage.sync.set({timeLeft : timeLeft--});
                    displayTime();
                }, 1000);
        } else{
            button.innerText = "Sit Down";
            headline.innerText = "You just stood up for yourself.";
            chrome.storage.sync.set({sitting : false});
            clearInterval(counting);
            
        }
    });
}
```
And finally we make adding and resseting time functions.

```js
//on add time button click add time to timeLeft
function addTime1(){
    chrome.storage.sync.get("timeLeft", ({timeLeft}) =>{
        chrome.storage.sync.set({timeLeft : timeLeft += 1800});
        displayTime();
    });
}
function addTime2(){
    chrome.storage.sync.get("timeLeft", ({timeLeft}) =>{
        chrome.storage.sync.set({timeLeft : timeLeft += 1800});
        displayTime();
    });
}
function addTime3(){
    chrome.storage.sync.get("timeLeft", ({timeLeft}) =>{
        chrome.storage.sync.set({timeLeft : timeLeft += 2400});
        displayTime();
    });
}
//reset timer
function resetTimer(){
    clearInterval(counting);
    chrome.storage.sync.set({timeLeft : 0});
    displayTime();
}
```
## TODO
- I realised that closing the popup keeps time but stops the timer. So that will have to be fixed by either making background script or using date() to remember time.
- It would be cool to have options to set your own exercises for each day. As working same muscles every day is not so good.
- Publish to chrome store. I just want to see how the whole process of publishing goes.

## Links
[Github repo](https://github.com/ikslavok/priceOfSitting)