const getId = (id) => document.getElementById(id); function getOverlay(id) { const elms = document.getElementsByName(id); if (elms.length == 0) return null; return elms[0]; } function showOverlay(id) { const elm = getId(id); if (!elm) return; const overlay = document.createElement("div"); const computedStyles = getComputedStyle(elm); const defaultStyles = getDefaultComputedStyle(elm); let styleString = ""; for (let style of computedStyles) { if (style == "display") continue; const computedValue = computedStyles.getPropertyValue(style); const defaultValue = defaultStyles.getPropertyValue(style); if (computedValue == defaultValue) continue; styleString += `${style}: ${computedValue}; `; } overlay.classList.add("overlay"); overlay.setAttribute("name", id); overlay.innerHTML = `
${elm.innerHTML}
`; document.body.appendChild(overlay); const cb = elm.getAttribute("onopen"); if (typeof cb == "string") { try { eval( `const overlay = document.getElementsByClassName("${id}")[0]; ` + cb ); } catch (err) { console.error(err); } } return overlay; } function _onOverlayDestroy(elm) { const ori_elm = getId(elm.getAttribute("name")); if (ori_elm) { const cb = ori_elm.getAttribute("onclose"); if (typeof cb == "string") { try { eval(cb); } catch (err) { console.error(err); } } } elm.remove(); } function hideOverlay(id) { const elms = document.getElementsByName(id); for (var i of elms) _onOverlayDestroy(i); } function _main_events() { const header_bar_1 = document.querySelector(".header_bar_1"); if (header_bar_1 != null) { let isFloating = false; window.addEventListener("load", function () { if (window.pageYOffset > 0) { header_bar_1.style.animationDuration = "0s"; header_bar_1.classList.add("header_bar_1_undocked"); isFloating = true; } }); window.addEventListener("scroll", function () { if (window.pageYOffset > 0 && !isFloating) { header_bar_1.style.animationDuration = "0.5s"; header_bar_1.classList.remove("header_bar_1_docked"); header_bar_1.classList.add("header_bar_1_undocked"); isFloating = true; } else if (window.pageYOffset === 0 && isFloating) { header_bar_1.style.animationDuration = "0.5s"; header_bar_1.classList.remove("header_bar_1_undocked"); header_bar_1.classList.add("header_bar_1_docked"); isFloating = false; } }); } } _main_events(); /* ----------- couch db ----------- */ //http://127.0.0.1:5984/_utils/#_config/couchdb@127.0.0.1 class CouchDB { static _default_url = "http://127.0.0.1:5984/"; constructor() { this._does_auth_exists_err(); this.request = new XMLHttpRequest(); this.db_name = couchdb_name; this.is_online = 2; } //private methods _does_auth_exists() { return ( typeof couchdb_username == "string" && typeof couchdb_password == "string" && typeof couchdb_name == "string" ); } _does_auth_exists_err() { if (!this._does_auth_exists()) throw 'Keine Auth vorhanden. Digga, mach mal '; } _is_error_missing_database(errReason) { return ( errReason === "no_db_file" || errReason === "Database does not exist." ); } _is_error_missing_data(errReason) { return errReason === "missing"; } async _ping() { try { const response = await fetch(CouchDB._default_url, { method: "GET", }); return response.ok; } catch (err) { return false; } } _send_db_request(method, url, body = null, errorHandling = true) { return new Promise(async (resolve, reject) => { if (this.is_online == 2) { await this.checkOnlineStatus(); } if (this.is_online != 1) { reject("CouchDB is not online!"); return; } const dburl = CouchDB._default_url + this.db_name + "/" + url; const request = this.request; this.request.onreadystatechange = () => { if (request.readyState != 4) return; try { if (request.status == 200 || request.status == 201) { var response = JSON.parse(request.responseText); resolve(response); } //errors else if (request.status == 404) { var json = JSON.parse(request.responseText); if (this._is_error_missing_data(json.reason)) { resolve(null); } else if ( errorHandling && this._is_error_missing_database(json.reason) ) { this.createDB() .then((value) => { this._send_db_request(method, url, body, false) .then((value) => { resolve(value); }) .catch((err) => { reject(err); }); }) .catch((err) => { reject(err); }); } else { reject( `Database not found: ${request.status} (Reason: ${reason.json})`, ); } } else { reject( `Unexpected status: ${request.status} (Response: ${ request.responseText })`, ); } } catch (err) { reject("Unexpected error: " + err); } }; this.request.open(method, dburl, true); this.request.setRequestHeader( "Authorization", "Basic " + btoa(couchdb_username + ":" + couchdb_password), ); this.request.setRequestHeader("Content-type", "application/json"); this.request.send(body); }); } async _get_db_data(id) { return await this._send_db_request("GET", id); } //public methods async checkOnlineStatus() { const res = await this._ping(); if (res === true) { this.is_online = 1; } else { this.is_online = 0; } return res; } async createDB() { await this._send_db_request("PUT", "", null, false); } async get(id) { const res = await this._get_db_data(id); if (res == null) return null; delete res["_id"]; delete res["_rev"]; return res; } async set(id, content, replace = true) { try { if (typeof content != "object") throw ( "basic.js - CouchDB->set: content is not from type object (type = " + typeof content + ")" ); let existingDoc; try { existingDoc = await this._get_db_data(id); } catch (err) { existingDoc = null; } if (existingDoc) { if (replace) { content = { ...content, _id: existingDoc._id, _rev: existingDoc._rev, }; } else { content = { ...existingDoc, ...content, _rev: existingDoc._rev, }; } } const res = await this._send_db_request( "PUT", id, JSON.stringify(content), ); return { type: "success", message: res, }; } catch (err) { console.error(err); return { type: "error", message: err, }; } } async delete(id) { try { var existingDoc = null; try { existingDoc = await this._get_db_data(id); } catch (err) {} if (!existingDoc) return { type: "error", message: "Not found!", }; const res = await this._send_db_request( "DELETE", `${id}?rev=${existingDoc._rev}` ); return { type: "success", message: res, }; } catch (err) { console.error(err); return { type: "error", message: err, }; } } } //getuser function getURLArgsMap() { let spl = location.href.split("?"); if (spl.length != 2) return {}; let _1 = spl[1].split(","); const res = {}; for (var i of _1) { let _2 = i.split("="); if (_2.length == 2) { res[_2[0]] = _2[1]; } else { res[i] = null; } } return res; } function form1(string) { if (!string) return string; return string.charAt(0).toUpperCase() + string.slice(1); } async function getUserData(couchDB) { let username = getURLArgsMap()["user"]; if (!username) { if (typeof (debug_username) == "string") { username = debug_username; } else { return null; } } const res = await couchDB.get("users"); if (!res) return null; const data = res[username]; return !data ? null : { ...data, "name": username }; } var userData = null; async function setUserData(couchDB) { const res = await getUserData(couchDB); if (res == null) { location.href = "../login.html"; return false; } userData = res; updateAllProfiles(res); return true; } async function updateUserData(couchDB, user) { const res = await couchDB.get("users"); if (res == null) return {"type":"error", "message": "CouchDB failed"}; const name = user["name"]; if (!name) return {"type":"error", "message": "Incorrect UserData was presented"}; const u = { ...user }; delete u["name"]; res[name] = u; return await couchDB.set("users", res); } function updateAllProfiles(user) { const profiles = document.getElementsByClassName("profile"); for (var i of profiles) { i.style.backgroundImage = `url("${user.avatar}")`; i.onclick = _onProfileClick; } } function _onProfileClick(event) { var buttonRect = this.getBoundingClientRect(); var dropdown = document.createElement("dropdown"); dropdown.addEventListener("click", dropdown.remove); var bg = document.createElement("div"); dropdown.appendChild(bg); var div = document.createElement("div"); const _1 = window.innerHeight - buttonRect.y - 200; if (_1 < 0) { div.style.transform = "translate(calc(-100% + 58px), calc(-100% - 30px))"; } div.style.top = (buttonRect.bottom) + 'px'; div.style.left = (buttonRect.left) + 'px'; div.innerHTML = ` `; dropdown.appendChild(div); document.body.appendChild(dropdown); } function _onProfilClickOnProfil() { if (typeof(showProfile) == "function") { showProfile(userData); } else { _showProfile(userData); } } function _showProfile(user) { let elm = getId("profile_overlay"); if (!elm) { elm = document.createElement("overlay"); elm.setAttribute("id", "profile_overlay"); document.body.appendChild(elm); } elm.innerHTML = `
Profil-Übersicht

${!user.title ? "": user.title+" "}${form1(user.name)}

Level: ${user.level ?? 0}
Rolle: ${form1(user.role ?? "Student")}

Avatar:

`; showOverlay("profile_overlay"); } async function _showProfileSave(elm) { if (!userData) return; let couchDB = new CouchDB(); const res = await couchDB.get("users"); const avatar = elm.parentElement.querySelector("input"); userData.avatar = avatar.value; const user = {...userData}; delete user["name"]; res[userData.name] = user; await couchDB.set("users", res); updateAllProfiles(userData); hideOverlay("profile_overlay"); }