Add easter egg achievement

This commit is contained in:
2023-02-23 20:42:56 +01:00
parent 3a71bdf14e
commit 457bc459f2
8 changed files with 185 additions and 13 deletions

View File

@ -11,16 +11,25 @@
</div>
<Cookie />
<EastereggBanner ref="easteregg" />
</div>
</template>
<script setup lang="ts">
import { onMounted } from "vue";
import { onMounted, ref } from "vue";
import { RouterView } from "vue-router";
import { applyTheme } from "./utilities/theme_handler";
import Cookie from "@/components/cookie/Cookie.vue";
import EastereggBanner from "@/components/easteregg-banner/EastereggBanner.vue";
const easteregg = ref();
onMounted(() => {
applyTheme();
document.addEventListener("easteregg", (e) => {
// @ts-ignore
easteregg.value.show(e.detail);
});
})
</script>

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -5,16 +5,14 @@
<canvas ref="canvas_cookie" :width="canvas_width" :height="canvas_height"></canvas>
</div>
<div ref="banner" class="fixed bottom-0 left-0 z-50">
<div class="border bg-slate-200/90 border-slate-700 dark:bg-slate-800/90 dark:border-slate-400 rounded w-fit lg:w-1/2 p-5 m-5">
<p class="text-sm">{{ t("cookie policy title") }}</p>
<div class="text-xs">
<span>{{ t("cookie policy") }} <button :onclick="throwCookie" class="underline">{{ t("cookie policy link") }}</button></span>
</div>
<div class="flex justify-end mt-2 text-sm">
<button :onclick="refuseCookieBanner" class="mx-1 hover:text-slate-500 dark:hover:text-slate-300">{{ t("reject") }}</button>
<button :onclick="acceptCookieBanner" class="rounded p-2 mx-1 bg-slate-300 hover:bg-slate-400 dark:bg-slate-700 dark:hover:bg-slate-600">{{ t("accept") }}</button>
</div>
<div ref="banner" class="fixed bottom-0 left-0 z-50 border bg-slate-200/90 border-slate-700 dark:bg-slate-800/90 dark:border-slate-400 rounded w-fit lg:w-1/2 p-5 m-5">
<p class="text-sm">{{ t("cookie policy title") }}</p>
<div class="text-xs">
<span>{{ t("cookie policy") }} <button :onclick="throwCookie" class="underline">{{ t("cookie policy link") }}</button></span>
</div>
<div class="flex justify-end mt-2 text-sm">
<button :onclick="refuseCookieBanner" class="mx-1 hover:text-slate-500 dark:hover:text-slate-300">{{ t("reject") }}</button>
<button :onclick="acceptCookieBanner" class="rounded p-2 mx-1 bg-slate-300 hover:bg-slate-400 dark:bg-slate-700 dark:hover:bg-slate-600">{{ t("accept") }}</button>
</div>
</div>
@ -29,6 +27,7 @@
import { randomInt, random } from "@/utilities/random";
import { shouldShowCookie, acceptCookie, refuseCookie } from "@/utilities/cookie_handler";
import { useI18n } from "vue-i18n";
import { addFoundEasterEgg } from "@/utilities/easteregg_handler";
const { t } = useI18n({ messages: {
"en": {
@ -118,6 +117,7 @@
}
function throwCookie() {
addFoundEasterEgg("cookie");
if (!engine) { return; }
// Creates a cookie at the bottom of visible screen

View File

@ -0,0 +1,70 @@
<template>
<div class="fixed top-0 left-0 w-full pointer-events-none">
<div :class="`border rounded-sm p-3 px-5 my-2 mx-auto w-fit max-w-xs md:max-w-md pointer-events-auto
bg-slate-200/90 border-slate-700 dark:bg-slate-800/90 dark:border-slate-400
transition-opacity ${show_banner ? 'opacity-100 duration-300' : 'opacity-0 duration-200'}`"
@click="dismiss">
<div class="flex text-sm">
<div class="flex-1">
<CookieEgg v-if="easteregg === 'cookie'" />
<FutureEgg v-if="easteregg === 'future'" />
<div class="mt-1 text-center">
<p v-if="found_eastereggs != total_eastereggs">{{ found_eastereggs }}/{{ total_eastereggs }} {{ t("easter eggs found") }}</p>
<p v-if="found_eastereggs === total_eastereggs">{{ t("all easter eggs found") }}</p>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { useI18n } from "vue-i18n";
import { getFoundEasterEggsCount, getTotalEasterEggsCount } from "@/utilities/easteregg_handler";
import CookieEgg from "./eggs/Cookie.vue";
import FutureEgg from "./eggs/Future.vue";
const show_banner = ref(false);
const easteregg = ref("");
const total_eastereggs = ref(getTotalEasterEggsCount());
const found_eastereggs = ref(getFoundEasterEggsCount());
const { t } = useI18n({ messages: {
"en": {
"easter eggs found": "easter eggs found",
"all easter eggs found": "You found all the easter eggs 🥚"
},
"it": {
"easter eggs found": "easter egg trovati",
"all easter eggs found": "Hai trovato tutti gli easter egg 🥚"
}
} });
function show(easteregg_name:string) {
easteregg.value = easteregg_name;
found_eastereggs.value = getFoundEasterEggsCount();
console.log(getFoundEasterEggsCount())
show_banner.value = true;
setTimeout(() => {
dismiss();
}, 8000);
}
function dismiss() {
show_banner.value = false;
}
defineExpose({
show
})
</script>

View File

@ -0,0 +1,32 @@
<template>
<div class="flex justify-center text-sm">
<div class="flex items-center justify-center">
<div class="w-10 h-10 flex items-center justify-center overflow-hidden">
<img :src="image" alt="" class="h-full w-full" />
</div>
</div>
<div class="flex-1 ml-2">
<p class="font-bold text-base">{{ t("title") }}</p>
<p>{{ t("description") }}</p>
</div>
</div>
</template>
<script setup lang="ts">
import { useI18n } from "vue-i18n";
import image from "@/assets/images/cookie.png";
const { t } = useI18n({ messages: {
"en": {
"title": "Who wants a cookie?",
"description": "It appears that you read the cookie policy"
},
"it": {
"title": "Chi vuole un biscotto?",
"description": "Sembra che hai letto l'informativa cookie"
}
} });
</script>

View File

@ -0,0 +1,32 @@
<template>
<div class="flex text-sm">
<div class="flex items-center justify-center">
<div class="w-10 h-10 flex items-center justify-center overflow-hidden">
<img :src="image" alt="" class="h-full w-full" />
</div>
</div>
<div class="flex-1 ml-2">
<p class="font-bold text-base">{{ t("title") }}</p>
<p>{{ t("description") }}</p>
</div>
</div>
</template>
<script setup lang="ts">
import { useI18n } from "vue-i18n";
import image from "@/assets/images/future.png";
const { t } = useI18n({ messages: {
"en": {
"title": "Wonderful future",
"description": "What will happen?"
},
"it": {
"title": "Che bello il futuro",
"description": "Cosa ci riserverà?"
}
} });
</script>

View File

@ -0,0 +1,28 @@
const EASTER_EGGS = ["cookie", "future"];
export function addFoundEasterEgg(name:string):void {
if (!EASTER_EGGS.includes(name)) { return; }
let found_eastereggs = new Set( JSON.parse(localStorage.getItem("eastereggs") ?? "[]") );
const is_new = !found_eastereggs.has(name);
found_eastereggs.add(name);
localStorage.setItem("eastereggs", JSON.stringify([...found_eastereggs]));
if (is_new) {
// To trigger the banner
document.dispatchEvent(new CustomEvent("easteregg", { detail: name }));
}
}
export function getFoundEasterEggs():string[] {
return JSON.parse(localStorage.getItem("eastereggs") ?? "[]");
}
export function getFoundEasterEggsCount():number {
return getFoundEasterEggs().length;
}
export function getTotalEasterEggsCount():number {
return EASTER_EGGS.length;
}

View File

@ -1,7 +1,7 @@
<template>
<div class="flex h-full justify-center relative">
<div class="absolute top-0 left-0 w-full">
<div data-tooltip-target="tooltip-future" class="relative w-6 h-2 mx-auto z-50">
<div data-tooltip-target="tooltip-future" class="relative w-6 h-2 mx-auto z-50" @mouseover="() => addFoundEasterEgg('future')">
</div>
<div id="tooltip-future" role="tooltip"
class="absolute z-10 invisible inline-block px-2 py-1 text-xs font-medium transition-opacity duration-1000 rounded-lg opacity-0 tooltip">
@ -52,6 +52,7 @@
import locale from "./locale.js";
import { initTooltips } from "flowbite";
import { onMounted } from "vue";
import { addFoundEasterEgg } from "@/utilities/easteregg_handler";
const timeline_locale = locale;
// @ts-ignore