87 lines
2.0 KiB
TypeScript
87 lines
2.0 KiB
TypeScript
import { useLocalStorage } from "@vueuse/core";
|
|
|
|
const STORAGE_ID = "achievements";
|
|
|
|
export const ACHIEVEMENTS = [
|
|
"boot",
|
|
// projects
|
|
"projects_visit",
|
|
"projects_view_5",
|
|
"projects_open_link",
|
|
// gallery
|
|
"gallery_visit",
|
|
// contact
|
|
"contact_visit",
|
|
"contact_git_visit",
|
|
// settings
|
|
"settings_color_change",
|
|
// snake
|
|
"snake_play",
|
|
"snake_score_40",
|
|
// secrets
|
|
"settings_color_try_all",
|
|
"settings_language_try_all",
|
|
"settings_visit_all",
|
|
"contact_36_notifications",
|
|
] as const;
|
|
|
|
export type Achievement = (typeof ACHIEVEMENTS)[number];
|
|
|
|
export const useAchievementsStore = defineStore("achievements", () => {
|
|
const app = useAppStore();
|
|
const { locale } = useI18n();
|
|
|
|
const storage = useLocalStorage(
|
|
STORAGE_ID,
|
|
{
|
|
unlocked: [] as Achievement[],
|
|
advancement: {
|
|
colors: [app.color.hex],
|
|
languages: [locale.value],
|
|
visitedSettings: [] as string[],
|
|
},
|
|
},
|
|
{ mergeDefaults: true },
|
|
);
|
|
|
|
if (!storage.value.advancement.colors.includes(app.color.hex)) {
|
|
storage.value.advancement.colors.push(app.color.hex);
|
|
}
|
|
if (!storage.value.advancement.languages.includes(locale.value)) {
|
|
storage.value.advancement.languages.push(locale.value);
|
|
}
|
|
|
|
const unlock = (name: Achievement) => {
|
|
if (storage.value.unlocked.includes(name)) {
|
|
return false;
|
|
}
|
|
|
|
storage.value.unlocked.push(name);
|
|
return true;
|
|
};
|
|
|
|
const reset = () => {
|
|
storage.value = {
|
|
unlocked: [],
|
|
advancement: {
|
|
colors: [app.color.hex],
|
|
languages: [locale.value],
|
|
visitedSettings: [],
|
|
},
|
|
};
|
|
};
|
|
|
|
return {
|
|
unlocked: computed(() => storage.value.unlocked),
|
|
advancement: computed(() => storage.value.advancement),
|
|
allObtained: computed(
|
|
() => storage.value.unlocked.length === ACHIEVEMENTS.length,
|
|
),
|
|
unlock,
|
|
reset,
|
|
isUnlocked: computed(
|
|
() => (name: Achievement) => storage.value.unlocked.includes(name),
|
|
),
|
|
};
|
|
});
|