From 7ee2ba631df268e1f1297d1f6252819f2bf21116 Mon Sep 17 00:00:00 2001 From: Victor Westerlund Date: Wed, 27 Nov 2024 15:44:51 +0100 Subject: [PATCH] wip: 2024-11-27T07:41:46+0100 (1732689706) --- api/.env.example.ini | 1 + api/endpoints/playground/coffee/DELETE.php | 40 ++++++ api/endpoints/playground/coffee/GET.php | 40 ++++++ api/endpoints/playground/coffee/POST.php | 38 ++++++ api/src/Endpoints.php | 2 + api/src/databases/VLWdb.php | 1 + .../models/Playground/Coffee/Coffee.php | 9 ++ public/assets/css/pages/playground/index.css | 46 ++++++- .../playground/super-secret-settings.css | 15 ++- public/assets/js/pages/playground/index.js | 9 +- .../pages/playground/super-secret-settings.js | 4 +- public/playground/index.php | 117 +++++++++++++++++- public/playground/super-secret-settings.php | 4 +- 13 files changed, 312 insertions(+), 14 deletions(-) create mode 100644 api/endpoints/playground/coffee/DELETE.php create mode 100644 api/endpoints/playground/coffee/GET.php create mode 100644 api/endpoints/playground/coffee/POST.php create mode 100644 api/src/databases/models/Playground/Coffee/Coffee.php diff --git a/api/.env.example.ini b/api/.env.example.ini index 163a056..041aec5 100755 --- a/api/.env.example.ini +++ b/api/.env.example.ini @@ -5,4 +5,5 @@ pass = "" [databases] vlw = "" +playground = "" battlestation = "" \ No newline at end of file diff --git a/api/endpoints/playground/coffee/DELETE.php b/api/endpoints/playground/coffee/DELETE.php new file mode 100644 index 0000000..85f4ed3 --- /dev/null +++ b/api/endpoints/playground/coffee/DELETE.php @@ -0,0 +1,40 @@ +ruleset = new Ruleset(strict: true); + + $this->ruleset->GET([ + (new Rules(CoffeeModel::ID->value)) + ->required() + ->type(Type::NUMBER) + ]); + + parent::__construct(Databases::PLAYGROUND, $this->ruleset); + } + + public function main(): Response { + return $this->db->for(WorkActionsModel::TABLE)->delete($_POST) === true + ? new Response(RESP_DELETE_OK) + : new Response("D:", 500); + } + } \ No newline at end of file diff --git a/api/endpoints/playground/coffee/GET.php b/api/endpoints/playground/coffee/GET.php new file mode 100644 index 0000000..0219d37 --- /dev/null +++ b/api/endpoints/playground/coffee/GET.php @@ -0,0 +1,40 @@ +ruleset = new Ruleset(strict: true); + + parent::__construct(Databases::PLAYGROUND, $this->ruleset); + } + + public function main(): Response { + $result = $this->db + ->for(CoffeeModel::TABLE) + ->order([CoffeeModel::ID->value => "DESC"]) + ->select([ + CoffeeModel::ID->value + ]); + + return $result->num_rows > 0 + // Return entries as sequential array of integer timestamps + ? new Response(array_map(fn(array $value): int => $value[0], $result->fetch_all(MYSQLI_NUM))) + : new Response([], 404); + } + } \ No newline at end of file diff --git a/api/endpoints/playground/coffee/POST.php b/api/endpoints/playground/coffee/POST.php new file mode 100644 index 0000000..9bb3c68 --- /dev/null +++ b/api/endpoints/playground/coffee/POST.php @@ -0,0 +1,38 @@ +ruleset = new Ruleset(strict: true); + + $this->ruleset->GET([ + (new Rules(CoffeeModel::ID->value)) + ->type(Type::NUMBER) + ->default(time()) + ]); + + parent::__construct(Databases::PLAYGROUND, $this->ruleset); + } + + public function main(): Response { + return $this->db->for(CoffeeModel::TABLE)->insert($_POST) === true + ? new Response($_POST[CoffeeModel::ID->value], 201) + : new Response(":(", 500); + } + } \ No newline at end of file diff --git a/api/src/Endpoints.php b/api/src/Endpoints.php index 7ce9a17..6659911 100644 --- a/api/src/Endpoints.php +++ b/api/src/Endpoints.php @@ -15,6 +15,8 @@ case WORK_TAGS = "/work/tags"; case WORK_ACTIONS = "/work/actions"; + case PLAYGROUND_COFFEE = "/playground/coffee"; + case BATTLESTATION = "/battlestation"; case BATTLESTATION_MB = "/battlestation/mb"; case BATTLESTATION_CPU = "/battlestation/cpu"; diff --git a/api/src/databases/VLWdb.php b/api/src/databases/VLWdb.php index 5286539..e2b4ef1 100755 --- a/api/src/databases/VLWdb.php +++ b/api/src/databases/VLWdb.php @@ -11,6 +11,7 @@ enum Databases: string { case VLW = "vlw"; + case PLAYGROUND = "playground"; case BATTLESTATION = "battlestation"; } diff --git a/api/src/databases/models/Playground/Coffee/Coffee.php b/api/src/databases/models/Playground/Coffee/Coffee.php new file mode 100644 index 0000000..67262a4 --- /dev/null +++ b/api/src/databases/models/Playground/Coffee/Coffee.php @@ -0,0 +1,9 @@ + { +new Elevent("click", document.querySelector("section.sss button"), (event) => { const SSS_TAG_NAME = "super-secret-settings"; let sssElement = document.querySelector(SSS_TAG_NAME); @@ -11,6 +11,13 @@ new Elevent("click", document.querySelector("section.sss button"), () => { document.body.appendChild(sssElement); } + const size = event.target.getBoundingClientRect(); + + // Set initial window position above button + const y = size.top; + const x = size.left + size.width; + sssElement.style.transform = `translate(${x}px, ${y}px)` + // Navigate SSS element to playground page new vegvisir.Navigation("/playground/super-secret-settings").navigate(sssElement); }); \ No newline at end of file diff --git a/public/assets/js/pages/playground/super-secret-settings.js b/public/assets/js/pages/playground/super-secret-settings.js index 6823edb..03fa909 100644 --- a/public/assets/js/pages/playground/super-secret-settings.js +++ b/public/assets/js/pages/playground/super-secret-settings.js @@ -8,6 +8,7 @@ const clampRight = (window.innerWidth - sssElement._size.width) - (borderWidth * const clampBottom = (window.innerHeight - sssElement._size.height) - (borderWidth * 3); const moveWindow = new Elevent("mousemove", null, (event) => { + // Clamp window to viewport const y = Math.max(borderWidth, Math.min(clampBottom, (event.clientY - 40))); const x = Math.max(borderWidth, Math.min(clampRight, event.clientX - (sssElement._size.width / 2))); @@ -34,4 +35,5 @@ new Elevent("mousedown", sssElement.querySelector(".header"), (event) => { }); }); -new Elevent("click", sssElement.querySelector(".header button"), () => sssElement.remove()); \ No newline at end of file +new Elevent("click", sssElement.querySelector(".header button.close"), () => sssElement.remove()); +new Elevent("click", sssElement.querySelector(".header button.collapse"), () => sssElement.classList.toggle("collapsed")); \ No newline at end of file diff --git a/public/playground/index.php b/public/playground/index.php index 06fbd62..9606726 100644 --- a/public/playground/index.php +++ b/public/playground/index.php @@ -1,20 +1,129 @@ +format("G"); + } + + public function minutes(): int { + return (int) $this->format("i"); + } + + public function since_midnight_str(): string { + $hours = $this->hours(); + $minutes = $this->minutes(); + + // Show minutes if we're not into the first hour yet + if ($hours < 1) { + return $minutes . " minute" . to_plural($minutes); + } + + // Round up to the nearest hour + return ($minutes < 45 ? $hours : $hours + 1) . " hour" . to_plural($hours); + } + }; + + $coffee = new class extends API { + const THRESHOLDS = [ + [-10, "a lot less than"], + [-5, "a bit less than"], + [0, "average"], + [5, "a bit more than"], + [10, "a lot more than"] + ]; + + private readonly int $now; + private readonly Response $resp; + + public function __construct() { + parent::__construct(); + + $this->now = time(); + $this->resp = $this->call(Endpoints::PLAYGROUND_COFFEE->value)->get(); + } + + private function get_until_timestamp(int $offset = 0): array { + return array_filter($this->resp->json(), fn(int $timestamp): int => $timestamp > $offset); + } + + private function get_average_month(): int { + $days = [0]; + + foreach ($this->get_until_timestamp(2592000) as $timestamp) { + // Append new value for next 24 hours + if ($timestamp % 86400 === 0) { + $days[] = 0; + } + + $days[count($days) - 1]++; + } + + // Count the average for each day + return array_sum($days) / count($days); + } + + // Return the number of cups within the last 24 hours + public function get_today(): int { + return $this->resp->ok ? count($this->get_until_timestamp(86400)) : 0; + } + + public function get_average_month_str(): string { + $diff = $this->get_today() - $this->get_average_month(); + + // Check diff of today against monthyl average thresholds + foreach (self::THRESHOLDS as $threshold) { + [$limit, $msg] = $threshold; + + // Bail out if diff is less than threshold limit + if ($diff < $limit) { + return $msg; + } + } + + // Return last entry if diff is more than last threshold limit + return self::THRESHOLDS[count(self::THRESHOLDS) - 1][1]; + } + }; + +?>
- + $char): ?> " style="animation-delay:ms">
- +

I'm so bored.

+

Don't like the way my website looks? These oficially very Super Secret Settings will give you something else to look at!

+
">
-

How much coffee is enough coffee?

-

Woah, I 've had 4 cups of coffee today (counting from and to midnight). That's about the average amount for me (from the last 30 days)

+

What else.. I've had get_today() ?> cupget_today()) ?> of coffee today!

+

That's get_average_month_str() ?> the daily average for me (last 30 days). Here I'm counting how many ~300ml cups of coffee I've had since midnight for my timezone , that was since_midnight_str() ?> ago.

+

How much coffee is enough coffee? value ?>">Click here to see my answer!! (NOT CLICKBAIT). Each array value is a UNIX timestamp that represents a single cup of coffee.

\ No newline at end of file diff --git a/public/playground/super-secret-settings.php b/public/playground/super-secret-settings.php index 43f1e32..0924301 100644 --- a/public/playground/super-secret-settings.php +++ b/public/playground/super-secret-settings.php @@ -1,8 +1,8 @@

Super Secret Settings

- - + +

Do you have what it takes to click this button?