From c005c50081f53f7557c1d32ce93d062efb37c7da Mon Sep 17 00:00:00 2001 From: Pihkaal Date: Wed, 14 Jan 2026 15:34:02 +0100 Subject: [PATCH] feat(buttonNavigation): expose readonly selected button and new select function, to allow user to select any button with path animation --- app/components/Contact/BottomScreen/BottomScreen.vue | 6 +++--- app/components/Home/BottomScreen/Buttons.vue | 10 +++++----- app/components/Settings/BottomScreen/Menus/Menus.vue | 10 +++++----- app/composables/useButtonNavigation.ts | 10 +++++++++- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/app/components/Contact/BottomScreen/BottomScreen.vue b/app/components/Contact/BottomScreen/BottomScreen.vue index 3473b1b..9d3fff7 100644 --- a/app/components/Contact/BottomScreen/BottomScreen.vue +++ b/app/components/Contact/BottomScreen/BottomScreen.vue @@ -18,7 +18,7 @@ const ACTIONS = { [action: "Copy" | "Open", verb: string, content: string] >; -const { selectedButton, selectorPosition } = useButtonNavigation({ +const { selected, selectorPosition } = useButtonNavigation({ buttons: { github: [26, 27, 202, 42], email: [26, 59, 202, 42], @@ -48,7 +48,7 @@ const { selectedButton, selectorPosition } = useButtonNavigation({ disabled: computed(() => store.isIntro || store.isOutro), }); -const actionateButton = async (button: (typeof selectedButton)["value"]) => { +const actionateButton = async (button: (typeof selected)["value"]) => { const [action, verb, content] = ACTIONS[button]; if (action === "Copy") { try { @@ -102,7 +102,7 @@ const actionateButton = async (button: (typeof selectedButton)["value"]) => { : 1 " b-label="Quit" - :a-label="ACTIONS[selectedButton][0]" + :a-label="ACTIONS[selected][0]" @activate-b="store.animateOutro()" /> diff --git a/app/components/Home/BottomScreen/Buttons.vue b/app/components/Home/BottomScreen/Buttons.vue index 077fc0d..c591419 100644 --- a/app/components/Home/BottomScreen/Buttons.vue +++ b/app/components/Home/BottomScreen/Buttons.vue @@ -7,7 +7,7 @@ const { onRender } = useScreen(); const store = useHomeStore(); const { assets } = useAssets(); -const { selectedButton, selectorPosition } = useButtonNavigation({ +const { selected, selectorPosition } = useButtonNavigation({ buttons: { projects: [31, 23, 193, 49], contact: [31, 71, 97, 49], @@ -56,14 +56,14 @@ const { selectedButton, selectorPosition } = useButtonNavigation({ disabled: computed(() => store.isIntro || store.isOutro), }); -const getButtonOffset = (button: (typeof selectedButton)["value"]) => { - if (selectedButton.value === button) return store.outro.buttonOffsetY; +const getButtonOffset = (button: (typeof selected)["value"]) => { + if (selected.value === button) return store.outro.buttonOffsetY; return 0; }; -const getOpacity = (button?: (typeof selectedButton)["value"]) => { +const getOpacity = (button?: (typeof selected)["value"]) => { if (store.isIntro) return store.intro.stage1Opacity; - if (selectedButton.value === button) return 1; + if (selected.value === button) return 1; if (store.isOutro) return store.outro.stage1Opacity; return 1; }; diff --git a/app/components/Settings/BottomScreen/Menus/Menus.vue b/app/components/Settings/BottomScreen/Menus/Menus.vue index 5df5a8e..cd4b088 100644 --- a/app/components/Settings/BottomScreen/Menus/Menus.vue +++ b/app/components/Settings/BottomScreen/Menus/Menus.vue @@ -27,7 +27,7 @@ const getParentMenu = (submenu: string): SettingsMenu => { return match[1] as SettingsMenu; }; -const { selectedButton: selected, selectorPosition } = useButtonNavigation({ +const { select, selected, selectorPosition } = useButtonNavigation({ buttons: { options: [31, 119, 49, 49], optionsLanguage: [31, 71, 49, 49], @@ -52,9 +52,9 @@ const { selectedButton: selected, selectorPosition } = useButtonNavigation({ if (isSubMenu(buttonName)) { settingsStore.openSubMenu(buttonName); } else { - if (buttonName === "options") selected.value = "optionsLanguage"; - if (buttonName === "clock") selected.value = "clockAlarm"; - if (buttonName === "user") selected.value = "userName"; + if (buttonName === "options") select("optionsLanguage"); + if (buttonName === "clock") select("clockAlarm"); + if (buttonName === "user") select("userName"); if (buttonName === "touchScreen") throw new Error("Not implemented"); } }, @@ -183,7 +183,7 @@ const viewComponents: Record = { :y-offset="0" b-label="Go back" a-label="Select" - @activate-b="selected = getParentMenu(selected)" + @activate-b="select(getParentMenu(selected))" /> >({ } }); + const select = (targetButton: Entry) => { + if (isAnimating.value || disabled?.value) return; + + const path = findPath(graph, selectedButton.value, targetButton); + animateToButton(targetButton, path); + }; + return { - selectedButton, + selected: readonly(selectedButton), selectorPosition, + select, }; };