feat(settings): render top and bottom bar, implement notifications stack and submenu navigation

This commit is contained in:
2025-11-26 11:07:03 +01:00
parent 9858ef0b07
commit d37a793488
16 changed files with 169 additions and 24 deletions

View File

@@ -5,6 +5,9 @@ import OPTIONS_IMAGE from "/assets/images/settings/top-screen/options/options.we
import CLOCK_IMAGE from "/assets/images/settings/top-screen/clock/clock.webp";
import USER_IMAGE from "/assets/images/settings/top-screen/user/user.webp";
import TOUCH_SCREEN_IMAGE from "/assets/images/settings/top-screen/touch_screen/touch-screen.webp";
import START_UP_IMAGE from "/assets/images/settings/top-screen/options/start-up.webp";
import LANGUAGE_IMAGE from "/assets/images/settings/top-screen/options/language.webp";
import GBA_MODE_IMAGE from "/assets/images/settings/top-screen/options/gba-mode.webp";
const store = useSettingsStore();
@@ -15,6 +18,9 @@ const [
clockImage,
userImage,
touchScreenImage,
startUpImage,
languageImage,
gbaModeImage,
] = useImages(
NOTIFICATION_IMAGE,
SETTINGS_IMAGE,
@@ -22,6 +28,9 @@ const [
CLOCK_IMAGE,
USER_IMAGE,
TOUCH_SCREEN_IMAGE,
START_UP_IMAGE,
LANGUAGE_IMAGE,
GBA_MODE_IMAGE,
);
const activeMenu = computed(() => {
@@ -64,25 +73,50 @@ const renderNotification = (
}
};
useRender((ctx) => {
ctx.translate(0, activeMenu.value ? 144 - 16 : 144);
renderNotification(
ctx,
settingsImage!,
$t(`settings.title`),
$t(`settings.description`),
);
const notificationStack = computed(() => {
const stack: Array<{ id: string; image: HTMLImageElement }> = [
{ id: "main", image: settingsImage! },
];
if (activeMenu.value) {
ctx.translate(0, 16);
stack.push({ id: activeMenu.value.id, image: activeMenu.value.image! });
}
for (const view of store.navigationStack) {
const menuMatch = view.match(/^(options|clock|user|touchScreen)(.+)$/);
if (menuMatch) {
const [, menu, submenu] = menuMatch;
const submenuKey = submenu!.charAt(0).toLowerCase() + submenu!.slice(1);
const imageMap: Record<string, HTMLImageElement> = {
optionsStartUp: startUpImage!,
optionsLanguage: languageImage!,
optionsGbaMode: gbaModeImage!,
};
if (imageMap[view]) {
stack.push({ id: `${menu}.${submenuKey}`, image: imageMap[view]! });
}
}
}
return stack;
});
useRender((ctx) => {
const stackSize = notificationStack.value.length;
ctx.translate(0, 144 - (stackSize - 1) * 16);
for (let i = 0; i < stackSize; i++) {
const notification = notificationStack.value[i]!;
renderNotification(
ctx,
activeMenu.value.image!,
$t(`settings.${activeMenu.value.id}.title`),
$t(`settings.${activeMenu.value.id}.description`),
notification.image,
$t(`settings.${notification.id}.title`),
$t(`settings.${notification.id}.description`),
);
ctx.translate(0, 16);
}
});