main.js (5933B)
1 import * as api from "/lib/api.js" 2 import * as etc from "/lib/etc.js" 3 import * as ui from "/lib/ui.js" 4 5 etc.handle_wrap(init) 6 7 function init() { 8 etc.authorize() 9 etc.bar() 10 main() 11 } 12 13 function main() { 14 update_info("Username", localStorage.getItem("username")) 15 16 let errfunc = function(err) { etc.error("Unable to get settings: " + err, document.querySelector("#settings")) } 17 api.fetch("GET", "settings") 18 .then(function(params) { 19 api.fetch("GET", "users/:user/settings") 20 .then(function(current) { 21 show_settings(current, params) 22 }) 23 }) 24 .catch(errfunc) 25 26 let h = document.body.appendChild( 27 document.createElement("h2") 28 ) 29 h.appendChild(document.createTextNode("Delete Account")) 30 let del = delete_form() 31 del.onsubmit = delete_user 32 document.body.append(del) 33 } 34 35 function delete_form() { 36 let form = document.createElement("form") 37 form.id = "delete_user_form" 38 39 form.appendChild(ui.warning("This action cannot be undone.")) 40 41 let label = document.createElement("label") 42 label.setAttribute("for", "delete_user_confirm") 43 label.appendChild(document.createTextNode("Confirm: ")) 44 form.append(label) 45 46 let check = document.createElement("input") 47 check.id = "delete_user_confirm" 48 check.type = "checkbox" 49 check.setAttribute("required", true) 50 form.append(check) 51 52 form.appendChild(document.createTextNode(" ")) 53 54 let submit = document.createElement("input") 55 submit.type = "submit" 56 submit.value = "Delete Account" 57 form.append(submit) 58 59 return form 60 } 61 62 function delete_user() { 63 api.fetch("DELETE", "users/:user") 64 .then(function() { 65 api.update_token(null) 66 document.location.href = "/" 67 }) 68 .catch(function(err) { etc.error("Unable to delete user: " + err, document.getElementById("#delete_form")) }) 69 return false 70 } 71 72 function show_settings(current, params) { 73 let form = document.createElement("form") 74 form.id = "settings" 75 let list = document.createElement("ul") 76 form.append(list) 77 for (name in params) { 78 let id = name + "_setting" 79 let item = document.createElement("li") 80 81 let label = document.createElement("label") 82 label.setAttribute("for", id) 83 84 label.appendChild(document.createTextNode(ui.prettyName(name, { title: false }) + " ")) 85 item.append(label) 86 87 let input = create_input(name, params[name], current[name]) 88 input.id = id 89 input.setAttribute("title", params[name].description) 90 item.append(input) 91 92 list.append(item) 93 } 94 95 let submit = document.createElement("input") 96 submit.value = "Update" 97 submit.type = "submit" 98 form.append(submit) 99 100 form.addEventListener("submit", function(event) { 101 event.preventDefault() 102 update_settings(current, params) 103 }) 104 105 let current_form = document.querySelector("#settings") 106 current_form.replaceWith(form) 107 108 update_verified_email() 109 } 110 111 function update_settings(current, params) { 112 let settings = Array.from(document.querySelectorAll("form#settings > ul > li > input")) 113 let patch = [] 114 for (let i in settings) { 115 let name = settings[i].name 116 let oldvalue = current[name] 117 let newvalue 118 if (settings[i].getAttribute("type") == "checkbox") { 119 newvalue = settings[i].checked 120 } else { 121 newvalue = settings[i].value 122 } 123 124 if (params.default && newvalue == params.default) { 125 if (oldvalue != null) { 126 patch.push({ op: "remove", path: name }) 127 } 128 } else if (newvalue != oldvalue) { 129 if (name === "email") { 130 update_verified_email() 131 } 132 patch.push({ op: "add", path: name, value: newvalue }) 133 } 134 } 135 136 if (patch.length == 0) { 137 return 138 } 139 api.fetch("PATCH", "users/:user/settings", patch) 140 .then(function(updated) { 141 for (let k in updated) { 142 current[k] = updated[k] 143 } 144 // Alert in a less annoying way 145 alert("Settings successfully updated") 146 }) 147 .catch(function(err) { etc.error("Unable to update settings: " + err) }) 148 } 149 150 function update_verified_email() { 151 let setting_form = document.querySelector('input[name="email"]') 152 if (!setting_form) { 153 throw new Error("Expected email setting") 154 } 155 156 api.verifiedEmail() 157 .then(function(verified) { 158 update_info("Email", verified) 159 let old_warning = document.getElementById("unverified_email_warning") 160 if (verified == setting_form.value) { 161 if (old_warning != null) { 162 old_warning.remove() 163 } 164 } else if (verified == null || verified != setting_form.value) { 165 let content = document.createElement("p") 166 content.appendChild(document.createTextNode("This email is not verified. Please verify it ")) 167 let a = content.appendChild(document.createElement("a")) 168 a.href = "./verify-email" 169 a.appendChild(document.createTextNode("here.")) 170 171 let warning = ui.warning(content) 172 warning.id = "unverified_email_warning" 173 warning.classList.add("small") 174 175 if (old_warning != null) { 176 old_warning.replaceWith(warning) 177 } else { 178 setting_form.after(warning) 179 } 180 } 181 }) 182 } 183 184 function create_input(name, setting, current_value) { 185 let input = document.createElement("input") 186 if (setting.type == "string") { 187 input.type = name === "email" ? "email" : "text" 188 } else if (setting.type == "bool") { 189 input.type = "checkbox" 190 if (current_value) { 191 input.setAttribute("checked", "true") 192 } 193 } else { 194 throw new Error("Unexpected setting type") 195 } 196 197 input.name = name 198 if (current_value) { 199 input.value = current_value 200 } 201 202 return input 203 } 204 205 function update_info(key, value) { 206 let dl = document.getElementById("userinfo") 207 208 if (value == null) { 209 return 210 } 211 212 let v = get_info_element(key) 213 if (v != undefined) { 214 v.textContent = value 215 return 216 } 217 218 let k = dl.appendChild(document.createElement("dt")) 219 k.appendChild(document.createTextNode(key)) 220 v = dl.appendChild(document.createElement("dd")) 221 v.appendChild(document.createTextNode(value)) 222 } 223 224 function get_info_element(key) { 225 let dl = document.getElementById("userinfo") 226 227 let k 228 let keys = Array.from(dl.querySelectorAll("dt")) 229 for (let i in keys) { 230 if (keys[i].textContent == key) { 231 return keys[i].nextElementSibling 232 } 233 } 234 235 return undefined 236 }