From a0a8ef51672f954024e4899fdbe1220db0fe914b Mon Sep 17 00:00:00 2001 From: Amazingca Date: Fri, 1 May 2026 01:23:01 -0600 Subject: [PATCH] Finish up management logic, add importing --- archived.html | 28 +++++++++++ archived.js | 107 ++++++++++++++++++++++++++++++++++++++++++ index.html | 2 +- script.js => index.js | 38 ++++++++++++--- settings.html | 36 ++++++++++++++ settings.js | 70 +++++++++++++++++++++++++++ style.css | 10 ++-- 7 files changed, 279 insertions(+), 12 deletions(-) create mode 100644 archived.html create mode 100644 archived.js rename script.js => index.js (89%) create mode 100644 settings.html create mode 100644 settings.js diff --git a/archived.html b/archived.html new file mode 100644 index 0000000..c3e951d --- /dev/null +++ b/archived.html @@ -0,0 +1,28 @@ + + + + todo + + + + + +
+
+

todo

+ +
+
+
+
+
+
+
+
+ + + diff --git a/archived.js b/archived.js new file mode 100644 index 0000000..1a9814d --- /dev/null +++ b/archived.js @@ -0,0 +1,107 @@ +var todos = { + uncompleted: [], + completed: [] +}; +var archived = []; +var theme = { + colorScheme: "default", + css: "" +}; + +if (localStorage.getItem("todos")) { + + todos = JSON.parse(localStorage.getItem("todos")); +} + +if (localStorage.getItem("archived")) { + + archived = JSON.parse(localStorage.getItem("archived")); +} + +if (localStorage.getItem("theme")) { + + theme = JSON.parse(localStorage.getItem("theme")); +} + +const backupData = () => { + + localStorage.setItem("todos", JSON.stringify(todos)); + localStorage.setItem("archived", JSON.stringify(archived)); + localStorage.setItem("theme", JSON.stringify(theme)); +} + +const archivedElement = document.getElementById("archived"); + +const todoElement = (item, index) => { + + return ` + +
+ +
+

restore

+

delete

+
+
+
+ `; +} + +const resizeTextHeights = () => { + + for (const element of document.querySelectorAll("todo textarea")) { + + element.style.height = "0"; + element.style.height = element.scrollHeight + "px"; + } +} + +const applyListeners = () => { + + resizeTextHeights(); + + for (var i = 0; i < archived.length; i++) { + + let index = i; // fixes scoping issue - what a disaster + + document.getElementById(`todo-archived-${i}-description`).addEventListener("input", (event) => { + + event.target.style.height = "0"; + event.target.style.height = event.target.scrollHeight + "px"; + + archived[index].description = event.target.value; + + backupData(); + }); + + document.getElementById(`todo-archived-${i}-restore`).addEventListener("click", (event) => { + + todos.uncompleted = [ + archived[index] + ].concat(todos.uncompleted); + archived.splice(index, 1); + + hydrateTodos(); + backupData(); + }); + + document.getElementById(`todo-archived-${i}-delete`).addEventListener("click", (event) => { + + archived.splice(index, 1); + + hydrateTodos(); + backupData(); + }); + } +} + +const hydrateTodos = () => { + + archivedElement.innerHTML = archived + .map((x, index) => todoElement(x, index)) + .join(""); + + applyListeners(); +}; + +hydrateTodos(); diff --git a/index.html b/index.html index aa00f69..4aa4a8f 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ todo - +
diff --git a/script.js b/index.js similarity index 89% rename from script.js rename to index.js index f8df07e..7ca7fa9 100644 --- a/script.js +++ b/index.js @@ -3,6 +3,10 @@ var todos = { completed: [] }; var archived = []; +var theme = { + colorScheme: "default", + css: "" +}; if (localStorage.getItem("todos")) { @@ -14,7 +18,32 @@ if (localStorage.getItem("archived")) { archived = JSON.parse(localStorage.getItem("archived")); } -// TODO: URL sharing data override here... +if (localStorage.getItem("theme")) { + + theme = JSON.parse(localStorage.getItem("theme")); +} + +const backupData = () => { + + localStorage.setItem("todos", JSON.stringify(todos)); + localStorage.setItem("archived", JSON.stringify(archived)); + localStorage.setItem("theme", JSON.stringify(theme)); +} + +if (window.location.hash.length > 0) { + + try { + + ({todos, archived, theme} = JSON.parse(atob(window.location.hash.substring(1)))); // using parenthesis around this is required because we're doing object literal destructuring without a declaration + + backupData(); + } catch (e) { + + console.error(e); + + window.alert("The import URL provided was not valid!"); + } +} document.getElementById("createTodo").addEventListener("click", () => { @@ -25,6 +54,7 @@ document.getElementById("createTodo").addEventListener("click", () => { ].concat(todos.uncompleted); hydrateUncompleted(); + applyListeners(); backupData(); }); @@ -34,12 +64,6 @@ document.getElementById("showCompleted").addEventListener("click", () => { resizeTextHeights(); }); -const backupData = () => { - - localStorage.setItem("todos", JSON.stringify(todos)); - localStorage.setItem("archived", JSON.stringify(archived)); -} - const todosElement = document.getElementById("todos"); const completedElement = document.getElementById("todos-completed"); diff --git a/settings.html b/settings.html new file mode 100644 index 0000000..1403db1 --- /dev/null +++ b/settings.html @@ -0,0 +1,36 @@ + + + + todo + + + + + +
+
+

todo

+ +
+
+
+
+
+ +

theming

+

override css

+ +
+
+ + + diff --git a/settings.js b/settings.js new file mode 100644 index 0000000..43e958d --- /dev/null +++ b/settings.js @@ -0,0 +1,70 @@ +var todos = { + uncompleted: [], + completed: [] +}; +var archived = []; +var theme = { + colorScheme: "default", + css: "" +}; + +if (localStorage.getItem("todos")) { + + todos = JSON.parse(localStorage.getItem("todos")); +} + +if (localStorage.getItem("archived")) { + + archived = JSON.parse(localStorage.getItem("archived")); +} + +if (localStorage.getItem("theme")) { + + theme = JSON.parse(localStorage.getItem("theme")); +} + +const exportDataText = document.getElementById("exportData_text"); + +document.getElementById("exportData").addEventListener("click", async (event) => { + + const dataExport = { + todos: todos, + archived: archived, + theme: theme + }; + + const exportURL = window.location.href.replace("settings.html", "") + "index.html#" + btoa(JSON.stringify(dataExport)); + + if (!window.navigator.userAgent.includes("Mozilla")) { + + try { + + await navigator.share({ + title: "todo data export", + url: exportURL + }); + + exportDataText.innerHTML = "shared!"; + setTimeout(() => { + exportDataText.innerHTML = "export as link"; + }, 2000); + } catch (e) { + + console.error(e); + } + } else { + + navigator.clipboard.writeText(exportURL); + + exportDataText.innerHTML = "link copied!"; + setTimeout(() => { + exportDataText.innerHTML = "export as link"; + }, 2000); + } +}); + +const override_css = document.getElementById("override_css"); + +const update = () => { + +} diff --git a/style.css b/style.css index 1cfc15a..04ccb70 100644 --- a/style.css +++ b/style.css @@ -16,7 +16,6 @@ body { h3 { margin: 0; - user-select: none; } header { @@ -44,7 +43,7 @@ nav { display: flex; width: 100%; justify-content: center; - & > div, #todos, #todos-completed { + & > div, #todos, #todos-completed, #archived { width: 400px; display: flex; flex-direction: column; @@ -80,7 +79,7 @@ todo { justify-content: right; gap: 0.5rem; & > p { - user-select: none; + /* user-select: none; */ font-size: 0.9rem; margin: 0; cursor: pointer; @@ -104,8 +103,11 @@ button { cursor: pointer; } +#override_css { + resize: vertical; +} + a, a:visited, a:active { - user-select: none; color: var(--text-primary); background-color: var(--background-secondary); text-decoration: none; -- 2.54.0