Initial commit
This commit is contained in:
commit
7dbdab4ee8
3 files changed
+555
No files matched your search
@@ -0,0 +1,167 @@
|
||||
const MAX_HISTORY_LENGTH = 32;
|
||||
const PIP_WINDOW_SIZE = { width: 280, height: 140 };
|
||||
|
||||
class Counter {
|
||||
constructor(elementId, storageKey) {
|
||||
this.el = document.getElementById(elementId);
|
||||
this.key = storageKey;
|
||||
this.count = parseInt(localStorage.getItem(this.key)) || 0;
|
||||
this.history = [];
|
||||
this.render();
|
||||
}
|
||||
|
||||
render = () => {
|
||||
this.el.textContent = this.count;
|
||||
}
|
||||
|
||||
set = (val) => {
|
||||
this.history.push(this.count);
|
||||
if (this.history.length > MAX_HISTORY_LENGTH) this.history.shift();
|
||||
this.count = val;
|
||||
localStorage.setItem(this.key, this.count);
|
||||
this.render();
|
||||
}
|
||||
|
||||
increase = () => {
|
||||
this.set(this.count + 1);
|
||||
}
|
||||
|
||||
undo = () => {
|
||||
if (this.history.length > 0) {
|
||||
this.count = this.history.pop();
|
||||
localStorage.setItem(this.key, this.count);
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const stitches = new Counter("stitches-counter", "stitches");
|
||||
const rows = new Counter("rows-counter", "rows");
|
||||
|
||||
const inputAuto = document.getElementById("input-autoincrease");
|
||||
const inputStitchMax = document.getElementById("input-stitches");
|
||||
|
||||
inputAuto.checked = localStorage.getItem("input_autoincrease") === "true";
|
||||
inputStitchMax.value = localStorage.getItem("input_stitches") || "10";
|
||||
|
||||
inputAuto.addEventListener("change", () => {
|
||||
localStorage.setItem("input_autoincrease", inputAuto.checked);
|
||||
});
|
||||
|
||||
inputStitchMax.addEventListener("change", () => {
|
||||
localStorage.setItem("input_stitches", inputStitchMax.value);
|
||||
});
|
||||
|
||||
document.getElementById("button-stitch").addEventListener("click", () => {
|
||||
const max = parseInt(inputStitchMax.value);
|
||||
if (inputAuto.checked && stitches.count + 1 >= max) {
|
||||
rows.increase();
|
||||
stitches.set(0);
|
||||
} else {
|
||||
stitches.increase();
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById("button-row").addEventListener("click", () => {
|
||||
rows.increase();
|
||||
stitches.set(0);
|
||||
});
|
||||
|
||||
document.getElementById("button-undo").addEventListener("click", () => {
|
||||
stitches.undo();
|
||||
rows.undo();
|
||||
});
|
||||
|
||||
document.getElementById("button-reset").addEventListener("click", () => {
|
||||
stitches.set(0);
|
||||
rows.set(0);
|
||||
});
|
||||
|
||||
class PipManager {
|
||||
constructor(pipElement, pipContainer, pipButton) {
|
||||
this.el = pipElement;
|
||||
this.container = pipContainer;
|
||||
this.button = pipButton;
|
||||
this.pipWindow = null;
|
||||
|
||||
this.button.addEventListener("click", this.start);
|
||||
}
|
||||
|
||||
start = async () => {
|
||||
if (this.pipWindow && !this.pipWindow.closed) return;
|
||||
|
||||
this.pipWindow = await documentPictureInPicture.requestWindow(PIP_WINDOW_SIZE);
|
||||
|
||||
for (const styleSheet of document.styleSheets) {
|
||||
try {
|
||||
const style = document.createElement("style");
|
||||
const rules = Array.from(styleSheet.cssRules).map(r => r.cssText).join("");
|
||||
style.textContent = rules;
|
||||
this.pipWindow.document.head.appendChild(style);
|
||||
} catch {
|
||||
if (styleSheet.href) {
|
||||
const link = document.createElement("link");
|
||||
link.rel = "stylesheet";
|
||||
link.href = styleSheet.href;
|
||||
this.pipWindow.document.head.appendChild(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.pipWindow.document.body.appendChild(this.el);
|
||||
|
||||
// Add keydown listener inside PiP window
|
||||
this.pipWindow.addEventListener("keydown", (event) => {
|
||||
// Ignore if focused on input or textarea in PiP window
|
||||
const active = this.pipWindow.document.activeElement;
|
||||
if (active && (active.tagName === "INPUT" || active.tagName === "TEXTAREA")) return;
|
||||
|
||||
if (event.code === "Space") {
|
||||
event.preventDefault();
|
||||
const max = parseInt(inputStitchMax.value);
|
||||
if (inputAuto.checked && stitches.count + 1 >= max) {
|
||||
rows.increase();
|
||||
stitches.set(0);
|
||||
} else {
|
||||
stitches.increase();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.pipWindow.addEventListener("pagehide", () => this.stop());
|
||||
}
|
||||
|
||||
stop = () => {
|
||||
this.container.appendChild(this.el);
|
||||
this.pipWindow = null;
|
||||
}
|
||||
}
|
||||
|
||||
new PipManager(
|
||||
document.getElementById("div-pip-element"),
|
||||
document.getElementById("div-pip-container"),
|
||||
document.getElementById("button-start-pip")
|
||||
);
|
||||
|
||||
const notesField = document.getElementById("notes");
|
||||
notesField.value = localStorage.getItem("notes") || "";
|
||||
notesField.addEventListener("input", () => {
|
||||
localStorage.setItem("notes", notesField.value);
|
||||
});
|
||||
|
||||
window.addEventListener("keydown", (event) => {
|
||||
// Ignore if focused on input or textarea, so typing space doesn't increment stitches accidentally
|
||||
const active = document.activeElement;
|
||||
if (active && (active.tagName === "INPUT" || active.tagName === "TEXTAREA")) return;
|
||||
|
||||
if (event.code === "Space") {
|
||||
event.preventDefault(); // prevent page scroll on space key
|
||||
const max = parseInt(inputStitchMax.value);
|
||||
if (inputAuto.checked && stitches.count + 1 >= max) {
|
||||
rows.increase();
|
||||
stitches.set(0);
|
||||
} else {
|
||||
stitches.increase();
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user