From b85899617b799ab2122a2f5b8522aa49ab99da1e Mon Sep 17 00:00:00 2001 From: Pihkaal Date: Wed, 17 Dec 2025 12:28:48 +0100 Subject: [PATCH] feat(assets): new assets loading system (currently only for images) --- .gitignore | 6 +- app/components/Common/ButtonSelector.vue | 12 +- .../Contact/BottomScreen/Background.vue | 12 +- app/components/Contact/BottomScreen/Bars.vue | 20 ++- .../Contact/BottomScreen/Buttons.vue | 6 +- .../Contact/TopScreen/Background.vue | 12 +- app/components/Contact/TopScreen/LeftBar.vue | 12 +- .../Contact/TopScreen/Notifications.vue | 12 +- .../Home/BottomScreen/Background.vue | 6 +- .../BottomScreen/Buttons/ContactButton.vue | 6 +- .../Buttons/DownloadPlayButton.vue | 10 +- .../Home/BottomScreen/Buttons/GameButton.vue | 6 +- .../BottomScreen/Buttons/SettingsButton.vue | 6 +- app/components/Home/TopScreen/Background.vue | 6 +- app/components/Home/TopScreen/Calendar.vue | 28 ++-- app/components/Home/TopScreen/Clock.vue | 6 +- app/components/Home/TopScreen/StatusBar.vue | 21 +-- .../Projects/BottomScreen/Background.vue | 6 +- .../Projects/BottomScreen/Buttons.vue | 46 +++---- .../Projects/TopScreen/Background.vue | 6 +- app/components/Projects/TopScreen/Project.vue | 14 +- .../Settings/BottomScreen/Background.vue | 16 +-- .../BottomScreen/Menus/Clock/Menu.vue | 39 ++---- .../BottomScreen/Menus/Options/Menu.vue | 39 ++---- .../BottomScreen/Menus/TouchScreen/Menu.vue | 20 +-- .../Settings/BottomScreen/Menus/User/Menu.vue | 44 ++---- .../Settings/TopScreen/Background.vue | 6 +- .../Settings/TopScreen/Calendar.vue | 28 ++-- app/components/Settings/TopScreen/Clock.vue | 6 +- .../Settings/TopScreen/Notifications.vue | 50 ++----- .../Settings/TopScreen/StatusBar.vue | 21 +-- app/composables/useAssets.ts.in | 34 +++++ app/composables/useImages.ts | 17 --- app/pages/test.vue | 8 ++ app/stores/projects.ts | 4 +- modules/content-assets.ts | 5 +- modules/image-assets.ts | 128 ++++++++++++++++++ nuxt.config.ts | 1 + .../contact/bottom-screen/background.webp | Bin .../contact/bottom-screen/bottom-bar.webp | Bin .../images/contact/bottom-screen/buttons.webp | Bin .../contact/bottom-screen/notification.webp | Bin .../contact/bottom-screen/ok-button.webp | Bin .../images/contact/bottom-screen/top-bar.webp | Bin .../images/contact/top-screen/background.webp | Bin .../contact/top-screen/left-bar-things.webp | Bin .../images/contact/top-screen/left-bar.webp | Bin .../images/contact/top-screen/title.webp | Bin .../images/home/bottom-screen/background.webp | Bin .../home/bottom-screen/buttons/alarm.webp | Bin .../home/bottom-screen/buttons/contact.webp | Bin .../home/bottom-screen/buttons/corner.webp | Bin .../bottom-screen/buttons/downloadPlay.webp | Bin .../home/bottom-screen/buttons/game.webp | Bin .../home/bottom-screen/buttons/settings.webp | Bin .../home/bottom-screen/buttons/theme.webp | Bin .../images/home/top-screen/background.webp | Bin .../home/top-screen/calendar/calendar.webp | Bin .../top-screen/calendar/day-selector.webp | Bin .../home/top-screen/calendar/last-row.webp | Bin .../images/home/top-screen/clock.webp | Bin .../home/top-screen/status-bar/battery.webp | Bin .../top-screen/status-bar/gba-display.webp | Bin .../top-screen/status-bar/startup-mode.webp | Bin .../top-screen/status-bar/status-bar.webp | Bin public/images/projects/biobleud.webp | Bin 0 -> 58 bytes .../projects/bottom-screen/background.webp | Bin .../projects/bottom-screen/circle_big.webp | Bin .../projects/bottom-screen/circle_small.webp | Bin .../projects/bottom-screen/link-pressed.webp | Bin .../projects/bottom-screen/next-pressed.webp | Bin .../projects/bottom-screen/prev-pressed.webp | Bin .../projects/bottom-screen/quit-pressed.webp | Bin public/images/projects/lbf-bot.webp | Bin 0 -> 456 bytes public/images/projects/lilou-cat.webp | Bin 0 -> 598 bytes public/images/projects/pihkaal-me.webp | Bin 0 -> 442 bytes public/images/projects/raylib-speedruns.webp | Bin 0 -> 478 bytes public/images/projects/s3pweb.webp | Bin 0 -> 624 bytes public/images/projects/simple-qr.webp | Bin 0 -> 910 bytes public/images/projects/tlock.webp | Bin 0 -> 660 bytes .../projects/top-screen/background.webp | Bin .../settings/bottom-screen/bottom-bar.webp | Bin .../settings/bottom-screen/top-bar.webp | Bin .../settings/top-screen/clock/alarm.webp | Bin .../top-screen/clock/clock-active.webp | Bin .../top-screen/clock/clock-disabled.png | Bin .../settings/top-screen/clock/clock.webp | Bin .../settings/top-screen/clock/date.webp | Bin .../settings/top-screen/clock/time.webp | Bin .../settings/top-screen/notification.webp | Bin .../settings/top-screen/options/gba-mode.webp | Bin .../settings/top-screen/options/language.webp | Bin .../top-screen/options/options-active.png | Bin .../top-screen/options/options-disabled.png | Bin .../settings/top-screen/options/options.webp | Bin .../settings/top-screen/options/start-up.webp | Bin .../images/settings/top-screen/settings.webp | Bin .../touch_screen/touch-screen-disabled.png | Bin .../top-screen/touch_screen/touch-screen.webp | Bin .../settings/top-screen/user/birthday.webp | Bin .../settings/top-screen/user/color.webp | Bin .../settings/top-screen/user/message.webp | Bin .../settings/top-screen/user/user-active.webp | Bin .../top-screen/user/user-disabled.png | Bin .../settings/top-screen/user/user-name.webp | Bin .../images/settings/top-screen/user/user.webp | Bin 106 files changed, 359 insertions(+), 366 deletions(-) create mode 100644 app/composables/useAssets.ts.in delete mode 100644 app/composables/useImages.ts create mode 100644 app/pages/test.vue create mode 100644 modules/image-assets.ts rename {app/assets => public}/images/contact/bottom-screen/background.webp (100%) rename {app/assets => public}/images/contact/bottom-screen/bottom-bar.webp (100%) rename {app/assets => public}/images/contact/bottom-screen/buttons.webp (100%) rename {app/assets => public}/images/contact/bottom-screen/notification.webp (100%) rename {app/assets => public}/images/contact/bottom-screen/ok-button.webp (100%) rename {app/assets => public}/images/contact/bottom-screen/top-bar.webp (100%) rename {app/assets => public}/images/contact/top-screen/background.webp (100%) rename {app/assets => public}/images/contact/top-screen/left-bar-things.webp (100%) rename {app/assets => public}/images/contact/top-screen/left-bar.webp (100%) rename {app/assets => public}/images/contact/top-screen/title.webp (100%) rename {app/assets => public}/images/home/bottom-screen/background.webp (100%) rename {app/assets => public}/images/home/bottom-screen/buttons/alarm.webp (100%) rename {app/assets => public}/images/home/bottom-screen/buttons/contact.webp (100%) rename {app/assets => public}/images/home/bottom-screen/buttons/corner.webp (100%) rename {app/assets => public}/images/home/bottom-screen/buttons/downloadPlay.webp (100%) rename {app/assets => public}/images/home/bottom-screen/buttons/game.webp (100%) rename {app/assets => public}/images/home/bottom-screen/buttons/settings.webp (100%) rename {app/assets => public}/images/home/bottom-screen/buttons/theme.webp (100%) rename {app/assets => public}/images/home/top-screen/background.webp (100%) rename {app/assets => public}/images/home/top-screen/calendar/calendar.webp (100%) rename {app/assets => public}/images/home/top-screen/calendar/day-selector.webp (100%) rename {app/assets => public}/images/home/top-screen/calendar/last-row.webp (100%) rename {app/assets => public}/images/home/top-screen/clock.webp (100%) rename {app/assets => public}/images/home/top-screen/status-bar/battery.webp (100%) rename {app/assets => public}/images/home/top-screen/status-bar/gba-display.webp (100%) rename {app/assets => public}/images/home/top-screen/status-bar/startup-mode.webp (100%) rename {app/assets => public}/images/home/top-screen/status-bar/status-bar.webp (100%) create mode 100644 public/images/projects/biobleud.webp rename {app/assets => public}/images/projects/bottom-screen/background.webp (100%) rename {app/assets => public}/images/projects/bottom-screen/circle_big.webp (100%) rename {app/assets => public}/images/projects/bottom-screen/circle_small.webp (100%) rename {app/assets => public}/images/projects/bottom-screen/link-pressed.webp (100%) rename {app/assets => public}/images/projects/bottom-screen/next-pressed.webp (100%) rename {app/assets => public}/images/projects/bottom-screen/prev-pressed.webp (100%) rename {app/assets => public}/images/projects/bottom-screen/quit-pressed.webp (100%) create mode 100644 public/images/projects/lbf-bot.webp create mode 100644 public/images/projects/lilou-cat.webp create mode 100644 public/images/projects/pihkaal-me.webp create mode 100644 public/images/projects/raylib-speedruns.webp create mode 100644 public/images/projects/s3pweb.webp create mode 100644 public/images/projects/simple-qr.webp create mode 100644 public/images/projects/tlock.webp rename {app/assets => public}/images/projects/top-screen/background.webp (100%) rename {app/assets => public}/images/settings/bottom-screen/bottom-bar.webp (100%) rename {app/assets => public}/images/settings/bottom-screen/top-bar.webp (100%) rename {app/assets => public}/images/settings/top-screen/clock/alarm.webp (100%) rename {app/assets => public}/images/settings/top-screen/clock/clock-active.webp (100%) rename {app/assets => public}/images/settings/top-screen/clock/clock-disabled.png (100%) rename {app/assets => public}/images/settings/top-screen/clock/clock.webp (100%) rename {app/assets => public}/images/settings/top-screen/clock/date.webp (100%) rename {app/assets => public}/images/settings/top-screen/clock/time.webp (100%) rename {app/assets => public}/images/settings/top-screen/notification.webp (100%) rename {app/assets => public}/images/settings/top-screen/options/gba-mode.webp (100%) rename {app/assets => public}/images/settings/top-screen/options/language.webp (100%) rename {app/assets => public}/images/settings/top-screen/options/options-active.png (100%) rename {app/assets => public}/images/settings/top-screen/options/options-disabled.png (100%) rename {app/assets => public}/images/settings/top-screen/options/options.webp (100%) rename {app/assets => public}/images/settings/top-screen/options/start-up.webp (100%) rename {app/assets => public}/images/settings/top-screen/settings.webp (100%) rename {app/assets => public}/images/settings/top-screen/touch_screen/touch-screen-disabled.png (100%) rename {app/assets => public}/images/settings/top-screen/touch_screen/touch-screen.webp (100%) rename {app/assets => public}/images/settings/top-screen/user/birthday.webp (100%) rename {app/assets => public}/images/settings/top-screen/user/color.webp (100%) rename {app/assets => public}/images/settings/top-screen/user/message.webp (100%) rename {app/assets => public}/images/settings/top-screen/user/user-active.webp (100%) rename {app/assets => public}/images/settings/top-screen/user/user-disabled.png (100%) rename {app/assets => public}/images/settings/top-screen/user/user-name.webp (100%) rename {app/assets => public}/images/settings/top-screen/user/user.webp (100%) diff --git a/.gitignore b/.gitignore index afa9c3d..ffcba71 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,6 @@ # generated -public/images/projects - -# temporary -__old +public/images/projects/pokemons +app/composables/useAssets.ts # ESlint .eslintcache diff --git a/app/components/Common/ButtonSelector.vue b/app/components/Common/ButtonSelector.vue index 5dd9b61..564ad31 100644 --- a/app/components/Common/ButtonSelector.vue +++ b/app/components/Common/ButtonSelector.vue @@ -1,6 +1,4 @@ + + diff --git a/app/stores/projects.ts b/app/stores/projects.ts index 0ae0fb2..2843842 100644 --- a/app/stores/projects.ts +++ b/app/stores/projects.ts @@ -38,7 +38,9 @@ export const useProjectsStore = defineStore("projects", { if (!projects.value) throw "Cannot load projects"; this.projects = projects.value.map((project) => ({ ...project, - id: project.id.split("/")[2]!, + id: project.id + .split("/")[2]! + .replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()), })); console.log(this.projects); diff --git a/modules/content-assets.ts b/modules/content-assets.ts index 008e149..d7184f8 100644 --- a/modules/content-assets.ts +++ b/modules/content-assets.ts @@ -13,7 +13,10 @@ export default defineNuxtModule({ async setup(_, nuxt) { const logger = useLogger("content-assets"); const contentDir = join(nuxt.options.rootDir, "content"); - const publicDir = join(nuxt.options.rootDir, "public/images/projects"); + const publicDir = join( + nuxt.options.rootDir, + "public/images/projects/pokemons", + ); const getFileChecksum = async (filePath: string): Promise => { const content = await readFile(filePath); diff --git a/modules/image-assets.ts b/modules/image-assets.ts new file mode 100644 index 0000000..4e7697b --- /dev/null +++ b/modules/image-assets.ts @@ -0,0 +1,128 @@ +import { defineNuxtModule, useLogger } from "@nuxt/kit"; +import { readdir, readFile, writeFile } from "fs/promises"; +import { join, relative, parse } from "path"; +import { existsSync, watch } from "fs"; + +type AssetsTree = { + [key: string]: string | AssetsTree; +}; + +const IMAGE_EXTENSIONS = new Set([".png", ".jpg", ".jpeg", ".webp", ".gif"]); + +export default defineNuxtModule({ + meta: { + name: "image-assets", + configKey: "imageAssets", + }, + defaults: {}, + async setup(_, nuxt) { + const logger = useLogger("image-assets"); + const publicImagesDir = join(nuxt.options.rootDir, "public/images"); + const templateFile = join( + nuxt.options.rootDir, + "app/composables/useAssets.ts.in", + ); + const outputFile = join( + nuxt.options.rootDir, + "app/composables/useAssets.ts", + ); + + const isImageFile = (filename: string): boolean => { + const ext = parse(filename).ext.toLowerCase(); + return IMAGE_EXTENSIONS.has(ext); + }; + + const scanDirectory = async (dir: string): Promise => { + const images: string[] = []; + const entries = await readdir(dir, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = join(dir, entry.name); + if (entry.isDirectory()) { + images.push(...(await scanDirectory(fullPath))); + } else if (isImageFile(entry.name)) { + images.push(fullPath); + } + } + + return images; + }; + + const toCamelCase = (str: string): string => { + return str.replace(/[-_](.)/g, (_, c) => c.toUpperCase()); + }; + + const buildAssetsTree = (images: string[], baseDir: string): AssetsTree => { + const tree: AssetsTree = {}; + + for (const imagePath of images) { + const relativePath = relative(baseDir, imagePath); + const parts = relativePath.split("/"); + const filename = parse(parts[parts.length - 1]!).name; + + let current = tree; + for (let i = 0; i < parts.length - 1; i += 1) { + const key = toCamelCase(parts[i]!); + current[key] ??= {}; + current = current[key] as AssetsTree; + } + + current[toCamelCase(filename)] = `/images/${relativePath}`; + } + + return tree; + }; + + const generateAssetsObject = (tree: AssetsTree, indent = 0): string => { + const spaces = " ".repeat(indent); + const entries = Object.entries(tree); + if (!entries.length) return "{}"; + + const lines = entries.map(([key, value]) => + typeof value === "string" + ? `${spaces} ${key}: createImage("${value}"),` + : `${spaces} ${key}: ${generateAssetsObject(value, indent + 1)},`, + ); + + return `{\n${lines.join("\n")}\n${spaces}}`; + }; + + const generateAssetsFile = async () => { + try { + if (!existsSync(publicImagesDir)) { + logger.warn("No public/images directory found"); + return; + } + + const images = await scanDirectory(publicImagesDir); + const assetsTree = buildAssetsTree(images, publicImagesDir); + const assetsObject = generateAssetsObject(assetsTree); + + const template = await readFile(templateFile, "utf-8"); + const fileContent = template + .replace("{{TOTAL}}", images.length.toString()) + .replace("{{ASSETS}}", assetsObject); + + await writeFile(outputFile, fileContent, "utf-8"); + logger.success(`Generated useAssets.ts with ${images.length} images`); + } catch (error) { + logger.error("Error generating assets file:", error); + } + }; + + nuxt.hook("build:before", async () => { + await generateAssetsFile(); + }); + + if (nuxt.options.dev) { + nuxt.hook("ready", () => { + watch(publicImagesDir, { recursive: true }, async (_, filePath) => { + if (filePath && isImageFile(filePath)) { + logger.info(`Detected change: ${filePath}`); + await generateAssetsFile(); + } + }); + }); + } + }, +}); diff --git a/nuxt.config.ts b/nuxt.config.ts index 7fda4be..f8aa02d 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -7,6 +7,7 @@ export default defineNuxtConfig({ "@nuxt/content", "@pinia/nuxt", "./modules/content-assets", + "./modules/image-assets", "@nuxtjs/i18n", "@tresjs/nuxt", ], diff --git a/app/assets/images/contact/bottom-screen/background.webp b/public/images/contact/bottom-screen/background.webp similarity index 100% rename from app/assets/images/contact/bottom-screen/background.webp rename to public/images/contact/bottom-screen/background.webp diff --git a/app/assets/images/contact/bottom-screen/bottom-bar.webp b/public/images/contact/bottom-screen/bottom-bar.webp similarity index 100% rename from app/assets/images/contact/bottom-screen/bottom-bar.webp rename to public/images/contact/bottom-screen/bottom-bar.webp diff --git a/app/assets/images/contact/bottom-screen/buttons.webp b/public/images/contact/bottom-screen/buttons.webp similarity index 100% rename from app/assets/images/contact/bottom-screen/buttons.webp rename to public/images/contact/bottom-screen/buttons.webp diff --git a/app/assets/images/contact/bottom-screen/notification.webp b/public/images/contact/bottom-screen/notification.webp similarity index 100% rename from app/assets/images/contact/bottom-screen/notification.webp rename to public/images/contact/bottom-screen/notification.webp diff --git a/app/assets/images/contact/bottom-screen/ok-button.webp b/public/images/contact/bottom-screen/ok-button.webp similarity index 100% rename from app/assets/images/contact/bottom-screen/ok-button.webp rename to public/images/contact/bottom-screen/ok-button.webp diff --git a/app/assets/images/contact/bottom-screen/top-bar.webp b/public/images/contact/bottom-screen/top-bar.webp similarity index 100% rename from app/assets/images/contact/bottom-screen/top-bar.webp rename to public/images/contact/bottom-screen/top-bar.webp diff --git a/app/assets/images/contact/top-screen/background.webp b/public/images/contact/top-screen/background.webp similarity index 100% rename from app/assets/images/contact/top-screen/background.webp rename to public/images/contact/top-screen/background.webp diff --git a/app/assets/images/contact/top-screen/left-bar-things.webp b/public/images/contact/top-screen/left-bar-things.webp similarity index 100% rename from app/assets/images/contact/top-screen/left-bar-things.webp rename to public/images/contact/top-screen/left-bar-things.webp diff --git a/app/assets/images/contact/top-screen/left-bar.webp b/public/images/contact/top-screen/left-bar.webp similarity index 100% rename from app/assets/images/contact/top-screen/left-bar.webp rename to public/images/contact/top-screen/left-bar.webp diff --git a/app/assets/images/contact/top-screen/title.webp b/public/images/contact/top-screen/title.webp similarity index 100% rename from app/assets/images/contact/top-screen/title.webp rename to public/images/contact/top-screen/title.webp diff --git a/app/assets/images/home/bottom-screen/background.webp b/public/images/home/bottom-screen/background.webp similarity index 100% rename from app/assets/images/home/bottom-screen/background.webp rename to public/images/home/bottom-screen/background.webp diff --git a/app/assets/images/home/bottom-screen/buttons/alarm.webp b/public/images/home/bottom-screen/buttons/alarm.webp similarity index 100% rename from app/assets/images/home/bottom-screen/buttons/alarm.webp rename to public/images/home/bottom-screen/buttons/alarm.webp diff --git a/app/assets/images/home/bottom-screen/buttons/contact.webp b/public/images/home/bottom-screen/buttons/contact.webp similarity index 100% rename from app/assets/images/home/bottom-screen/buttons/contact.webp rename to public/images/home/bottom-screen/buttons/contact.webp diff --git a/app/assets/images/home/bottom-screen/buttons/corner.webp b/public/images/home/bottom-screen/buttons/corner.webp similarity index 100% rename from app/assets/images/home/bottom-screen/buttons/corner.webp rename to public/images/home/bottom-screen/buttons/corner.webp diff --git a/app/assets/images/home/bottom-screen/buttons/downloadPlay.webp b/public/images/home/bottom-screen/buttons/downloadPlay.webp similarity index 100% rename from app/assets/images/home/bottom-screen/buttons/downloadPlay.webp rename to public/images/home/bottom-screen/buttons/downloadPlay.webp diff --git a/app/assets/images/home/bottom-screen/buttons/game.webp b/public/images/home/bottom-screen/buttons/game.webp similarity index 100% rename from app/assets/images/home/bottom-screen/buttons/game.webp rename to public/images/home/bottom-screen/buttons/game.webp diff --git a/app/assets/images/home/bottom-screen/buttons/settings.webp b/public/images/home/bottom-screen/buttons/settings.webp similarity index 100% rename from app/assets/images/home/bottom-screen/buttons/settings.webp rename to public/images/home/bottom-screen/buttons/settings.webp diff --git a/app/assets/images/home/bottom-screen/buttons/theme.webp b/public/images/home/bottom-screen/buttons/theme.webp similarity index 100% rename from app/assets/images/home/bottom-screen/buttons/theme.webp rename to public/images/home/bottom-screen/buttons/theme.webp diff --git a/app/assets/images/home/top-screen/background.webp b/public/images/home/top-screen/background.webp similarity index 100% rename from app/assets/images/home/top-screen/background.webp rename to public/images/home/top-screen/background.webp diff --git a/app/assets/images/home/top-screen/calendar/calendar.webp b/public/images/home/top-screen/calendar/calendar.webp similarity index 100% rename from app/assets/images/home/top-screen/calendar/calendar.webp rename to public/images/home/top-screen/calendar/calendar.webp diff --git a/app/assets/images/home/top-screen/calendar/day-selector.webp b/public/images/home/top-screen/calendar/day-selector.webp similarity index 100% rename from app/assets/images/home/top-screen/calendar/day-selector.webp rename to public/images/home/top-screen/calendar/day-selector.webp diff --git a/app/assets/images/home/top-screen/calendar/last-row.webp b/public/images/home/top-screen/calendar/last-row.webp similarity index 100% rename from app/assets/images/home/top-screen/calendar/last-row.webp rename to public/images/home/top-screen/calendar/last-row.webp diff --git a/app/assets/images/home/top-screen/clock.webp b/public/images/home/top-screen/clock.webp similarity index 100% rename from app/assets/images/home/top-screen/clock.webp rename to public/images/home/top-screen/clock.webp diff --git a/app/assets/images/home/top-screen/status-bar/battery.webp b/public/images/home/top-screen/status-bar/battery.webp similarity index 100% rename from app/assets/images/home/top-screen/status-bar/battery.webp rename to public/images/home/top-screen/status-bar/battery.webp diff --git a/app/assets/images/home/top-screen/status-bar/gba-display.webp b/public/images/home/top-screen/status-bar/gba-display.webp similarity index 100% rename from app/assets/images/home/top-screen/status-bar/gba-display.webp rename to public/images/home/top-screen/status-bar/gba-display.webp diff --git a/app/assets/images/home/top-screen/status-bar/startup-mode.webp b/public/images/home/top-screen/status-bar/startup-mode.webp similarity index 100% rename from app/assets/images/home/top-screen/status-bar/startup-mode.webp rename to public/images/home/top-screen/status-bar/startup-mode.webp diff --git a/app/assets/images/home/top-screen/status-bar/status-bar.webp b/public/images/home/top-screen/status-bar/status-bar.webp similarity index 100% rename from app/assets/images/home/top-screen/status-bar/status-bar.webp rename to public/images/home/top-screen/status-bar/status-bar.webp diff --git a/public/images/projects/biobleud.webp b/public/images/projects/biobleud.webp new file mode 100644 index 0000000000000000000000000000000000000000..74a29464492712f74e5bea6828160906f3498b01 GIT binary patch literal 58 zcmWIYbaOLeU|jjPc>q0qJYo;RX3v+f~h*^aU6$~PEd3U zs%L0~lye@lW&qln0z6|k4XMsKr-B6qtx4$BE}=#+trD9}E1_QPrx<`0s9BgTE3xSr zr|i2CTA>1Bwk%aMb>H_VSiuS^1#L;yOu^gR8sGxJ0^5;TGo4TG3aP3B5~>BZBBh#{ z>9_`EjaXR2HU!WNorC!L`nslo;1X=ctU8UZ=bYDI$VLRs1=p1^mJk|Jw*}3m5?zmB zg=$6HS@{^^>#0r)00julbQ9lLFr9*hupmoq?;Bu%3W3%zs|whdra^2LsjG4WW-c@9 y>(bU@)o+El)B=}bdu3t1m2@lL0JBf2=2};!TRG33rK{5HS5Lj5nHMngQg8sA@Xd1o literal 0 HcmV?d00001 diff --git a/public/images/projects/lilou-cat.webp b/public/images/projects/lilou-cat.webp new file mode 100644 index 0000000000000000000000000000000000000000..a68c9e2018ed87755bad70d363ebccf7db138299 GIT binary patch literal 598 zcmV-c0;&B{Nk&Fa0ssJ4MM6+kP&iCN0ssInSwI#Ll}K&?Ns^Schnpu}v@ifi@R2WO ztO-b65!s`ud~#$dBe`;o}yGSb;?f!?N!|c zN;l%(Wmr1-!kD+Hs>Ij>lBK=3lv0Kd9Ypd&48gk>Zio?Pq9!5T04PG4u|bp2LFlGu zdCNM9A(0dw81ee}0UFVgTVg(P{fHR00M;{oG- z|9%7z;^cb@YtY@055_L?wA3;)Ey2{vOa^6%@yNE$+aP9Xg%1VHd%2WoL2*o2rzv?+ zXz1!R<;t7p3o4Y3#>oxc&2ok;IFl1dFy<>KeiR{|`>HDAGf_Bd(1}r`aD;-K1m2k< k2DAaWfftk^#E+^jB}d{#kpA^>;;VH13*AeWkmAQU3liKMLI3~& literal 0 HcmV?d00001 diff --git a/public/images/projects/pihkaal-me.webp b/public/images/projects/pihkaal-me.webp new file mode 100644 index 0000000000000000000000000000000000000000..aefcfcad67204c26190e622e0cd425a4bc33e01e GIT binary patch literal 442 zcmV;r0Y&~&Nk&Gp0RRA3MM6+kP&iDb0RR9mSwI#Ll}K&?Ns<)Y!3Eq|S8#_XZt%pN zt7>|du6m=8Hb4>Dh?1FrNmhrG8l2RyrxiS{Vx(=P**JLc;B36DH{SmVz+Y3oRDJZ4 z>`3~W+Mmbj18_UCO)`acV%L`PvsdzyxBSD%^uWS9exSEz&Flt*(rX)b=LXwtPFm6kx z7hF;zrb;?40h$DmD{e#pkYsxx)+ELUoe==!bB^tnSb8Q;8UXScT?I?0vE4@mkPdE$ z<=Qr_-5C;+3|3E@wq>W2U8XJ7mTIeTBS_nDs*xK(*j6DxN=h~YkdXoal-leBlK@C< k?*)-W0Elg8Pl#=2C!mx^+6+j{WQlvZ7&*H_Nc@!~05@;V5dZ)H literal 0 HcmV?d00001 diff --git a/public/images/projects/raylib-speedruns.webp b/public/images/projects/raylib-speedruns.webp new file mode 100644 index 0000000000000000000000000000000000000000..7317eed281c319a22f39b2002cee582a0abe4cfc GIT binary patch literal 478 zcmV<40U`cUNk&H20RRA3MM6+kP&iD=0RR9mSwI#LFF=rOGmZH>Oz9Zc5C|ms%Z)Ta zw$0`|tuuc90|5VxG!;m$ZM$w8paY!iMAfE? z?^(=Cz^QqU19J@KVUg4Fz2zKZ6~=xaHGmQbjH|1r20*GQ2q;=*TwPRCm5Lg6P2F;7 zHC0oK2WhCOYD~G}!5|(%Y3hkOUkx~zfC^Bto`aXhDx17)DtT34Ttd{Q0jgU)6ULh$ zYU+72TkyRFk^=``P-VU|7T7JntBPt<1;+b}qxq_-m`V*WzH@>62I!9uX@CNAeD4Cj z{(SuY^YP=;RF31@7x3fr>&Iuh$zYBhHfjJ3deb88Rj9dXKmZM(y=ehd zfogJB!&ybdsw*ZlDHo*J3Zn&b!9ejLip()@F=lAF*QR7^5}gf$d=> Uk632xWIkb(!+OY?hr#&g9qF0jS^xk5 literal 0 HcmV?d00001 diff --git a/public/images/projects/s3pweb.webp b/public/images/projects/s3pweb.webp new file mode 100644 index 0000000000000000000000000000000000000000..5f14ca59ff140d1043ea7651e6fe2a98bffdf5fc GIT binary patch literal 624 zcmV-$0+0PtNk&F!0ssJ4MM6+kP&iCm0ssInSwI#L^~i02N0XHnpoJ$Yq6JzZrwV!@ zq7SM-n(=t=&1?#q;HsD+oQ|wXT)`I&zcpABIyO_=##KTUtNs}r6|6?JkR-v`LD>69 zEX?y2}5XNXJd+%B*4bz^~CBEZ7L<}6rT|T6qUFmm0Ifauw8OSyYk({*2tJRv- z`5{R0lssim0t~?3f`pk^p>S5LV#+r0gaF3CDI(O0RR)QZ6Cz2=Tnd0zWJ_S-nutaMh*f4R ztfkP4(i!z;-JLTcFp7>`pwlnVS&gnaPNx7T-_{s8N@6q;F=VWX(0`I!|Rv_%(oDF2l5c1=&b_1{``R+PaB}$ KG(i7ZLOK9I1Sfp} literal 0 HcmV?d00001 diff --git a/public/images/projects/simple-qr.webp b/public/images/projects/simple-qr.webp new file mode 100644 index 0000000000000000000000000000000000000000..91db7bb90501964fb661eb356f9197bd70c923be GIT binary patch literal 910 zcmV;919ALPNk&G70{{S5MM6+kP&iC^0{{RoSwI#L_0WlJ%aZI2goo>yvV=jdV2F-r z2*HnvB0A5>>8@;3pSm|9L0lt^OCX_~>nD+Mjkax*6FN4!|23B53e~iYB$+>s)ppx1 zgy#-b{~bt@8aE5b=sqGq`NI8g9{ND$+iJfz%$kxwZ`J)(#hviKm8hQdK5g`+@d@-I~(rZ*z99P!5|gZPFgl?7M0v z{pdqx?R>GG#+{s@n|eLSGqJ^R(#y|e>&hYZ6TWPXFkVN<{)eEu3$l4C;~MMW8@^|* zj|6zb`J2h3(FQx2UuM1ZKvn&WeFds8xR8bfiz(pDiA?}ak-Ptf^%7SV;MdDW+!YR| zJa931jM;HD4(#rGt)-_SMMT|IsJSQK@`}HnPw(`gw6FdwEl)isH3?TS`tW~ zIi%r_#CX2fmd-glLJ{Rebjkgzi{jOAXcN@?s;A`~9c_>B>WE|GB4Jea902+(NwuD3 zowIPu5fU@r@v7*G+?~xRyKzUVdRo>FN2V-~QvOrBTejc`*}x!qjU>S+J>Z3g(@3vi z(E`{+UvLH3c-*DN%8mt^WgO=oA3B`C!eGPqMXYm{hpXp99~4V8mwtF>W703a#+k%E z=g0+McUl$Y(fQfSiyUJAw4zil~kVuM{1l<#k}s(8*X%d!Qx$fF!SEKM6eM z$v{V)RuNUz(SI`N{#$pQQz_DU+Wg!)j(vm4k3JsUDf2Zt4PCUJs0+Mx;PllPCMdk*}1 zV|qe$4xeowey4$g?kUsY?0c_N%O(+CW6`)vv{P35X< zrCtE$u|G^ud)1W^5nX;kahLD4rHj!i&cF-Yiljt??%$CbEE@!zk(wue@haS|HGGV09Q!GAOHXW literal 0 HcmV?d00001 diff --git a/public/images/projects/tlock.webp b/public/images/projects/tlock.webp new file mode 100644 index 0000000000000000000000000000000000000000..4438594e38bb1879612f86e9d42dd08d12134982 GIT binary patch literal 660 zcmV;F0&D$JNk&GD0ssJ4MM6+kP&iD00ssInSwI#L)yQo?$&!={fp`c5lT>gCfpjhm z$bl%3rmL#wuG-_*ns)14toG_jk6)XswpKFQwvGRPv~aX&RTN2T935_O!I!v5{~b7z z)J8osVhxTLz;EbZG4&2bZ_wh{yuLta&e;@YOyw#aEoB*b#9nRr6-sp57IRhEdp6Xr zt&rJlhl)PweYM3X((P=AxyIHSYwXP<&3M<;P&yl?v!13*gNv=Xb6#hgw|#h>&2|Qv zcJaUw#gj9xP9fc$g9f4DqNf@k^1`*keu@;Zg3L*gd9a3v}B<(Lp z%mz(#A!Vh>9AhN?d`>WaN`eNQhpZnd0*h;Gvb#Gm)*482JjGwjiL}VEq=+#R%_l*dYpvx3B8P-D^G7qc+}zV;6^7uWS&P)U-|ohS z@ZK&BatKtxdl3z!+}OKtljoD%1zDKab-95Q{JBd#j2hG9m6=rx{n7y7+&(R{ub5^(FHagwC#;ISw`N#XbC&Ag_^Jbw5IEKV literal 0 HcmV?d00001 diff --git a/app/assets/images/projects/top-screen/background.webp b/public/images/projects/top-screen/background.webp similarity index 100% rename from app/assets/images/projects/top-screen/background.webp rename to public/images/projects/top-screen/background.webp diff --git a/app/assets/images/settings/bottom-screen/bottom-bar.webp b/public/images/settings/bottom-screen/bottom-bar.webp similarity index 100% rename from app/assets/images/settings/bottom-screen/bottom-bar.webp rename to public/images/settings/bottom-screen/bottom-bar.webp diff --git a/app/assets/images/settings/bottom-screen/top-bar.webp b/public/images/settings/bottom-screen/top-bar.webp similarity index 100% rename from app/assets/images/settings/bottom-screen/top-bar.webp rename to public/images/settings/bottom-screen/top-bar.webp diff --git a/app/assets/images/settings/top-screen/clock/alarm.webp b/public/images/settings/top-screen/clock/alarm.webp similarity index 100% rename from app/assets/images/settings/top-screen/clock/alarm.webp rename to public/images/settings/top-screen/clock/alarm.webp diff --git a/app/assets/images/settings/top-screen/clock/clock-active.webp b/public/images/settings/top-screen/clock/clock-active.webp similarity index 100% rename from app/assets/images/settings/top-screen/clock/clock-active.webp rename to public/images/settings/top-screen/clock/clock-active.webp diff --git a/app/assets/images/settings/top-screen/clock/clock-disabled.png b/public/images/settings/top-screen/clock/clock-disabled.png similarity index 100% rename from app/assets/images/settings/top-screen/clock/clock-disabled.png rename to public/images/settings/top-screen/clock/clock-disabled.png diff --git a/app/assets/images/settings/top-screen/clock/clock.webp b/public/images/settings/top-screen/clock/clock.webp similarity index 100% rename from app/assets/images/settings/top-screen/clock/clock.webp rename to public/images/settings/top-screen/clock/clock.webp diff --git a/app/assets/images/settings/top-screen/clock/date.webp b/public/images/settings/top-screen/clock/date.webp similarity index 100% rename from app/assets/images/settings/top-screen/clock/date.webp rename to public/images/settings/top-screen/clock/date.webp diff --git a/app/assets/images/settings/top-screen/clock/time.webp b/public/images/settings/top-screen/clock/time.webp similarity index 100% rename from app/assets/images/settings/top-screen/clock/time.webp rename to public/images/settings/top-screen/clock/time.webp diff --git a/app/assets/images/settings/top-screen/notification.webp b/public/images/settings/top-screen/notification.webp similarity index 100% rename from app/assets/images/settings/top-screen/notification.webp rename to public/images/settings/top-screen/notification.webp diff --git a/app/assets/images/settings/top-screen/options/gba-mode.webp b/public/images/settings/top-screen/options/gba-mode.webp similarity index 100% rename from app/assets/images/settings/top-screen/options/gba-mode.webp rename to public/images/settings/top-screen/options/gba-mode.webp diff --git a/app/assets/images/settings/top-screen/options/language.webp b/public/images/settings/top-screen/options/language.webp similarity index 100% rename from app/assets/images/settings/top-screen/options/language.webp rename to public/images/settings/top-screen/options/language.webp diff --git a/app/assets/images/settings/top-screen/options/options-active.png b/public/images/settings/top-screen/options/options-active.png similarity index 100% rename from app/assets/images/settings/top-screen/options/options-active.png rename to public/images/settings/top-screen/options/options-active.png diff --git a/app/assets/images/settings/top-screen/options/options-disabled.png b/public/images/settings/top-screen/options/options-disabled.png similarity index 100% rename from app/assets/images/settings/top-screen/options/options-disabled.png rename to public/images/settings/top-screen/options/options-disabled.png diff --git a/app/assets/images/settings/top-screen/options/options.webp b/public/images/settings/top-screen/options/options.webp similarity index 100% rename from app/assets/images/settings/top-screen/options/options.webp rename to public/images/settings/top-screen/options/options.webp diff --git a/app/assets/images/settings/top-screen/options/start-up.webp b/public/images/settings/top-screen/options/start-up.webp similarity index 100% rename from app/assets/images/settings/top-screen/options/start-up.webp rename to public/images/settings/top-screen/options/start-up.webp diff --git a/app/assets/images/settings/top-screen/settings.webp b/public/images/settings/top-screen/settings.webp similarity index 100% rename from app/assets/images/settings/top-screen/settings.webp rename to public/images/settings/top-screen/settings.webp diff --git a/app/assets/images/settings/top-screen/touch_screen/touch-screen-disabled.png b/public/images/settings/top-screen/touch_screen/touch-screen-disabled.png similarity index 100% rename from app/assets/images/settings/top-screen/touch_screen/touch-screen-disabled.png rename to public/images/settings/top-screen/touch_screen/touch-screen-disabled.png diff --git a/app/assets/images/settings/top-screen/touch_screen/touch-screen.webp b/public/images/settings/top-screen/touch_screen/touch-screen.webp similarity index 100% rename from app/assets/images/settings/top-screen/touch_screen/touch-screen.webp rename to public/images/settings/top-screen/touch_screen/touch-screen.webp diff --git a/app/assets/images/settings/top-screen/user/birthday.webp b/public/images/settings/top-screen/user/birthday.webp similarity index 100% rename from app/assets/images/settings/top-screen/user/birthday.webp rename to public/images/settings/top-screen/user/birthday.webp diff --git a/app/assets/images/settings/top-screen/user/color.webp b/public/images/settings/top-screen/user/color.webp similarity index 100% rename from app/assets/images/settings/top-screen/user/color.webp rename to public/images/settings/top-screen/user/color.webp diff --git a/app/assets/images/settings/top-screen/user/message.webp b/public/images/settings/top-screen/user/message.webp similarity index 100% rename from app/assets/images/settings/top-screen/user/message.webp rename to public/images/settings/top-screen/user/message.webp diff --git a/app/assets/images/settings/top-screen/user/user-active.webp b/public/images/settings/top-screen/user/user-active.webp similarity index 100% rename from app/assets/images/settings/top-screen/user/user-active.webp rename to public/images/settings/top-screen/user/user-active.webp diff --git a/app/assets/images/settings/top-screen/user/user-disabled.png b/public/images/settings/top-screen/user/user-disabled.png similarity index 100% rename from app/assets/images/settings/top-screen/user/user-disabled.png rename to public/images/settings/top-screen/user/user-disabled.png diff --git a/app/assets/images/settings/top-screen/user/user-name.webp b/public/images/settings/top-screen/user/user-name.webp similarity index 100% rename from app/assets/images/settings/top-screen/user/user-name.webp rename to public/images/settings/top-screen/user/user-name.webp diff --git a/app/assets/images/settings/top-screen/user/user.webp b/public/images/settings/top-screen/user/user.webp similarity index 100% rename from app/assets/images/settings/top-screen/user/user.webp rename to public/images/settings/top-screen/user/user.webp