2024-06-22 14:57:09 +01:00
|
|
|
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0
|
|
|
|
|
2024-03-12 18:34:05 +00:00
|
|
|
if (localStorage.getItem("DONOTSHARE-secretkey") === null) {
|
2024-04-28 23:48:03 +01:00
|
|
|
window.location.replace("/login")
|
2024-03-12 18:34:05 +00:00
|
|
|
document.body.innerHTML = "Redirecting..."
|
|
|
|
throw new Error();
|
|
|
|
}
|
|
|
|
if (localStorage.getItem("DONOTSHARE-password") === null) {
|
2024-04-28 23:48:03 +01:00
|
|
|
window.location.replace("/login")
|
2024-03-12 18:34:05 +00:00
|
|
|
document.body.innerHTML = "Redirecting..."
|
|
|
|
throw new Error();
|
|
|
|
}
|
|
|
|
|
|
|
|
let remote = localStorage.getItem("homeserverURL")
|
|
|
|
if (remote == null) {
|
|
|
|
localStorage.setItem("homeserverURL", "https://notes.hectabit.org")
|
|
|
|
remote = "https://notes.hectabit.org"
|
|
|
|
}
|
|
|
|
|
|
|
|
function formatBytes(a, b = 2) { if (!+a) return "0 Bytes"; const c = 0 > b ? 0 : b, d = Math.floor(Math.log(a) / Math.log(1000)); return `${parseFloat((a / Math.pow(1000, d)).toFixed(c))} ${["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"][d]}` }
|
|
|
|
|
|
|
|
let secretkey = localStorage.getItem("DONOTSHARE-secretkey")
|
|
|
|
let password = localStorage.getItem("DONOTSHARE-password")
|
2024-04-24 20:25:23 +01:00
|
|
|
let currentFontSize = 16
|
2024-04-25 22:34:18 +01:00
|
|
|
let markdowntoggle = false
|
2024-03-12 18:34:05 +00:00
|
|
|
|
2024-05-20 20:24:43 +01:00
|
|
|
let backButton = document.getElementById("backButton")
|
2024-03-12 18:34:05 +00:00
|
|
|
let usernameBox = document.getElementById("usernameBox")
|
|
|
|
let optionsCoverDiv = document.getElementById("optionsCoverDiv")
|
|
|
|
let optionsDiv = document.getElementById("optionsDiv")
|
|
|
|
let errorDiv = document.getElementById("errorDiv")
|
|
|
|
let errorMessageThing = document.getElementById("errorMessageThing")
|
|
|
|
let closeErrorButton = document.getElementById("closeErrorButton")
|
|
|
|
let cancelErrorButton = document.getElementById("cancelErrorButton")
|
|
|
|
let errorInput = document.getElementById("errorInput")
|
|
|
|
let exitThing = document.getElementById("exitThing")
|
|
|
|
let exitSessionsThing = document.getElementById("exitSessionsThing")
|
|
|
|
let sessionManagerButton = document.getElementById("sessionManagerButton")
|
2024-05-20 20:24:43 +01:00
|
|
|
let importNotesButton = document.getElementById("importNotesButton")
|
2024-03-12 18:34:05 +00:00
|
|
|
let sessionManagerDiv = document.getElementById("sessionManagerDiv")
|
2024-05-20 20:24:43 +01:00
|
|
|
let importNotesDiv = document.getElementById("importDiv")
|
2024-03-12 18:34:05 +00:00
|
|
|
let sessionDiv = document.getElementById("sessionDiv")
|
|
|
|
let deleteMyAccountButton = document.getElementById("deleteMyAccountButton")
|
|
|
|
let storageThing = document.getElementById("storageThing")
|
|
|
|
let storageProgressThing = document.getElementById("storageProgressThing")
|
|
|
|
let usernameThing = document.getElementById("usernameThing")
|
|
|
|
let logOutButton = document.getElementById("logOutButton")
|
|
|
|
let notesBar = document.getElementById("notesBar")
|
2024-06-25 19:43:24 +01:00
|
|
|
let topBar = document.getElementById("topBar")
|
2024-03-12 18:34:05 +00:00
|
|
|
let notesDiv = document.getElementById("notesDiv")
|
|
|
|
let newNote = document.getElementById("newNote")
|
|
|
|
let noteBox = document.getElementById("noteBox")
|
2024-05-20 20:24:43 +01:00
|
|
|
let noteBoxDiv = document.getElementById("noteBoxDiv")
|
2024-03-12 18:34:05 +00:00
|
|
|
let loadingStuff = document.getElementById("loadingStuff")
|
|
|
|
let exportNotesButton = document.getElementById("exportNotesButton")
|
2024-04-24 20:25:23 +01:00
|
|
|
let markdown = document.getElementById('markdown');
|
2024-04-28 23:48:03 +01:00
|
|
|
let textSizeBox = document.getElementById('textSizeBox');
|
|
|
|
let textPlusBox = document.getElementById('textPlusBox');
|
|
|
|
let textMinusBox = document.getElementById('textMinusBox');
|
|
|
|
let wordCountBox = document.getElementById('wordCountBox');
|
|
|
|
let removeBox = document.getElementById("removeBox")
|
2024-05-20 20:24:43 +01:00
|
|
|
let importFile = document.getElementById("importFile")
|
2024-03-12 18:34:05 +00:00
|
|
|
|
|
|
|
let selectedNote = 0
|
|
|
|
let timer
|
|
|
|
let waitTime = 400
|
2024-05-20 20:24:43 +01:00
|
|
|
let indiv = false
|
|
|
|
let mobile = false
|
2024-06-23 15:49:01 +01:00
|
|
|
let selectLatestNote = false
|
2024-03-12 18:34:05 +00:00
|
|
|
|
2024-06-25 19:43:24 +01:00
|
|
|
if (/Android|iPhone|iPod/i.test(navigator.userAgent)) {
|
|
|
|
mobile = true
|
|
|
|
noteBoxDiv.classList.add("mobile");
|
|
|
|
noteBoxDiv.style.width = "0px";
|
|
|
|
notesBar.style.width = "100%"
|
|
|
|
topBar.style.width = "100%"
|
|
|
|
noteBoxDiv.readOnly = true
|
|
|
|
noteBoxDiv.classList.add("hidden")
|
|
|
|
|
|
|
|
let touchstartX, touchstartY, touchendX, touchendY
|
|
|
|
|
|
|
|
notesBar.addEventListener("touchstart", function (event) {
|
|
|
|
touchstartX = event.changedTouches[0].screenX;
|
|
|
|
touchstartY = event.changedTouches[0].screenY;
|
|
|
|
}, false);
|
|
|
|
|
|
|
|
notesBar.addEventListener("touchend", function (event) {
|
|
|
|
touchendX = event.changedTouches[0].screenX;
|
|
|
|
touchendY = event.changedTouches[0].screenY;
|
|
|
|
if (touchendX < touchstartX - 75) {
|
|
|
|
handleGesture();
|
|
|
|
}
|
|
|
|
}, false);
|
|
|
|
|
|
|
|
noteBox.addEventListener("touchstart", function (event) {
|
|
|
|
touchstartX = event.changedTouches[0].screenX;
|
|
|
|
touchstartY = event.changedTouches[0].screenY;
|
|
|
|
}, false);
|
|
|
|
|
|
|
|
noteBox.addEventListener("touchend", function (event) {
|
|
|
|
touchendX = event.changedTouches[0].screenX;
|
|
|
|
touchendY = event.changedTouches[0].screenY;
|
|
|
|
if (touchendX > touchstartX + 75) {
|
|
|
|
handleGesture();
|
|
|
|
} else if (touchendX < touchstartX - 75) {
|
|
|
|
enableMarkdown();
|
|
|
|
}
|
|
|
|
}, false);
|
|
|
|
|
|
|
|
markdown.addEventListener("touchstart", function (event) {
|
|
|
|
touchstartX = event.changedTouches[0].screenX;
|
|
|
|
touchstartY = event.changedTouches[0].screenY;
|
|
|
|
}, false);
|
|
|
|
|
|
|
|
noteBox.addEventListener("touchend", function (event) {
|
|
|
|
touchendX = event.changedTouches[0].screenX;
|
|
|
|
touchendY = event.changedTouches[0].screenY;
|
|
|
|
if (touchendX > touchstartX + 75) {
|
|
|
|
handleGesture();
|
|
|
|
} else if (touchendX < touchstartX - 75) {
|
|
|
|
enableMarkdown();
|
|
|
|
}
|
|
|
|
}, false);
|
|
|
|
|
|
|
|
markdown.addEventListener("touchstart", function (event) {
|
|
|
|
touchstartX = event.changedTouches[0].screenX;
|
|
|
|
touchstartY = event.changedTouches[0].screenY;
|
|
|
|
}, false);
|
|
|
|
|
|
|
|
markdown.addEventListener("touchend", function (event) {
|
|
|
|
touchendX = event.changedTouches[0].screenX;
|
|
|
|
touchendY = event.changedTouches[0].screenY;
|
|
|
|
if (touchendX > touchstartX + 75) {
|
|
|
|
disableMarkdown();
|
|
|
|
} else if (touchendX < touchstartX - 75) {
|
|
|
|
disableMarkdown();
|
|
|
|
}
|
|
|
|
}, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
function handleGesture() {
|
|
|
|
if (indiv) {
|
|
|
|
indiv = false
|
|
|
|
notesBar.style.width = "100%";
|
|
|
|
noteBoxDiv.style.width = "0px"
|
|
|
|
if (selectedNote !== 0) {
|
|
|
|
noteBoxDiv.readOnly = true
|
|
|
|
}
|
|
|
|
notesDiv.classList.remove("hidden")
|
|
|
|
noteBoxDiv.classList.add("hidden")
|
|
|
|
backButton.classList.add("hidden")
|
|
|
|
newNote.classList.remove("hidden")
|
|
|
|
} else {
|
|
|
|
indiv = true
|
|
|
|
noteBoxDiv.style.width = "100%";
|
|
|
|
notesBar.style.width = "0px"
|
|
|
|
if (selectedNote !== 0) {
|
|
|
|
noteBoxDiv.readOnly = false
|
|
|
|
}
|
|
|
|
notesDiv.classList.add("hidden")
|
|
|
|
noteBoxDiv.classList.remove("hidden")
|
|
|
|
backButton.classList.remove("hidden")
|
|
|
|
newNote.classList.add("hidden")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-12 18:34:05 +00:00
|
|
|
noteBox.value = ""
|
|
|
|
noteBox.readOnly = true
|
|
|
|
|
|
|
|
let noteCount = 0
|
|
|
|
|
|
|
|
function displayError(message) {
|
|
|
|
errorDiv.classList.remove("hidden")
|
|
|
|
optionsCoverDiv.classList.remove("hidden")
|
|
|
|
|
|
|
|
errorMessageThing.innerHTML = message
|
|
|
|
}
|
|
|
|
|
2024-04-28 23:48:03 +01:00
|
|
|
closeErrorButton.addEventListener("click", () => {
|
2024-03-12 18:34:05 +00:00
|
|
|
errorDiv.classList.add("hidden")
|
|
|
|
optionsCoverDiv.classList.add("hidden")
|
|
|
|
});
|
2024-04-28 23:48:03 +01:00
|
|
|
closeErrorButton.addEventListener("click", () => {
|
2024-03-12 18:34:05 +00:00
|
|
|
errorDiv.classList.add("hidden")
|
|
|
|
optionsCoverDiv.classList.add("hidden")
|
|
|
|
errorInput.classList.add("hidden")
|
|
|
|
cancelErrorButton.classList.add("hidden")
|
|
|
|
});
|
|
|
|
|
|
|
|
function updateFont() {
|
2024-04-24 20:25:23 +01:00
|
|
|
currentFontSize = localStorage.getItem("SETTING-fontsize")
|
2024-03-12 18:34:05 +00:00
|
|
|
noteBox.style.fontSize = currentFontSize + "px"
|
|
|
|
textSizeBox.innerText = currentFontSize + "px"
|
2024-04-26 16:54:57 +01:00
|
|
|
if (markdowntoggle) {
|
2024-06-26 00:53:44 +01:00
|
|
|
markdown.srcdoc = "<!DOCTYPE html><html lang='en'><style>html { height: 100% } pre { white-space: pre-wrap; overflow-wrap: break-word; } body { white-space: pre-wrap; overflow-wrap: break-word; font-family: 'Inter', sans-serif; height: 100%; color: " + getComputedStyle(document.documentElement).getPropertyValue('--text-color') + "; font-size: " + currentFontSize + "px; }</style>" + marked.parse(DOMPurify.sanitize(noteBox.value)) + "</html>";
|
2024-04-25 22:34:18 +01:00
|
|
|
}
|
2024-03-12 18:34:05 +00:00
|
|
|
}
|
|
|
|
|
2024-05-24 19:48:24 +01:00
|
|
|
async function checknetwork() {
|
|
|
|
fetch(remote + "/api/loggedin", {
|
|
|
|
method: "POST",
|
|
|
|
body: JSON.stringify({
|
|
|
|
secretKey: localStorage.getItem("DONOTSHARE-secretkey"),
|
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json; charset=UTF-8"
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.catch(() => {
|
|
|
|
noteBox.readOnly = true
|
|
|
|
noteBox.value = ""
|
|
|
|
noteBox.placeholder = "You are currently offline."
|
|
|
|
displayError("Failed to connect to the server.\nPlease check your internet connection.")
|
|
|
|
})
|
|
|
|
.then((response) => response)
|
|
|
|
.then((response) => {
|
|
|
|
if (response.status == 400) {
|
|
|
|
displayError("Something went wrong! Signing you out...")
|
|
|
|
closeErrorButton.classList.add("hidden")
|
2024-06-22 14:40:31 +01:00
|
|
|
//usernameBox.innerText = ""
|
2024-05-24 19:48:24 +01:00
|
|
|
setTimeout(function () {
|
|
|
|
window.location.replace("/logout")
|
|
|
|
}, 2500);
|
|
|
|
} else if (response.status == 200) {
|
|
|
|
updateUserInfo()
|
|
|
|
} else {
|
|
|
|
noteBox.readOnly = true
|
|
|
|
noteBox.value = ""
|
|
|
|
noteBox.placeholder = "You are currently offline."
|
|
|
|
displayError("Failed to connect to the server.\nPlease check your internet connection.")
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-03-12 18:34:05 +00:00
|
|
|
if (localStorage.getItem("SETTING-fontsize") === null) {
|
|
|
|
localStorage.setItem("SETTING-fontsize", "16")
|
|
|
|
updateFont()
|
|
|
|
} else {
|
|
|
|
updateFont()
|
|
|
|
}
|
|
|
|
|
2024-04-28 23:48:03 +01:00
|
|
|
textPlusBox.addEventListener("click", () => {
|
2024-03-12 18:34:05 +00:00
|
|
|
localStorage.setItem("SETTING-fontsize", String(Number(localStorage.getItem("SETTING-fontsize")) + Number(1)))
|
|
|
|
updateFont()
|
|
|
|
});
|
2024-04-28 23:48:03 +01:00
|
|
|
textMinusBox.addEventListener("click", () => {
|
2024-03-12 18:34:05 +00:00
|
|
|
localStorage.setItem("SETTING-fontsize", String(Number(localStorage.getItem("SETTING-fontsize")) - Number(1)))
|
|
|
|
updateFont()
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
function truncateString(str, num) {
|
|
|
|
if (str.length > num) {
|
|
|
|
return str.slice(0, num) + "..";
|
|
|
|
} else {
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function updateUserInfo() {
|
|
|
|
fetch(remote + "/api/userinfo", {
|
|
|
|
method: "POST",
|
|
|
|
body: JSON.stringify({
|
|
|
|
secretKey: secretkey
|
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json; charset=UTF-8"
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.then((response) => {
|
|
|
|
async function doStuff() {
|
2024-04-28 23:48:03 +01:00
|
|
|
if (response.status === 500) {
|
2024-05-24 19:48:24 +01:00
|
|
|
displayError("Something went wrong! Signing you out...")
|
2024-03-12 18:34:05 +00:00
|
|
|
closeErrorButton.classList.add("hidden")
|
|
|
|
setTimeout(function () {
|
2024-04-28 23:48:03 +01:00
|
|
|
window.location.replace("/logout")
|
2024-03-12 18:34:05 +00:00
|
|
|
}, 2500);
|
|
|
|
} else {
|
|
|
|
let responseData = await response.json()
|
|
|
|
usernameThing.innerText = "Username: " + responseData["username"]
|
|
|
|
storageThing.innerText = "You've used " + formatBytes(responseData["storageused"]) + " out of " + formatBytes(responseData["storagemax"])
|
|
|
|
storageProgressThing.value = responseData["storageused"]
|
|
|
|
storageProgressThing.max = responseData["storagemax"]
|
|
|
|
noteCount = responseData["notecount"]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
doStuff()
|
|
|
|
});
|
|
|
|
}
|
2024-04-28 23:48:03 +01:00
|
|
|
usernameBox.addEventListener("click", () => {
|
2024-03-12 18:34:05 +00:00
|
|
|
optionsCoverDiv.classList.remove("hidden")
|
|
|
|
optionsDiv.classList.remove("hidden")
|
|
|
|
updateUserInfo()
|
|
|
|
});
|
2024-04-28 23:48:03 +01:00
|
|
|
logOutButton.addEventListener("click", () => {
|
|
|
|
window.location.replace("/logout")
|
2024-03-12 18:34:05 +00:00
|
|
|
});
|
2024-04-28 23:48:03 +01:00
|
|
|
exitThing.addEventListener("click", () => {
|
2024-03-12 18:34:05 +00:00
|
|
|
optionsDiv.classList.add("hidden")
|
|
|
|
optionsCoverDiv.classList.add("hidden")
|
|
|
|
});
|
2024-04-28 23:48:03 +01:00
|
|
|
deleteMyAccountButton.addEventListener("click", () => {
|
|
|
|
if (confirm("Are you REALLY sure that you want to delete your account? There's no going back!") === true) {
|
2024-03-12 18:34:05 +00:00
|
|
|
fetch(remote + "/api/deleteaccount", {
|
|
|
|
method: "POST",
|
|
|
|
body: JSON.stringify({
|
|
|
|
secretKey: secretkey
|
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json; charset=UTF-8"
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.then((response) => {
|
2024-04-28 23:48:03 +01:00
|
|
|
if (response.status === 200) {
|
|
|
|
window.location.href = "/logout"
|
2024-03-12 18:34:05 +00:00
|
|
|
} else {
|
|
|
|
displayError("Failed to delete account (HTTP error code " + response.status + ")")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
});
|
2024-05-20 20:24:43 +01:00
|
|
|
importNotesButton.addEventListener("click", () => {
|
|
|
|
optionsDiv.classList.add("hidden")
|
|
|
|
importNotesDiv.classList.remove("hidden")
|
|
|
|
});
|
2024-04-28 23:48:03 +01:00
|
|
|
sessionManagerButton.addEventListener("click", () => {
|
2024-03-12 18:34:05 +00:00
|
|
|
optionsDiv.classList.add("hidden")
|
|
|
|
sessionManagerDiv.classList.remove("hidden")
|
|
|
|
|
|
|
|
fetch(remote + "/api/sessions/list", {
|
|
|
|
method: "POST",
|
|
|
|
body: JSON.stringify({
|
|
|
|
secretKey: secretkey
|
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json; charset=UTF-8"
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.then((response) => {
|
|
|
|
async function doStuff() {
|
|
|
|
let responseData = await response.json()
|
|
|
|
document.querySelectorAll(".burgerSession").forEach((el) => el.remove());
|
2024-04-28 23:48:03 +01:00
|
|
|
let ua;
|
2024-03-12 18:34:05 +00:00
|
|
|
for (let i in responseData) {
|
|
|
|
let sessionElement = document.createElement("div")
|
|
|
|
let sessionText = document.createElement("p")
|
|
|
|
let sessionImage = document.createElement("img")
|
|
|
|
let sessionRemoveButton = document.createElement("button")
|
|
|
|
sessionText.classList.add("w300")
|
2024-04-28 23:48:03 +01:00
|
|
|
if (responseData[i]["thisSession"] === true) {
|
2024-03-12 18:34:05 +00:00
|
|
|
sessionText.innerText = "(current) " + responseData[i]["device"]
|
|
|
|
} else {
|
|
|
|
sessionText.innerText = responseData[i]["device"]
|
|
|
|
}
|
|
|
|
sessionText.title = responseData[i]["device"]
|
|
|
|
sessionRemoveButton.innerText = "x"
|
|
|
|
|
|
|
|
sessionImage.src = "/static/svg/device_other.svg"
|
|
|
|
|
|
|
|
ua = responseData[i]["device"]
|
|
|
|
|
|
|
|
if (ua.includes("NT") || ua.includes("Linux")) {
|
|
|
|
sessionImage.src = "/static/svg/device_computer.svg"
|
|
|
|
}
|
2024-04-28 23:48:03 +01:00
|
|
|
if (ua.includes("iPhone" || ua.includes("Android") || ua.includes("iPod"))) {
|
2024-03-12 18:34:05 +00:00
|
|
|
sessionImage.src = "/static/svg/device_smartphone.svg"
|
|
|
|
}
|
|
|
|
|
2024-04-28 23:48:03 +01:00
|
|
|
sessionRemoveButton.addEventListener("click", () => {
|
2024-03-12 18:34:05 +00:00
|
|
|
fetch(remote + "/api/sessions/remove", {
|
|
|
|
method: "POST",
|
|
|
|
body: JSON.stringify({
|
|
|
|
secretKey: secretkey,
|
|
|
|
sessionId: responseData[i]["id"]
|
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json; charset=UTF-8"
|
|
|
|
}
|
|
|
|
})
|
2024-04-28 23:48:03 +01:00
|
|
|
.then(() => {
|
|
|
|
if (responseData[i]["thisSession"] === true) {
|
|
|
|
window.location.replace("/logout")
|
2024-03-12 18:34:05 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
sessionElement.remove()
|
|
|
|
});
|
|
|
|
|
|
|
|
sessionElement.append(sessionImage)
|
|
|
|
sessionElement.append(sessionText)
|
|
|
|
sessionElement.append(sessionRemoveButton)
|
|
|
|
|
|
|
|
sessionElement.classList.add("burgerSession")
|
|
|
|
|
|
|
|
sessionDiv.append(sessionElement)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
doStuff()
|
|
|
|
});
|
|
|
|
});
|
2024-05-20 20:24:43 +01:00
|
|
|
exitImportThing.addEventListener("click", () => {
|
|
|
|
optionsDiv.classList.remove("hidden")
|
|
|
|
importNotesDiv.classList.add("hidden")
|
|
|
|
});
|
2024-04-28 23:48:03 +01:00
|
|
|
exitSessionsThing.addEventListener("click", () => {
|
2024-03-12 18:34:05 +00:00
|
|
|
optionsDiv.classList.remove("hidden")
|
|
|
|
sessionManagerDiv.classList.add("hidden")
|
|
|
|
});
|
|
|
|
|
|
|
|
function updateWordCount() {
|
|
|
|
let wordCount = noteBox.value.split(" ").length
|
2024-04-28 23:48:03 +01:00
|
|
|
if (wordCount === 1) {
|
2024-03-12 18:34:05 +00:00
|
|
|
wordCount = 0
|
|
|
|
}
|
|
|
|
wordCountBox.innerText = wordCount + " words"
|
|
|
|
}
|
|
|
|
|
2024-04-24 20:25:23 +01:00
|
|
|
function renderMarkDown() {
|
2024-04-26 16:48:32 +01:00
|
|
|
if (markdowntoggle) {
|
2024-06-26 00:53:44 +01:00
|
|
|
markdown.srcdoc = "<!DOCTYPE html><html lang='en'><style>html { height: 100% } pre { white-space: pre-wrap; overflow-wrap: break-word; } body { white-space: pre-wrap; overflow-wrap: break-word; font-family: 'Inter', sans-serif; height: 100%; color: " + getComputedStyle(document.documentElement).getPropertyValue('--text-color') + "; font-size: " + currentFontSize + "px; }</style>" + marked.parse(DOMPurify.sanitize(noteBox.value)) + "</html>"
|
2024-04-25 22:34:18 +01:00
|
|
|
}
|
2024-04-24 20:25:23 +01:00
|
|
|
}
|
|
|
|
|
2024-03-12 18:34:05 +00:00
|
|
|
function selectNote(nameithink) {
|
|
|
|
document.querySelectorAll(".noteButton").forEach((el) => el.classList.remove("selected"));
|
2024-04-28 23:48:03 +01:00
|
|
|
let thingArray = Array.from(document.querySelectorAll(".noteButton")).find(el => String(nameithink) === String(el.id));
|
2024-03-12 18:34:05 +00:00
|
|
|
thingArray.classList.add("selected")
|
|
|
|
|
|
|
|
fetch(remote + "/api/readnote", {
|
|
|
|
method: "POST",
|
|
|
|
body: JSON.stringify({
|
|
|
|
secretKey: secretkey,
|
|
|
|
noteId: nameithink,
|
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json; charset=UTF-8"
|
|
|
|
}
|
|
|
|
})
|
2024-04-28 23:48:03 +01:00
|
|
|
.catch(() => {
|
2024-03-12 18:34:05 +00:00
|
|
|
noteBox.readOnly = true
|
|
|
|
noteBox.value = ""
|
|
|
|
noteBox.placeholder = ""
|
|
|
|
displayError("Something went wrong... Please try again later!")
|
|
|
|
})
|
|
|
|
.then((response) => {
|
|
|
|
selectedNote = nameithink
|
2024-05-20 20:24:43 +01:00
|
|
|
if (mobile) {
|
|
|
|
handleGesture()
|
|
|
|
}
|
2024-03-12 18:34:05 +00:00
|
|
|
noteBox.readOnly = false
|
|
|
|
noteBox.placeholder = "Type something!"
|
|
|
|
|
|
|
|
async function doStuff() {
|
|
|
|
let responseData = await response.json()
|
|
|
|
|
|
|
|
let bytes = CryptoJS.AES.decrypt(responseData["content"], password);
|
2024-04-28 23:48:03 +01:00
|
|
|
noteBox.value = bytes.toString(CryptoJS.enc.Utf8)
|
2024-06-22 15:45:33 +01:00
|
|
|
|
2024-03-12 18:34:05 +00:00
|
|
|
updateWordCount()
|
2024-04-24 20:25:23 +01:00
|
|
|
renderMarkDown()
|
2024-03-12 18:34:05 +00:00
|
|
|
|
2024-04-28 23:48:03 +01:00
|
|
|
noteBox.addEventListener("input", () => {
|
2024-03-12 18:34:05 +00:00
|
|
|
updateWordCount()
|
2024-04-24 20:25:23 +01:00
|
|
|
renderMarkDown()
|
2024-03-12 18:34:05 +00:00
|
|
|
clearTimeout(timer);
|
|
|
|
timer = setTimeout(() => {
|
2024-06-23 15:49:01 +01:00
|
|
|
let preEncryptedTitle = noteBox.value
|
2024-03-12 18:34:05 +00:00
|
|
|
|
2024-06-23 15:49:01 +01:00
|
|
|
if (noteBox.value.substring(0, noteBox.value.indexOf("\n")) !== "") {
|
|
|
|
preEncryptedTitle = noteBox.value.substring(0, noteBox.value.indexOf("\n"));
|
2024-03-12 18:34:05 +00:00
|
|
|
}
|
2024-06-23 15:49:01 +01:00
|
|
|
|
|
|
|
preEncryptedTitle = truncateString(preEncryptedTitle, 15)
|
|
|
|
document.getElementById(nameithink).innerText = preEncryptedTitle
|
|
|
|
|
2024-03-12 18:34:05 +00:00
|
|
|
let encryptedText = CryptoJS.AES.encrypt(noteBox.value, password).toString();
|
2024-06-23 15:49:01 +01:00
|
|
|
let encryptedTitle = CryptoJS.AES.encrypt(preEncryptedTitle, password).toString();
|
|
|
|
|
|
|
|
console.log(encryptedTitle)
|
|
|
|
console.log(encryptedText)
|
2024-03-12 18:34:05 +00:00
|
|
|
|
2024-04-28 23:48:03 +01:00
|
|
|
if (selectedNote === nameithink) {
|
2024-03-12 18:34:05 +00:00
|
|
|
fetch(remote + "/api/editnote", {
|
|
|
|
method: "POST",
|
|
|
|
body: JSON.stringify({
|
|
|
|
secretKey: secretkey,
|
|
|
|
noteId: nameithink,
|
|
|
|
content: encryptedText,
|
|
|
|
title: encryptedTitle
|
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json; charset=UTF-8"
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.then((response) => {
|
2024-04-28 23:48:03 +01:00
|
|
|
if (response.status === 418) {
|
2024-03-12 18:34:05 +00:00
|
|
|
displayError("You've ran out of storage... Changes will not be saved until you free up storage!")
|
|
|
|
}
|
|
|
|
})
|
2024-04-28 23:48:03 +01:00
|
|
|
.catch(() => {
|
2024-03-12 18:34:05 +00:00
|
|
|
displayError("Failed to save changes, please try again later...")
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}, waitTime);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
doStuff()
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateNotes() {
|
2024-06-23 15:49:01 +01:00
|
|
|
console.log("notes updated")
|
2024-03-12 18:34:05 +00:00
|
|
|
fetch(remote + "/api/listnotes", {
|
|
|
|
method: "POST",
|
|
|
|
body: JSON.stringify({
|
|
|
|
secretKey: secretkey
|
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json; charset=UTF-8"
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.then((response) => {
|
|
|
|
async function doStuff() {
|
|
|
|
noteBox.readOnly = true
|
|
|
|
selectedNote = 0
|
2024-06-23 15:49:01 +01:00
|
|
|
if (selectLatestNote == false) {
|
2024-03-12 18:34:05 +00:00
|
|
|
noteBox.placeholder = ""
|
2024-06-23 15:49:01 +01:00
|
|
|
}
|
2024-03-12 18:34:05 +00:00
|
|
|
noteBox.value = ""
|
|
|
|
clearTimeout(timer)
|
|
|
|
updateWordCount()
|
2024-04-24 20:25:23 +01:00
|
|
|
renderMarkDown()
|
2024-03-12 18:34:05 +00:00
|
|
|
|
|
|
|
let responseData = await response.json()
|
2024-06-23 15:49:01 +01:00
|
|
|
|
|
|
|
let decryptedResponseData = []
|
|
|
|
|
|
|
|
let highestID = 0
|
|
|
|
|
|
|
|
// First decrypt note data, then render
|
2024-03-12 18:34:05 +00:00
|
|
|
for (let i in responseData) {
|
2024-06-23 15:49:01 +01:00
|
|
|
noteData = responseData[i]
|
|
|
|
|
|
|
|
let bytes = CryptoJS.AES.decrypt(noteData["title"], password);
|
|
|
|
let decryptedTitle = bytes.toString(CryptoJS.enc.Utf8);
|
|
|
|
|
|
|
|
noteData["title"] = decryptedTitle
|
|
|
|
|
|
|
|
if (noteData["id"] > highestID) {
|
|
|
|
highestID = noteData["id"]
|
|
|
|
}
|
|
|
|
|
|
|
|
decryptedResponseData.push(noteData)
|
|
|
|
console.log(noteData)
|
|
|
|
}
|
|
|
|
|
|
|
|
document.querySelectorAll(".noteButton").forEach((el) => el.remove());
|
|
|
|
for (let i in decryptedResponseData) {
|
|
|
|
let noteData = decryptedResponseData[i]
|
|
|
|
|
2024-03-12 18:34:05 +00:00
|
|
|
let noteButton = document.createElement("button");
|
|
|
|
noteButton.classList.add("noteButton")
|
|
|
|
notesDiv.append(noteButton)
|
|
|
|
|
2024-06-23 15:49:01 +01:00
|
|
|
console.log(noteData["title"])
|
2024-03-12 18:34:05 +00:00
|
|
|
|
2024-06-23 15:49:01 +01:00
|
|
|
if (noteData["title"] == "") {
|
|
|
|
console.log(noteData["title"])
|
|
|
|
console.log("case")
|
|
|
|
noteData["title"] = "New note"
|
|
|
|
}
|
|
|
|
|
|
|
|
noteButton.id = noteData["id"]
|
|
|
|
noteButton.innerText = truncateString(noteData["title"], 15)
|
2024-03-12 18:34:05 +00:00
|
|
|
|
|
|
|
noteButton.addEventListener("click", (event) => {
|
|
|
|
if (event.ctrlKey) {
|
|
|
|
fetch(remote + "/api/removenote", {
|
|
|
|
method: "POST",
|
|
|
|
body: JSON.stringify({
|
|
|
|
secretKey: secretkey,
|
2024-06-23 15:49:01 +01:00
|
|
|
noteId: noteData["id"]
|
2024-03-12 18:34:05 +00:00
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json; charset=UTF-8"
|
|
|
|
}
|
|
|
|
})
|
2024-04-28 23:48:03 +01:00
|
|
|
.then(() => {
|
2024-03-12 18:34:05 +00:00
|
|
|
updateNotes()
|
|
|
|
})
|
2024-04-28 23:48:03 +01:00
|
|
|
.catch(() => {
|
2024-03-12 18:34:05 +00:00
|
|
|
displayError("Something went wrong! Please try again later...")
|
|
|
|
})
|
|
|
|
} else {
|
2024-06-23 15:49:01 +01:00
|
|
|
selectNote(noteData["id"])
|
2024-03-12 18:34:05 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
document.querySelectorAll(".loadingStuff").forEach((el) => el.remove());
|
2024-06-23 15:49:01 +01:00
|
|
|
|
|
|
|
if (selectLatestNote == true) {
|
|
|
|
selectNote(highestID)
|
|
|
|
selectLatestNote = false
|
|
|
|
}
|
2024-03-12 18:34:05 +00:00
|
|
|
}
|
|
|
|
doStuff()
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
updateNotes()
|
|
|
|
|
2024-04-28 23:48:03 +01:00
|
|
|
newNote.addEventListener("click", () => {
|
2024-03-12 18:34:05 +00:00
|
|
|
let noteName = "New note"
|
2024-06-23 15:49:01 +01:00
|
|
|
selectLatestNote = true
|
|
|
|
console.log(selectLatestNote)
|
|
|
|
|
|
|
|
// create fake item
|
|
|
|
|
|
|
|
document.querySelectorAll(".noteButton").forEach((el) => el.classList.remove("selected"));
|
|
|
|
let noteButton = document.createElement("button");
|
|
|
|
noteButton.classList.add("noteButton")
|
|
|
|
notesDiv.append(noteButton)
|
|
|
|
noteButton.innerText = "New note"
|
|
|
|
noteButton.style.order = -1
|
|
|
|
noteButton.classList.add("selected")
|
|
|
|
noteBox.placeholder = "Type something!"
|
|
|
|
|
2024-04-28 23:48:03 +01:00
|
|
|
let encryptedName = CryptoJS.AES.encrypt(noteName, password).toString(CryptoJS.enc.Utf8);
|
2024-06-23 15:49:01 +01:00
|
|
|
|
2024-03-12 18:34:05 +00:00
|
|
|
fetch(remote + "/api/newnote", {
|
|
|
|
method: "POST",
|
|
|
|
body: JSON.stringify({
|
|
|
|
secretKey: secretkey,
|
|
|
|
noteName: encryptedName,
|
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json; charset=UTF-8"
|
|
|
|
}
|
|
|
|
})
|
2024-04-28 23:48:03 +01:00
|
|
|
.catch(() => {
|
2024-03-12 18:34:05 +00:00
|
|
|
displayError("Failed to create new note, please try again later...")
|
|
|
|
})
|
|
|
|
.then((response) => {
|
|
|
|
if (response.status !== 200) {
|
|
|
|
updateNotes()
|
|
|
|
displayError("Failed to create new note (HTTP error code " + response.status + ")")
|
|
|
|
} else {
|
|
|
|
updateNotes()
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
function downloadObjectAsJson(exportObj, exportName) {
|
2024-06-26 00:53:44 +01:00
|
|
|
let dataStr = "data:text/json;charset=utf-8," + DOMPurify.sanitize(JSON.stringify(exportObj));
|
2024-04-28 23:48:03 +01:00
|
|
|
let downloadAnchorNode = document.createElement("a");
|
2024-03-12 18:34:05 +00:00
|
|
|
downloadAnchorNode.setAttribute("href", dataStr);
|
|
|
|
downloadAnchorNode.setAttribute("download", exportName + ".json");
|
|
|
|
document.body.appendChild(downloadAnchorNode);
|
|
|
|
downloadAnchorNode.click();
|
|
|
|
downloadAnchorNode.remove();
|
|
|
|
}
|
|
|
|
|
|
|
|
function exportNotes() {
|
|
|
|
fetch(remote + "/api/exportnotes", {
|
|
|
|
method: "POST",
|
|
|
|
body: JSON.stringify({
|
|
|
|
secretKey: secretkey
|
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json; charset=UTF-8"
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.then((response) => {
|
|
|
|
async function doStuff() {
|
|
|
|
let responseData = await response.json()
|
|
|
|
for (let i in responseData) {
|
|
|
|
exportNotes.innerText = "Decrypting " + i + "/" + noteCount
|
|
|
|
|
|
|
|
let bytes = CryptoJS.AES.decrypt(responseData[i]["title"], password);
|
2024-04-28 23:48:03 +01:00
|
|
|
responseData[i]["title"] = bytes.toString(CryptoJS.enc.Utf8)
|
2024-03-12 18:34:05 +00:00
|
|
|
|
|
|
|
let bytesd = CryptoJS.AES.decrypt(responseData[i]["content"], password);
|
2024-04-28 23:48:03 +01:00
|
|
|
responseData[i]["content"] = bytesd.toString(CryptoJS.enc.Utf8)
|
2024-03-12 18:34:05 +00:00
|
|
|
}
|
|
|
|
let jsonString = JSON.parse(JSON.stringify(responseData))
|
|
|
|
downloadObjectAsJson(jsonString, "data")
|
|
|
|
optionsDiv.classList.add("hidden")
|
|
|
|
displayError("Exported notes!")
|
|
|
|
}
|
|
|
|
doStuff()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-05-20 20:24:43 +01:00
|
|
|
function importNotes(plaintextNotes) {
|
|
|
|
for (let i in plaintextNotes) {
|
|
|
|
let originalTitle = plaintextNotes[i]["title"];
|
|
|
|
let encryptedTitle = CryptoJS.AES.encrypt(originalTitle, password).toString();
|
|
|
|
plaintextNotes[i]["title"] = encryptedTitle;
|
|
|
|
|
|
|
|
let originalContent = plaintextNotes[i]["content"];
|
|
|
|
let encryptedContent = CryptoJS.AES.encrypt(originalContent, password).toString();
|
|
|
|
plaintextNotes[i]["content"] = encryptedContent;
|
2024-03-12 18:34:05 +00:00
|
|
|
}
|
2024-05-23 17:54:26 +01:00
|
|
|
fetch(remote + "/api/importnotes", {
|
|
|
|
method: "POST",
|
|
|
|
body: JSON.stringify({
|
|
|
|
"secretKey": localStorage.getItem("DONOTSHARE-secretkey"),
|
|
|
|
"notes": JSON.stringify(plaintextNotes)
|
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json; charset=UTF-8"
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.then((response) => {
|
|
|
|
async function doStuff() {
|
|
|
|
if (response.status === 500) {
|
2024-05-23 18:15:20 +01:00
|
|
|
optionsDiv.classList.add("hidden")
|
|
|
|
importNotesDiv.classList.add("hidden")
|
2024-05-23 17:54:26 +01:00
|
|
|
displayError("Something went wrong! Perhaps your note file was invalid?")
|
|
|
|
} else {
|
2024-05-23 18:15:20 +01:00
|
|
|
optionsDiv.classList.add("hidden")
|
|
|
|
importNotesDiv.classList.add("hidden")
|
2024-05-23 17:54:26 +01:00
|
|
|
displayError("Notes uploaded!")
|
|
|
|
updateNotes()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
doStuff()
|
|
|
|
})
|
2024-03-12 18:34:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function firstNewVersion() {
|
2024-04-28 23:48:03 +01:00
|
|
|
if (localStorage.getItem("NEWVERSION") === "1.2") {
|
2024-03-12 18:34:05 +00:00
|
|
|
return false;
|
|
|
|
} else {
|
2024-04-24 17:08:32 +01:00
|
|
|
localStorage.setItem("NEWVERSION", "1.2")
|
2024-03-12 18:34:05 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-24 20:25:23 +01:00
|
|
|
function toggleMarkdown() {
|
|
|
|
if (markdown.style.display === 'none') {
|
2024-05-20 20:24:43 +01:00
|
|
|
enableMarkdown()
|
2024-04-24 20:25:23 +01:00
|
|
|
} else {
|
2024-05-20 20:24:43 +01:00
|
|
|
disableMarkdown()
|
2024-04-24 20:25:23 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-20 20:24:43 +01:00
|
|
|
function enableMarkdown() {
|
|
|
|
markdown.style.display = 'inherit';
|
|
|
|
markdowntoggle = true
|
|
|
|
renderMarkDown()
|
|
|
|
}
|
|
|
|
|
|
|
|
function disableMarkdown() {
|
|
|
|
markdown.style.display = 'none';
|
|
|
|
markdowntoggle = false
|
|
|
|
markdown.srcdoc = ""
|
|
|
|
}
|
|
|
|
|
2024-04-28 23:48:03 +01:00
|
|
|
exportNotesButton.addEventListener("click", () => {
|
2024-03-12 18:34:05 +00:00
|
|
|
exportNotes()
|
|
|
|
});
|
|
|
|
|
2024-05-20 20:24:43 +01:00
|
|
|
importFile.addEventListener('change', function(e) {
|
|
|
|
let fileread = new FileReader()
|
|
|
|
fileread.addEventListener(
|
|
|
|
"load",
|
|
|
|
() => {
|
|
|
|
let decrypted = JSON.parse(fileread.result)
|
2024-05-23 17:54:26 +01:00
|
|
|
importNotes(decrypted)
|
2024-05-20 20:24:43 +01:00
|
|
|
},
|
|
|
|
false,
|
|
|
|
);
|
|
|
|
|
|
|
|
fileread.readAsText(importFile.files[0])
|
|
|
|
})
|
|
|
|
|
2024-04-28 23:48:03 +01:00
|
|
|
removeBox.addEventListener("click", () => {
|
|
|
|
if (selectedNote === 0) {
|
2024-03-12 18:34:05 +00:00
|
|
|
displayError("You need to select a note first!")
|
|
|
|
} else {
|
2024-06-23 15:49:01 +01:00
|
|
|
selectLatestNote = true
|
2024-03-12 18:34:05 +00:00
|
|
|
fetch(remote + "/api/removenote", {
|
|
|
|
method: "POST",
|
|
|
|
body: JSON.stringify({
|
|
|
|
secretKey: secretkey,
|
|
|
|
noteId: selectedNote
|
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json; charset=UTF-8"
|
|
|
|
}
|
|
|
|
})
|
2024-04-28 23:48:03 +01:00
|
|
|
.then(() => {
|
2024-03-12 18:34:05 +00:00
|
|
|
updateNotes()
|
|
|
|
})
|
2024-04-28 23:48:03 +01:00
|
|
|
.catch(() => {
|
2024-03-12 18:34:05 +00:00
|
|
|
displayError("Something went wrong! Please try again later...")
|
|
|
|
})
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2024-04-24 20:25:23 +01:00
|
|
|
document.addEventListener("DOMContentLoaded", function() {
|
2024-06-26 00:53:44 +01:00
|
|
|
markdown.srcdoc = "<!DOCTYPE html><html lang='en'><style>html { height: 100% } pre { white-space: pre-wrap; overflow-wrap: break-word; } body { white-space: pre-wrap; overflow-wrap: break-word; font-family: 'Inter', sans-serif; height: 100%; color: " + getComputedStyle(document.documentElement).getPropertyValue('--text-color') + "; font-size: " + currentFontSize + "px; }</style>" + marked.parse(DOMPurify.sanitize(noteBox.value)) + "</html>"
|
2024-04-24 20:25:23 +01:00
|
|
|
});
|
|
|
|
|
2024-03-12 18:34:05 +00:00
|
|
|
if (firstNewVersion()) {
|
2024-05-24 19:48:24 +01:00
|
|
|
displayError("What's new in Burgernotes 2.0?\nRestyled client\nAdded changing passwords\nMigrated to OAuth2\nAdded importing notes")
|
2024-03-12 18:34:05 +00:00
|
|
|
}
|
2024-03-29 20:05:46 +00:00
|
|
|
|
2024-05-24 19:48:24 +01:00
|
|
|
checknetwork()
|
2024-06-22 14:57:09 +01:00
|
|
|
|
2024-06-25 19:43:24 +01:00
|
|
|
// @license-end
|