import gsap from "gsap"; // not sure how i came up with it last night export const SUBMENU_LABEL_CHANGE_DELAY = 0.25 + 0.15 - (0.167 + 0.08); export const SETTINGS_MENUS = [ "options", "clock", "user", "touchScreen", ] as const; export const SETTINGS_SUB_MENUS = [ "optionsLanguage", "options2048", "optionsRenderingMode", "clockAchievements", "clockTime", "clockDate", "userBirthday", "userUserName", "userSnake", "userColor", "touchScreenTapTap", ] as const; export type SettingsMenu = (typeof SETTINGS_MENUS)[number]; export type SettingsSubMenu = (typeof SETTINGS_SUB_MENUS)[number]; export type SettingsNavigableButton = | SettingsMenu | Exclude; export const useSettingsStore = defineStore("settings", { state: () => ({ currentMenu: null as SettingsMenu | null, currentSubMenu: null as SettingsSubMenu | null, menuExpanded: false, selectedButton: "options" as SettingsNavigableButton, notificationYOffset: 48, barOffsetY: 24, menuOffsets: [0, -48, -48, -48] as [number, number, number, number], menuYOffset: 72, submenuTransition: { offsetY: 0, selectorOffsetY: 0, opacity: 1, }, submenuBackground: { offsetY: 16, opacity: 0, }, submenuButtonsOffsetY: 0, animatingNotification: false, isIntro: true, isOutro: false, returningFromAchievements: false, }), actions: { openMenu(menu: SettingsMenu, expanded: boolean = false) { this.currentMenu = menu; this.menuExpanded = expanded; this.currentSubMenu = null; }, async openSubMenu(submenu: SettingsSubMenu) { const { assets } = useAssets(); assets.audio.menuOpen.play(); await gsap .timeline() .to(this.submenuTransition, { offsetY: -48, selectorOffsetY: -140, opacity: 0, duration: 0.25, ease: "none", }) .fromTo( this.submenuBackground, { offsetY: 16, opacity: 0 }, { offsetY: 0, opacity: 1, duration: 0.25, ease: "none" }, "+=0.05", ) .call(() => { this.currentSubMenu = submenu; }); const achievements = useAchievementsStore(); if (!achievements.advancement.visitedSettings.includes(submenu)) { achievements.advancement.visitedSettings.push(submenu); } if ( achievements.advancement.visitedSettings.length === SETTINGS_SUB_MENUS.length ) { achievements.unlock("settings_visit_all"); } }, async closeSubMenu(silent = false) { if (!silent) { const { assets } = useAssets(); assets.audio.menuError.play(); } await gsap .timeline() .to(this, { submenuButtonsOffsetY: 24, duration: 0.167, ease: "none", }) .call(() => { this.currentSubMenu = null; const confirmationModal = useConfirmationModal(); confirmationModal.buttonsYOffset = 0; }) .fromTo( this.submenuBackground, { offsetY: 0, opacity: 1 }, { offsetY: 16, opacity: 0, duration: 0.25, ease: "none" }, 0.167, ) .to( this, { submenuButtonsOffsetY: 0, duration: 0.167, ease: "none", }, 0.217, ) .fromTo( this.submenuTransition, { offsetY: -48, selectorOffsetY: -140, opacity: 0, }, { offsetY: 0, selectorOffsetY: 0, opacity: 1, duration: 0.25, ease: "none", }, "+=0.05", ); }, animateIntro() { this.isIntro = true; const { assets } = useAssets(); gsap .timeline() // bars .fromTo( this, { barOffsetY: 24 }, { barOffsetY: 0, duration: 0.2, ease: "none" }, 0, ) // title notification .fromTo( this, { notificationYOffset: 48 }, { notificationYOffset: 0, duration: 0.2, ease: "none" }, 0.1, ) // menus slide up .fromTo( this, { menuYOffset: 72 }, { menuYOffset: 0, duration: 0.2, ease: "none" }, 0, ) // menus accordion .fromTo( this.menuOffsets, { 1: -48 }, { 1: 0, duration: 0.143, ease: "none" }, 0.2, ) .call(() => assets.audio.settingsMenuIntro.play(), undefined, 0.2) .fromTo( this.menuOffsets, { 2: -48 }, { 2: 0, duration: 0.143, ease: "none" }, 0.343, ) .fromTo( this.menuOffsets, { 3: -48 }, { 3: 0, duration: 0.143, ease: "none" }, 0.486, ) .call(() => { this.isIntro = false; }); }, animateOutro() { this.isOutro = true; const { assets } = useAssets(); gsap .timeline() .call(() => assets.audio.settingsMenuOutro.play()) // title notification .fromTo( this, { notificationYOffset: 0 }, { notificationYOffset: 48, duration: 0.2, ease: "none" }, 0, ) // bars .fromTo( this, { barOffsetY: 0 }, { barOffsetY: 24, duration: 0.2, ease: "none" }, 0.1, ) // menus accordion .fromTo( this.menuOffsets, { 3: 0 }, { 3: -48, duration: 0.143, ease: "none" }, 0, ) .fromTo( this.menuOffsets, { 2: 0 }, { 2: -48, duration: 0.143, ease: "none" }, 0.143, ) .fromTo( this.menuOffsets, { 1: 0 }, { 1: -48, duration: 0.143, ease: "none" }, 0.286, ) // menus slide down .fromTo( this, { menuYOffset: 0 }, { menuYOffset: 72, duration: 0.2, ease: "none" }, 0.429, ) .call(() => { const app = useAppStore(); app.navigateTo("home"); this.isOutro = false; }); }, }, });