import gsap from "gsap"; 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, }, animatingNotification: false, isIntro: true, isOutro: false, }), actions: { openMenu(menu: SettingsMenu, expanded: boolean = false) { this.currentMenu = menu; this.menuExpanded = expanded; this.currentSubMenu = null; }, async openSubMenu(submenu: SettingsSubMenu) { 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", ); 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() { this.currentSubMenu = null; await gsap .timeline() .fromTo( this.submenuBackground, { offsetY: 0, opacity: 1 }, { offsetY: 16, opacity: 0, duration: 0.25, ease: "none" }, ) .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; 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.1, ease: "none" }, 0.2, ) .fromTo( this.menuOffsets, { 2: -48 }, { 2: 0, duration: 0.1, ease: "none" }, 0.3, ) .fromTo( this.menuOffsets, { 3: -48 }, { 3: 0, duration: 0.1, ease: "none" }, 0.4, ) .call(() => { this.isIntro = false; }); }, animateOutro() { this.isOutro = true; gsap .timeline() // 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.1, ease: "none" }, 0, ) .fromTo( this.menuOffsets, { 2: 0 }, { 2: -48, duration: 0.1, ease: "none" }, 0.1, ) .fromTo( this.menuOffsets, { 1: 0 }, { 1: -48, duration: 0.1, ease: "none" }, 0.2, ) // menus slide down .fromTo( this, { menuYOffset: 0 }, { menuYOffset: 72, duration: 0.2, ease: "none" }, 0.3, ) .call(() => { const app = useAppStore(); app.navigateTo("home"); this.isOutro = false; }); }, }, });