css: "",
showCompleted: false
};
+var server = {
+ address: "",
+ passphrase: ""
+};
+
+const wsOptions = document.getElementById("ws-options");
if (localStorage.getItem("todos")) {
theme = JSON.parse(localStorage.getItem("theme"));
}
+const serverAddressElement = document.getElementById("serverAddress");
+
+if (localStorage.getItem("server")) {
+
+ server = JSON.parse(localStorage.getItem("server"));
+
+ serverAddressElement.value = server.address;
+ wsOptions.classList.remove("hidden");
+}
+
const exportDataText = document.getElementById("exportData_text");
-document.getElementById("exportData").addEventListener("click", async (event) => {
+const encodeApplicationData = () => {
const dataExport = {
todos: todos,
theme: theme
};
- const exportURL = window.location.href.replace("settings", "").replace(".html", "") + "index.html#" + btoa(encodeURIComponent(JSON.stringify(dataExport)));
+ return btoa(encodeURIComponent(JSON.stringify(dataExport)));
+}
+
+document.getElementById("exportData").addEventListener("click", async (event) => {
+
+ const exportURL = window.location.href.replace("settings", "").replace(".html", "") + "index.html#" + encodeApplicationData();
if (!window.navigator.userAgent.includes("Firefox") && !/(Linux|Windows|Mac)/g.test(window.navigator.platform)) {
}
});
-const backupData = () => {
+const backupData = (full = false) => {
+
+ if (full == true) {
+ localStorage.setItem("todos", JSON.stringify(todos));
+ localStorage.setItem("archived", JSON.stringify(archived));
+ }
localStorage.setItem("theme", JSON.stringify(theme));
+ localStorage.setItem("server", JSON.stringify(server));
}
const override_css = document.getElementById("override_css");
}
updateTheme();
+
+const checkConnection = document.getElementById("checkConnection");
+
+checkConnection.addEventListener("click", async () => {
+
+ const serverAddress = serverAddressElement.value;
+ const serverPassphrase = document.getElementById("serverPassphrase").value;
+
+ const reply = await fetch(serverAddress + "/auth", {
+ headers: {
+ "Authorization": `Basic ${serverPassphrase}`
+ }
+ });
+
+ if (reply.status == 200) {
+
+ server = {
+ address: serverAddress,
+ passphrase: serverPassphrase
+ };
+
+ backupData();
+
+ checkConnection.innerHTML = "Successfully connected!";
+
+ setTimeout(() => {
+ checkConnection.innerHTML = "Save";
+ }, 2000);
+
+ wsOptions.classList.remove("hidden");
+ } else {
+
+ checkConnection.innerHTML = "Server or credentials provided not valid!";
+
+ setTimeout(() => {
+ checkConnection.innerHTML = "Save";
+ }, 2000);
+
+ wsOptions.classList.add("hidden");
+ }
+});
+
+const pushToServer = document.getElementById("pushToServer");
+const pullFromServer = document.getElementById("pullFromServer");
+
+pushToServer.addEventListener("click", async () => {
+
+ const req = await fetch(server.address + "/push", {
+ method: "POST",
+ headers: {
+ "Authorization": `Basic ${server.passphrase}`,
+ "Data": JSON.stringify({
+ todos: todos,
+ archived: archived,
+ theme: theme
+ })
+ }
+ });
+
+ if (req.status == 200) {
+
+ pushToServer.innerHTML = "Success!";
+
+ setTimeout(() => {
+ pushToServer.innerHTML = "Push";
+ }, 2000);
+ } else {
+
+ window.alert(JSON.stringify(req));
+ }
+});
+
+pullFromServer.addEventListener("click", async () => {
+
+ const req = await fetch(server.address + "/pull", {
+ headers: {
+ "Authorization": `Basic ${server.passphrase}`
+ }
+ });
+
+ if (req.status == 200) {
+
+ try {
+
+ ({todos, archived, theme} = JSON.parse(await req.text())); // using parenthesis around this is required because we're doing object literal destructuring without a declaration
+
+ backupData(true);
+ updateHeaders();
+ updateTheme();
+ } catch (e) {
+
+ console.error(e);
+
+ window.alert("The data pulled from the server was not valid!");
+ }
+
+ pullFromServer.innerHTML = "Success!";
+
+ setTimeout(() => {
+ pullFromServer.innerHTML = "Pull";
+ }, 2000);
+ } else {
+
+ window.alert(JSON.stringify(req));
+ }
+})
}
}
+.form {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ & input[type="text"], & input[type="password"] {
+ border: unset;
+ border-radius: var(--border-radius-inner);
+ background-color: var(--background-primary);
+ font-family: "Maple Mono";
+ padding: 0.25rem;
+ &:focus-visible {
+ outline: unset;
+ }
+ }
+ & > div {
+ background-color: var(--background-secondary);
+ border-radius: var(--border-radius-inner);
+ padding: 0.5rem;
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ p {
+ margin: 0;
+ }
+ }
+ & > button {
+ border-radius: var(--border-radius-inner);
+ }
+ & > :first-child {
+ border-top-left-radius: var(--border-radius-outer);
+ border-top-right-radius: var(--border-radius-outer);
+ }
+ & > :last-child {
+ border-bottom-left-radius: var(--border-radius-outer);
+ border-bottom-right-radius: var(--border-radius-outer);
+ }
+}
+
+#ws-options {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+ & > button {
+ flex: 1;
+ }
+}
+
#override_css {
border-radius: 0.5rem;
resize: vertical;