feat(settings): more specific notification handling, and put menu in query to allow user to go back in history to go back in menus

This commit is contained in:
2025-11-26 22:58:03 +01:00
parent d37a793488
commit aa60eb4909
9 changed files with 181 additions and 128 deletions

View File

@@ -1,44 +1,9 @@
<script setup lang="ts">
import Background from "./Background.vue";
import Menus from "./Menus/Menus.vue";
import OptionsStartUp from "./Menus/Options/StartUp.vue";
import OptionsLanguage from "./Menus/Options/Language.vue";
import OptionsGbaMode from "./Menus/Options/GbaMode.vue";
const store = useSettingsStore();
const viewComponents: Record<string, Component> = {
optionsStartUp: OptionsStartUp,
optionsLanguage: OptionsLanguage,
optionsGbaMode: OptionsGbaMode,
};
const currentViewComponent = computed(() => {
if (store.currentView === "menu" || !store.currentView) return null;
return viewComponents[store.currentView] || null;
});
const handleBackNavigation = (event: KeyboardEvent) => {
if (event.key === "Escape" || event.key === "Backspace") {
if (store.navigationStack.length > 0) {
store.popNavigation();
event.preventDefault();
}
}
};
onMounted(() => {
store.$reset();
window.addEventListener("keydown", handleBackNavigation);
});
onUnmounted(() => {
window.removeEventListener("keydown", handleBackNavigation);
});
</script>
<template>
<Background />
<Menus v-if="store.currentView === 'menu'" />
<component :is="currentViewComponent" v-else-if="currentViewComponent" />
<Menus />
</template>

View File

@@ -34,7 +34,7 @@ const isAnyOtherMenuOpen = computed(() =>
settingsStore.isAnyOtherMenuOpen("clock"),
);
const animation = useMenuAnimation(isOpen);
const animation = useMenuAnimation("clock", isOpen);
useRender((ctx) => {
ctx.translate(props.x, props.y);

View File

@@ -1,10 +1,16 @@
<script setup lang="ts">
import OptionsMenu from "./Options/Menu.vue";
import OptionsStartUp from "./Options/StartUp.vue";
import OptionsLanguage from "./Options/Language.vue";
import OptionsGbaMode from "./Options/GbaMode.vue";
import ClockMenu from "./Clock/Menu.vue";
import UserMenu from "./User/Menu.vue";
import TouchScreenMenu from "./TouchScreen/Menu.vue";
import Selector from "~/components/Common/ButtonSelector.vue";
const settingsStore = useSettingsStore();
const { selectedButton: selected, selectorPosition } = useButtonNavigation({
buttons: {
options: [31, 119, 49, 49],
@@ -28,7 +34,11 @@ const { selectedButton: selected, selectorPosition } = useButtonNavigation({
initialButton: "options",
onButtonClick: (buttonName: string) => {
if (isSubmenu(buttonName)) {
settingsStore.pushNavigation(buttonName);
router.push({
query: {
menu: buttonName,
},
});
}
},
navigation: {
@@ -104,8 +114,6 @@ const { selectedButton: selected, selectorPosition } = useButtonNavigation({
},
});
const settingsStore = useSettingsStore();
const isSubmenu = (buttonName: string) => {
return (
/^(options|clock|user|touchScreen)[A-Z]/.test(buttonName) &&
@@ -113,20 +121,64 @@ const isSubmenu = (buttonName: string) => {
);
};
const router = useRouter();
onBeforeRouteUpdate((to, from) => {
const fromMenu = from.query.menu?.toString();
const toMenu = to.query.menu?.toString();
if (!fromMenu && toMenu) {
settingsStore.setActiveMenu(selected.value);
} else if (fromMenu && !toMenu) {
if (fromMenu === "options" || fromMenu === "clock" || fromMenu === "user") {
selected.value = fromMenu;
settingsStore.setActiveMenu(null);
} else {
throw new Error("Unreachable");
}
} else if (fromMenu && toMenu) {
if (toMenu === "options" || toMenu === "clock" || toMenu === "user") {
settingsStore.setCurrentSubMenu(null);
settingsStore.setActiveMenu(selected.value);
} else {
settingsStore.setCurrentSubMenu(toMenu);
}
}
});
watch(
selected,
(newSelected) => {
settingsStore.setActiveMenu(newSelected);
if (settingsStore.currentSubMenu === null) {
if (isSubmenu(newSelected)) {
router.push({
query: {
menu: newSelected.split(/[A-Z]/)[0],
},
});
} else {
router.push({ query: { menu: undefined } });
}
}
},
{ immediate: true },
);
const viewComponents: Record<string, Component> = {
optionsStartUp: OptionsStartUp,
optionsLanguage: OptionsLanguage,
optionsGbaMode: OptionsGbaMode,
};
</script>
<template>
<OptionsMenu :x="33" :y="121" />
<ClockMenu :x="81" :y="121" />
<UserMenu :x="129" :y="121" />
<TouchScreenMenu :x="177" :y="121" :opacity="1" />
<template v-if="!settingsStore.currentSubMenu">
<OptionsMenu :x="33" :y="121" />
<ClockMenu :x="81" :y="121" />
<UserMenu :x="129" :y="121" />
<TouchScreenMenu :x="177" :y="121" :opacity="1" />
<Selector :rect="selectorPosition" :opacity="1" />
<Selector :rect="selectorPosition" :opacity="1" />
</template>
<component :is="viewComponents[settingsStore.currentSubMenu]" v-else />
</template>

View File

@@ -34,7 +34,7 @@ const isAnyOtherMenuOpen = computed(() =>
settingsStore.isAnyOtherMenuOpen("options"),
);
const animation = useMenuAnimation(isOpen);
const animation = useMenuAnimation("options", isOpen);
useRender((ctx) => {
ctx.translate(props.x, props.y);

View File

@@ -37,7 +37,7 @@ const isAnyOtherMenuOpen = computed(() =>
settingsStore.isAnyOtherMenuOpen("user"),
);
const animation = useMenuAnimation(isOpen);
const animation = useMenuAnimation("user", isOpen);
useRender((ctx) => {
ctx.translate(props.x, props.y);