This commit is contained in:
Turtle committed 2025-12-19 12:06:38 +01:00
1 parent 75e445ef91
commit c84cd0f9f2
6 files changed
+338 -67

No files matched your search

+171
View File
@@ -0,0 +1,171 @@
:root {
--accent_color_fg: #007bff;
--accent_color_bg: rgba(137, 197, 221, 1);
--accent_color_bg_o: rgba(137, 197, 221, 0.5);
--main_color_fg: white;
--main_color_bg: black;
--border-radius: 10px;
--def-shadow: 10px 20px 20px rgb(128, 128, 128, 0.5);
}
* {
box-sizing: border-box;
outline-style: none;
}
body, html {
height: 100%;
margin: 0;
font-family: Arial, Helvetica, sans-serif;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
overscroll-behavior: none;
touch-action: pan-x pan-y;
font-size: 20px;
}
::selection {
background-color: var(--accent_color_fg);
color: black;
}
selectable {
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
}
/* ----------- elements ----------- */
.profile {
width: 58px;
height: 58px;
border-radius: 50%;
background: var(--accent_color_bg);
border: none;
}
/* ----------- overlay ----------- */
overlay {
display: none;
}
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 100;
}
.overlay > div:first-child {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.2);
backdrop-filter: blur(1px);
}
.overlay > div:last-child {
position: fixed;
top: 50%;
left: 50%;
min-width: 250px;
min-height: 150px;
transform: translate(-50%, -50%);
background: var(--accent_color_bg_o);
backdrop-filter: blur(10px);
border-radius: var(--border-radius);
padding: 15px;
text-align: center;
overflow-x: hidden;
overflow-y: auto;
box-shadow: var(--def-shadow);
}
.overlay > div:last-child > .close {
position: absolute;
top: 8px;
right: 8px;
width: 40px;
height: 40px;
background: var(--accent_color_bg);
border-radius: var(--border-radius);
border: none;
font-size: 20px;
font-weight: 600;
}
/* ----------- headerbar ----------- */
.header_bar_1 {
position: fixed;
top: 0%;
left: 50%;
transform: translateX(-50%);
width: 100%;
background: var(--accent_color_bg_o);
backdrop-filter: blur(10px);
padding: 15px;
box-shadow: var(--def-shadow);
height: 75px;
align-items: center;
display: flex;
flex-direction: row;
}
.header_bar_1 > div {
display: table-cell;
}
.header_bar_1 > div:nth-child(1) {
text-align: left;
}
.header_bar_1 > div:nth-child(2) {
text-align: center;
width: 100%;
}
.header_bar_1 > div:nth-child(3) {
text-align: right;
}
.header_bar_1_placeholder {
height: 75px;
}
.header_bar_1_undocked {
width: 96%;
top: 2%;
border-radius: var(--border-radius);
animation: header_bar_1_undocked_ani 0.5s ease-in-out;
}
.header_bar_1_docked {
width: 100%;
animation: header_bar_1_docked_ani 0.5s ease-in-out;
}
content {
display: block;
padding: 15px;
}
@keyframes header_bar_1_undocked_ani {
from {
width: 100%;
top: 0;
border-radius: 0;
}
to {
width: 96%;
top: 2%;
border-radius: var(--border-radius);
}
}
@keyframes header_bar_1_docked_ani {
from {
width: 96%;
top: 2%;
border-radius: var(--border-radius);
}
to {
width: 100%;
top: 0;
border-radius: 0;
}
}
+230
View File
@@ -0,0 +1,230 @@
const getId = (id) => document.getElementById(id);
function showOverlay(id) {
const elm = getId(id);
const overlay = document.createElement("div");
overlay.classList.add("overlay");
overlay.setAttribute("name", id);
overlay.innerHTML = `
<div onclick="_onOverlayDestroy(this.parentElement);"></div>
<div>
<button class="close" onclick="_onOverlayDestroy(this.parentElement.parentElement);">x</button>
${elm.innerHTML}
</div>
`;
document.body.appendChild(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 <script src="./auth.js"></script>';
}
_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);
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
};
}
}
}