Oh-Stick!
Tags: notes, stick, remember, magnet
Published: 2023-12-28 08:13:57

**[Oh-Stick](https://sudo-self.github.io/oh-stick/)**

A **fun**, easy to use, sticky note **web-app**.

start with manifest.json

** instructions to save the app to a screen,
create an icon, and work offline.

create this file from terminal

```
touch manifest.json
```
A text editor will work
```
{
  "name": "oh-stick!",
  "short_name": "notes by jr",
  "start_url": "https://sudo-self.github.io/oh-stick/#",
  "scope": "./",
  "icons": [
    {
      "src": "APPicon.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "APPicon1.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "theme_color": "#ffd31d",
  "background_color": "#333",
  "display": "standalone"
}
```
APPicon.png = Appicon

Oh-stick starts with HTML

```
touch index.html
```
link external CSS and JAVA

```
<link rel=¨stylesheet¨ type=¨text/css¨ href=¨..\[folder_name]\[file_name].css¨><br>
<script src="myscripts.js"></script>
```

standard is legit in 2024.

Set header with favicon

add<br>
favicon.ico&nbsp;&&nbsp;apple-touch-icon.png<br>

in the root folder

```
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
```
 next is html body

```
      <h1>Oh-Stick!</h1>
      <p id="ts">notes by Jesse</p>
    </div>
    <div id="form">
      <form id="inputForm">
        <input
          type="text"
          class="inputText"
          placeholder="Title"
          id="new-note-title-input"
          autocomplete="off"
          required
          autofocus
        /><br><br>
        <input
          class="inputText"
          type="text"
          placeholder="Note Content"
          id="new-note-body-input"
          autocomplete="off"
          required
        />
        <button type="submit" class="btn">
            🧲
        </button>
      </form>
    </div>
</html>
```
Emoji as a button to stick note.

The favicon you can create from scratch.

A good quality starting image is key. 

Javascript makes up the function of the notes.
 
```
touch script.js
```

Set or modify alerts as needed.

```
if ("serviceWorker" in navigator) {
  // register service worker
  navigator.serviceWorker.register("service-worker.js");
}

var itemList = document.getElementById("notes");

itemList.addEventListener("click", removeItem);

let count = Number(window.localStorage.getItem("count"));
if (!count) {
  window.localStorage.setItem("count", "0");
}

console.log(count);

let createNote = (noteTitle, noteBody) => {
  if (count > 0) {
    document.getElementById("no-notes").className = "hidden";
  }

  var li = document.createElement("li");
  var a = document.createElement("a");
  var h2 = document.createElement("h2");
  var p = document.createElement("p");
  var ul = document.getElementById("notes");

  let xButton = document.createElement("button");
  xButton.classList.add("delete");
  let xText = document.createTextNode("X");
  let h2TN = document.createTextNode(noteTitle);
  let pTN = document.createTextNode(noteBody);

  h2.appendChild(h2TN);
  p.appendChild(pTN);
  xButton.appendChild(xText);

  a.appendChild(h2);
  a.appendChild(xButton);
  a.appendChild(p);
  a.setAttribute("href", "#");

  li.appendChild(a);
  ul.appendChild(li);
};

let createNoteFromInput = (e) => {
  e.preventDefault();
  var noteTitle = document.getElementById("new-note-title-input").value;
  var noteBody = document.getElementById("new-note-body-input").value;

  document.getElementById("new-note-title-input").value = "";
  document.getElementById("new-note-body-input").value = "";

  console.log("yes");
  if (!noteTitle || !noteBody) {
    alert("Both Title and body of the note must be provided");
    return;
  }
  count += 1;
  window.localStorage.setItem("count", count);

  while (window.localStorage.getItem(noteTitle)) {
    noteTitle = noteTitle + " - 1";
  }
  window.localStorage.setItem(noteTitle, noteBody);

  createNote(noteTitle, noteBody);
};

function removeItem(e) {
  //console.log('2');
  if (e.target.classList.contains("delete")) {
    console.log(e);
    if (
      confirm(
        'Remove adhesive from "' +
          e.target.previousElementSibling.innerText +
          '" stick?'
      )
    ) {
      //grab the parent
      // console.log(e.target.previousSibling.data);
      var li = e.target.parentElement.parentElement;

      itemList.removeChild(li);
      count -= 1;
      window.localStorage.setItem("count", count);
      window.localStorage.removeItem(e.target.previousElementSibling.innerText);
      if (count < 1) {
        document.getElementById("no-notes").className = "";
      }
    }
  }
}

for (i = 0; i < count + 1; i++) {
  console.log(window.localStorage.key(i));
  let noteTitle = window.localStorage.key(i);
  let noteBody = window.localStorage.getItem(noteTitle);
  if (noteTitle !== "count" && noteTitle) {
    createNote(noteTitle, noteBody);
  }
}

document
  .getElementById("inputForm")
  .addEventListener("submit", createNoteFromInput, false);
```

style.css

strong foundations can scale vertically

.json adds wrapper versatility.

```
touch style.css
```

```
* {
  margin: 0;
  padding: 0;
}

body {
  font-family: arial, sans-serif;
  font-size: 100%;
  margin: 3em;
  background: #333;
  color: #fff;
}

#heading {
  position: sticky;
  top: 0;
  background-color: #333;
  z-index: 7;
  padding: 15px 0px;
  margin-left: 15px;
}

#no-notes {
  padding: 100px 0px;
  text-align: center;
}

#ts {
  color: #9085c4;
}

.inputText {
  padding: 10px;
  border-radius: 5px;
  border: 2px solid #9085c4;
  width: 30%;
  margin: 15px;
  outline: none;
}

.hidden {
  display: none;
}

.btn {
  padding: 10px;
  border-radius: 20px;
  border: 2px solid #9085c4;
  background-color: #333;
  color: #333;
  cursor: pointer;
  outline: none;
  -webkit-tap-highlight-color: transparent;
}

.btn:active {
  border: 2px solid #333;
  box-shadow: inset 0 0 5px #000000;
}

h2,
p {
  font-size: 100%;
  font-weight: normal;
}

ul,
li {
  list-style: none;
}

ul {
  overflow: hidden;
  padding: 3em 1em;
}

ul li a {
  text-decoration: none;
  color: #000;
  background: #9085c4;
  display: block;
  height: 10em;
  width: 10em;
  padding: 1em;
  box-shadow: 5px 5px 7px rgba(33, 33, 33, 0.7);
}

ul li {
  margin: 1em;
  float: left;
  position: relative;
}

ul li h2 {
  font-size: 1.2rem;
  font-weight: bold;
  padding-bottom: 10px;
}

ul li p {
  font-family: "Reenie Beanie", cursive;
  font-size: 1.1rem;
}

.delete {
  float: right;
  position: absolute;
  top: 0;
  right: 0;
  width: 30px;
  height: 30px;
  background-color: red;
  border: 4px double white;
  font-weight: bold;
  cursor: pointer;
}

ul li a {
  transform: rotate(-6deg);
  -moz-transform: rotate(-6deg);
  cursor: default;
}

ul li:nth-child(even) a {
  transform: rotate(4deg);
  -moz-transform: rotate(4deg);
  position: relative;
  top: 5px;
  background: #ff5733;
}

ul li:nth-child(3n) a {
  transform: rotate(-3deg);
  -moz-transform: rotate(-3deg);
  position: relative;
  top: -5px;
  background: #77d8d8;
}

ul li:nth-child(5n) a {
  transform: rotate(5deg);
  -moz-transform: rotate(5deg);
  position: relative;
  top: -10px;
}

ul li a:hover,
ul li a:focus {
  box-shadow: 10px 10px 7px rgba(0, 0, 0, 0.7);
  -moz-box-shadow: 10px 10px 7px rgba(0, 0, 0, 0.7);
  transform: scale(1.25);
  -moz-transform: scale(1.25);
  position: relative;
  z-index: 5;
}

ol {
  text-align: center;
}

ol li {
  display: inline;
  padding-right: 1em;
}

ol li a {
  color: #fff;
}

@media only screen and (max-width: 600px) {
  body {
    margin-top: 1em;
  }
  #new-note-title-input,
  #new-note-body-input {
    display: block;
    width: 90%;
    margin-left: 0px;
  }

  #heading {
    margin-left: 0px;
  }

  .btn {
    margin-left: 0px;
  }
}
```

A **static.yml** will work to publish a workflow.

[![Deploy static content to Pages](https://github.com/sudo-self/audio-html/actions/workflows/static.yml/badge.svg)](https://github.com/sudo-self/audio-html/actions/workflows/static.yml)<br>

The workflow is essential for wrapping to PWA to APK. with GH-Pages you now have a URL for manifest.json

https://sudo-self.github.io/oh-stick/ manifest.json HERE


static.yml

```
name: Deploy static content to Pages

on:
 
  push:
    branches: ["main"]

 tab
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Setup Pages
        uses: actions/configure-pages@v4
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
         
          path: '.'
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4
```

Now The App is live online.

https://sudo-self.github.io/oh-stick/
 

1. index.html
2. style.css
3. script.js
4. ""
5. ""
<----website---->

<---webapp----->

4. liscense.txt
5. README.md (project explanation)

<----TWA---->

6. manifest.json (for PWA to APK or IPA)


<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="html,result" data-slug-hash="jOJbNdV" data-editable="true" data-user="sudo-self" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sudo-self/pen/jOJbNdV">
  Oh-stick!</a> by sudo-self (<a href="https://codepen.io/sudo-self">@sudo-self</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


All the way to a signed android APK with a wrapper.

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

<p>sticky reminders</p>

<p><a href="https://oh-stick.JesseJesse.com" target="_blank">https://oh-stick.JesseJesse.com</a></p>

<iframe height="300" style="width: 100%;" scrolling="no" title="Oh-stick!" src="https://codepen.io/sudo-self/embed/jOJbNdV?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href="https://codepen.io/sudo-self/pen/jOJbNdV">
  Oh-stick!</a> by sudo-self (<a href="https://codepen.io/sudo-self">@sudo-self</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>