diff --git a/help/data_xample.js b/help/data_xample.js
index 37daaff..0c8b6ed 100644
--- a/help/data_xample.js
+++ b/help/data_xample.js
@@ -6,10 +6,8 @@ async function createTemp() {
"level": 1,
"avatar": null,
"abilities": [
- "dark_mode"
],
"enabled_abilities": [
- "dark_mode"
],
"role": "student",
"courses": [
@@ -22,10 +20,8 @@ async function createTemp() {
"level": 4,
"avatar": "https://static.turtle-coding-gbr.de/profile-pic.png",
"abilities": [
- "dark_mode"
],
"enabled_abilities": [
- "dark_mode"
],
"role": "professor",
"courses": [
@@ -37,10 +33,8 @@ async function createTemp() {
"level": 4,
"avatar": "https://static.turtle-coding-gbr.de/st",
"abilities": [
- "dark_mode"
],
"enabled_abilities": [
- "dark_mode"
],
"role": "professor",
"courses": [
diff --git a/imgs/epic_border.png b/imgs/epic_border.png
new file mode 100644
index 0000000..284c4dc
Binary files /dev/null and b/imgs/epic_border.png differ
diff --git a/imgs/gold_border.png b/imgs/gold_border.png
new file mode 100644
index 0000000..e50d3a6
Binary files /dev/null and b/imgs/gold_border.png differ
diff --git a/imgs/simple_border.png b/imgs/simple_border.png
new file mode 100644
index 0000000..b8776d1
Binary files /dev/null and b/imgs/simple_border.png differ
diff --git a/lib/basic.css b/lib/basic.css
index 2e6cc50..fd46be2 100644
--- a/lib/basic.css
+++ b/lib/basic.css
@@ -208,7 +208,9 @@ content {
background-color: lightgray;
}
-
+.do-not-color-me {
+ color: black !important;
+}
dropdown {
position: fixed;
@@ -244,6 +246,7 @@ dropdown > div:last-child label {
padding-bottom: 8px;
font-weight: normal;
text-align: center;
+ color: black;
}
dropdown > div:last-child button {
background: none;
diff --git a/lib/basic.js b/lib/basic.js
index e74daef..5f2123c 100644
--- a/lib/basic.js
+++ b/lib/basic.js
@@ -65,6 +65,18 @@ function hideOverlay(id) {
for (var i of elms) _onOverlayDestroy(i);
}
+function refreshOverlays() {
+ const elms = document.getElementsByClassName("overlay");
+ for (var i of elms) {
+ const id = i.getAttribute("name");
+ hideOverlay(id);
+ showOverlay(id);
+ }
+}
+
+
+//----------------------------------//
+
function _main_events() {
const header_bar_1 = document.querySelector(".header_bar_1");
if (header_bar_1 != null) {
@@ -359,6 +371,8 @@ async function getUserData(couchDB) {
}
var userData = null;
+const userDataListener = [];
+
async function setUserData(couchDB) {
const res = await getUserData(couchDB);
if (res == null) {
@@ -367,9 +381,17 @@ async function setUserData(couchDB) {
}
userData = res;
updateAllProfiles(res);
+ _constructProfile(res);
+
+ while (userDataListener.length > 0) {
+ const call = userDataListener[userDataListener.length - 1];
+ userDataListener.pop();
+ try { call(); } catch(err) { console.error(err); }
+ }
+
return true;
}
-async function updateUserData(couchDB, user) {
+async function updateUserData(couchDB, user = userData) {
const res = await couchDB.get("users");
if (res == null) return {"type":"error", "message": "CouchDB failed"};
@@ -385,9 +407,15 @@ async function updateUserData(couchDB, user) {
function updateAllProfiles(user) {
+ const hasProfilAbility = user.enabled_abilities.includes("profile_pic");
+
const profiles = document.getElementsByClassName("profile");
for (var i of profiles) {
- i.style.backgroundImage = `url("${user.avatar}")`;
+ if (hasProfilAbility) {
+ i.style.backgroundImage = `url("${user.avatar}")`;
+ } else {
+ i.style.removeProperty("backgroundImage");
+ }
i.onclick = _onProfileClick;
}
}
@@ -412,6 +440,7 @@ function _onProfileClick(event) {
div.innerHTML = `
+
`;
dropdown.appendChild(div);
@@ -425,28 +454,45 @@ function _onProfilClickOnProfil() {
_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);
- }
+function _constructProfile(user) {
+ const 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")}
+Level:
+Rolle:
-Avatar:
-
+Avatar:
+
`;
+}
+function _showProfile(user) {
+ let elm = getId("profile_overlay");
+
+ const hasProfilAbility = user.enabled_abilities.includes("profile_pic");
+
+ const avatarInp = elm.querySelector(".avatar-inp");
+ if (hasProfilAbility) {
+ elm.querySelector(".profile-pic").style.setProperty("background-image", `url('${user.avatar}')`);
+ elm.querySelector("input").setAttribute("value", user.avatar);
+ avatarInp.style.display = "unset";
+ } else {
+ avatarInp.style.display = "none";
+ }
+ elm.querySelector("u").innerText = getUserDisplayName(user);
+
+ const labels = elm.getElementsByTagName("label");
+ labels[0].innerText = user.level ?? 0;
+ labels[1].innerText = form1(user.role ?? "Student");
+
showOverlay("profile_overlay");
}
async function _showProfileSave(elm) {
@@ -480,4 +526,20 @@ async function playSound(src) {
} catch(err) {
console.log("Error playing audio:", err);
}
+}
+
+function hexToRGBA(hex) {
+ let r = 0, g = 0, b = 0;
+ if (hex.length === 7) {
+ r = parseInt(hex.slice(1, 3), 16);
+ g = parseInt(hex.slice(3, 5), 16);
+ b = parseInt(hex.slice(5, 7), 16);
+ }
+ return [r, g, b];
+}
+
+function getUserDisplayName(user) {
+ const hasHonor = (user.enabled_abilities ??= []).includes("title_of_honor");
+ const title_of_honor = hasHonor ? "(Sir) " : "";
+ return `${title_of_honor}${ !user.title ? "" : user.title + " " }${ form1(user.name) }`;
}
\ No newline at end of file
diff --git a/other/skills.js b/other/skills.js
new file mode 100644
index 0000000..16012f1
--- /dev/null
+++ b/other/skills.js
@@ -0,0 +1,207 @@
+const getSkillTree = () => ({
+ id: "root",
+ text: "Skill-Tree",
+ children: [
+ {
+ text: "Dark-Mode",
+ id: "dark_mode",
+ description: "Ändert das Aussehen zu einem dunklen Design!",
+ collision: ["pink_mode"],
+ children: [
+ {
+ text: "Pink-Mode",
+ description: "Ändert das Aussehen zu einem pinken Design!",
+ id: "pink_mode",
+ collision: ["dark_mode"],
+ },
+ {
+ text: "Accent-Color",
+ description: "Verändere die Primärfarbe",
+ id: "accent_color",
+ call: `chooseAccentColor();`,
+ call_unset: `unsetAccentColor()`
+ }
+ ]
+ },
+ {
+ text: "Profilbild",
+ id: "profile_pic",
+ description: "Erlange die Fähigkeit, das Profilbild zu ändern",
+ children: [
+ {
+ text: "Einfacher Rahmen",
+ id: "simple_border",
+ description: "Ein einfacher Rahmen, der sich um das Profilbild legt",
+ collision: ["gold_border", "epic_border"],
+ children: [
+ {
+ text: "Gold-Rahmen",
+ id: "gold_border",
+ description: "Ein goldener Rahmen, der sich um das Profilbild legt",
+ collision: ["simple_border", "epic_border"],
+ children: []
+ },
+ {
+ text: "Epic-Rahmen",
+ id: "epic_border",
+ description: "Ein epischer Rahmen, der sich um das Profilbild legt",
+ collision: ["simple_border", "gold_border"],
+ children: [
+ {
+ text: "Ehren-Titel",
+ id: "title_of_honor",
+ description: "Kriege den Ehrentitel \"Sir\" verliehen"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ }
+ ]
+});
+
+const _skillCb = {
+ "dark_mode": function() {
+ document.body.style = "background: black; color: white;";
+ },
+ "dark_mode_unset": function() {
+ document.body.style = "background: unset; color: unset;";
+ },
+ "pink_mode": function() {
+ document.body.style = `background: rgba(242, 199, 252, 1); color: #5a076d;`;
+ },
+ "pink_mode_unset": function() {
+ _skillCb.dark_mode_unset();
+ },
+ "accent_color": function() {
+ const storage = (userData.skillStorage ??= {})["accent_color"];
+ if (!storage) return;
+
+ const rgb = storage.join(",");
+
+ setRootStyle("--accent_color_fg", `rgba(${rgb}, 1)`);
+ setRootStyle("--accent_color_fg_o", `rgba(${rgb}, 0.5)`);
+
+ setRootStyle("--accent_color_bg", `rgba(${rgb}, 1)`);
+ setRootStyle("--accent_color_bg_o", `rgba(${rgb}, 0.5)`);
+ setRootStyle("--accent_color_bg_o2", `rgba(${rgb}, 0.25)`);
+ },
+ "accent_color_unset": function() {
+ removeRootStyle("--accent_color_fg");
+ removeRootStyle("--accent_color_fg_o");
+
+ removeRootStyle("--accent_color_bg");
+ removeRootStyle("--accent_color_bg_o");
+ removeRootStyle("--accent_color_bg_o2");
+ },
+ "simple_border": function() {
+ setProfileBorder("../imgs/simple_border.png", 8);
+ },
+ "unset_simple_border": () => unsetProfileBorder(),
+ "gold_border": function() {
+ setProfileBorder("../imgs/gold_border.png", 8);
+ },
+ "unset_gold_border": () => unsetProfileBorder(),
+ "epic_border": function() {
+ setProfileBorder("../imgs/epic_border.png", 8);
+ },
+ "unset_epic_border": () => unsetProfileBorder(),
+ "title_of_honor": function() {},
+ "profile_pic": () => updateAllProfiles(userData)
+};
+
+function chooseAccentColor() {
+ var elm = getId("skill_chooseAccentColor");
+ if (!elm) {
+ elm = document.createElement("overlay");
+ elm.setAttribute("id", "skill_chooseAccentColor");
+ elm.innerHTML = `
+Wähle eine Farbe:
+
+
+ `;
+ document.body.appendChild(elm);
+ }
+
+ setTimeout(() => showOverlay("skill_chooseAccentColor"), 1);
+}
+function unsetAccentColor() {
+ userData.skillStorage ??= {};
+ userData.skillStorage["accent_color"] = null;
+ updateUserData(new CouchDB());
+}
+function setAccentColor(elm) {
+ const input = elm.parentElement.querySelector("input");
+ const rgba = hexToRGBA(input.value);
+
+ userData.skillStorage ??= {};
+ userData.skillStorage["accent_color"] = rgba;
+
+ updateUserData(new CouchDB());
+
+ hideOverlay("skill_chooseAccentColor");
+ _skillCb.accent_color();
+ refreshOverlays();
+}
+
+
+
+//--------------------------------------------//
+
+function unsetProfileBorder() {
+ const elms = document.getElementsByClassName("profile");
+ for (var i of elms) i.innerHTML = '';
+}
+function setProfileBorder(src, x) {
+ const elms = document.getElementsByClassName("profile");
+
+ const style1 = `
+width: 67px;
+height: 67px;
+border-radius: 50%;
+border: none;
+background-size: 67px 67px;
+position: absolute;
+background-image: url('${src}');
+transform: translate(-${x}px, calc(-50%));
+ `;
+
+ for (var i of elms) {
+ i.innerHTML = ``;
+ }
+
+ const style2 = `
+width: 160px;
+height: 160px;
+border-radius: 50%;
+border: none;
+background-size: 160px 160px;
+position: absolute;
+background-image: url('${src}');
+transform: translate(-${x*1.2}px, -8px);
+ `;
+
+ const profilPic = getId("profile-pic");
+ if (profilPic) {
+ profilPic.innerHTML = ``;
+ }
+}
+function setRootStyle(key, value) {
+ document.documentElement.style.setProperty(key, value);
+}
+function removeRootStyle(key) {
+ document.documentElement.style.removeProperty(key);
+}
+function exeSkill(id, activate = true) {
+ const cb = _skillCb[activate ? id: id+"_unset"];
+ if (typeof(cb) != "function") return;
+ try { cb(); } catch(err) { console.error(err); }
+}
+var globalSkills = [];
+async function runSkills() {
+ const skills = userData.enabled_abilities;
+ globalSkills = skills;
+ for (var i of skills) exeSkill(i, true);
+}
+userDataListener.push(runSkills);
\ No newline at end of file
diff --git a/student/skilltree.js b/other/skilltree.js
similarity index 90%
rename from student/skilltree.js
rename to other/skilltree.js
index 292748d..0f5c5c8 100644
--- a/student/skilltree.js
+++ b/other/skilltree.js
@@ -2,46 +2,6 @@
//=> use playLevelSound() -> void;
//=> use playXPSound() -> void;
-
-const getSkillTree = () => ({
- id: "root",
- text: "Skill-Tree",
- children: [
- {
- text: "DarkMode",
- id: "dark_mode",
- description: "Setzt die Theme auf dunkel!",
- children: [
- {
- text: "Bla",
- description: "Lorem ipsum et idk! Lorem ipsum et idk! Lorem ipsum et idk! Lorem ipsum et idk! Lorem ipsum et idk! Lorem ipsum et idk! Lorem ipsum et idk! Lorem ipsum et idk!",
- id: "pink_mode",
- children: []
- }
- ]
- },
- {
- text: "1",
- id: "1",
- description: "one",
- children: [
- {
- text: "2",
- id: "2",
- description: "two",
- children: []
- },
- {
- text: "3",
- id: "3",
- description: "three",
- children: []
- }
- ]
- }
- ]
-});
-
var aSkillPoints = 0;
function showSkillTree() {
@@ -52,6 +12,8 @@ function showSkillTree() {
document.body.appendChild(elm);
}
+ elm.innerHTML = ``;
+
const div = document.createElement("div");
div.style = `
display: inline-block;
@@ -60,6 +22,7 @@ height: 100%;
overflow: auto;
margin-top: 20px;
text-align: center;
+color: black;
`;
var res = generateSkillTree(getSkillTree(), userData.abilities)
@@ -77,7 +40,7 @@ text-align: center;
margin-top: 20px;
`;
div2.innerHTML = `
-
+
Skill-Points: ${aSkillPoints}
`;
@@ -99,7 +62,7 @@ function _getRect(parent, data) {
elm.innerHTML = '';
const div = document.createElement("div");
- div.style = `display: inline-block; width: 100%; min-width: 300px; text-align: center;`;
+ div.style = `display: inline-block; width: 100%; min-width: 300px; text-align: center; color: black;`;
div.innerHTML = `
${data.text}
${data.description}
@@ -138,15 +101,25 @@ async function activateSkill(elm, data) {
const isEnabled = eAblities.includes(data.id);
if (isEnabled) {
+ //disabled
userData.enabled_abilities = eAblities.filter((val) => val != data.id);
for (var elm of elms) {
elm.setAttribute("fill", "rgb(187, 243, 183)");
}
} else {
+ //enabled
+ const coll = data.collision ??= [];
+ userData.enabled_abilities = eAblities.filter((val) => !coll.includes(val));
userData.enabled_abilities.push(data.id);
for (var elm of elms) {
elm.setAttribute("fill", "lightgreen");
}
+ for (var i of coll) {
+ exeSkill(i, false);
+ for (var elm of document.getElementsByClassName("skill_" + i)) {
+ elm.setAttribute("fill", "rgb(187, 243, 183)");
+ }
+ }
}
elm.innerText = !isEnabled ? "Deaktivieren" : "Aktivieren";
@@ -154,6 +127,19 @@ async function activateSkill(elm, data) {
getOverlay("skill_tree_details_overlay").innerHTML = "";
await updateUserData(new CouchDB(), userData);
hideOverlay("skill_tree_details_overlay");
+
+ if (!isEnabled) {
+ if (typeof(data.call) == "string") {
+ try { eval(data.call); } catch (err) { console.error(err); }
+ }
+ }
+ exeSkill(data.id, !isEnabled);
+ if (isEnabled) {
+ if (typeof(data.call_unset) == "string") {
+ try { eval(data.call_unset); } catch (err) { console.error(err); }
+ }
+ }
+ refreshOverlays();
}
async function _buySkill(data) {
const elms = document.getElementsByClassName("skill_" + data.id);
@@ -170,6 +156,8 @@ async function _buySkill(data) {
userData.abilities.push(data.id);
+ playXPSound();
+
getOverlay("skill_tree_details_overlay").innerHTML = "";
await updateUserData(new CouchDB(), userData);
@@ -183,10 +171,11 @@ function generateSkillTree(skillTree, abilities) {
const lvlGap = 100;
const borderRadius = getComputedStyle(document.documentElement).getPropertyValue('--border-radius').trim();
const siblingGap = 40;
-
+
/* -------- calc layout -------- */
function measure_tree(data) {
+ data.children ??= [];
if (data.children.length === 0) {
data._width = nWidth;
} else {
@@ -196,6 +185,7 @@ function generateSkillTree(skillTree, abilities) {
}
return data._width;
}
+ measure_tree(skillTree);
function calc_tree(data, x, y) {
data._x = x;
@@ -211,7 +201,6 @@ function generateSkillTree(skillTree, abilities) {
});
}
- measure_tree(skillTree);
calc_tree(skillTree, 0, 0);
/* -------- bounding-stuff -------- */
diff --git a/prof/auswertung.html b/prof/auswertung.html
index a8d0e27..5c41a74 100644
--- a/prof/auswertung.html
+++ b/prof/auswertung.html
@@ -6,6 +6,8 @@
+
+