import { writable, derived } from "svelte/store"; import { listen } from "@tauri-apps/api/event"; import { invoke } from "@tauri-apps/api/core"; import type { Achievement, AchievementUnlockedEvent, AchievementId } from "$lib/types/achievements"; import { playAchievementSound } from "$lib/sounds/achievement"; interface AchievementState { achievements: Record; totalUnlocked: number; lastUnlocked: Achievement | null; } // Initial achievement definitions - must match Rust backend exactly! const achievementDefinitions: Record< AchievementId, Omit > = { // ============================================ // Token Milestones // ============================================ FirstSteps: { id: "FirstSteps", name: "First Steps", description: "Generated your first 1,000 tokens", icon: "๐Ÿ‘ถ", rarity: "common", maxProgress: 1000, }, GrowingStrong: { id: "GrowingStrong", name: "Growing Strong", description: "Reached 10,000 tokens total", icon: "๐ŸŒฑ", rarity: "common", maxProgress: 10000, }, BlossomingCoder: { id: "BlossomingCoder", name: "Blossoming Coder", description: "Generated 100,000 tokens - you're really growing!", icon: "๐ŸŒธ", rarity: "rare", maxProgress: 100000, }, TokenMaster: { id: "TokenMaster", name: "Token Master", description: "One million tokens! You're unstoppable!", icon: "๐Ÿ‘‘", rarity: "epic", maxProgress: 1000000, }, TokenBillionaire: { id: "TokenBillionaire", name: "Token Billionaire", description: "Generated 10 million tokens!", icon: "๐Ÿ’ฐ", rarity: "legendary", maxProgress: 10000000, }, TokenTreasure: { id: "TokenTreasure", name: "Token Treasure", description: "Generated 50 million tokens - a true treasure trove!", icon: "๐Ÿ’Ž", rarity: "legendary", maxProgress: 50000000, }, // ============================================ // Code Generation // ============================================ HelloWorld: { id: "HelloWorld", name: "Hello, World!", description: "Generated your first code block", icon: "๐Ÿ‘‹", rarity: "common", maxProgress: 1, }, CodeWizard: { id: "CodeWizard", name: "Code Wizard", description: "100 code blocks generated", icon: "๐Ÿง™โ€โ™€๏ธ", rarity: "rare", maxProgress: 100, }, ThousandBlocks: { id: "ThousandBlocks", name: "Thousand Blocks", description: "1,000 code blocks! You're a code machine!", icon: "๐Ÿ—๏ธ", rarity: "epic", maxProgress: 1000, }, CodeFactory: { id: "CodeFactory", name: "Code Factory", description: "Generated 5,000 code blocks!", icon: "๐Ÿญ", rarity: "epic", maxProgress: 5000, }, CodeEmpire: { id: "CodeEmpire", name: "Code Empire", description: "Generated 10,000 code blocks - an empire of code!", icon: "๐Ÿฐ", rarity: "legendary", maxProgress: 10000, }, // ============================================ // File Operations // ============================================ FileManipulator: { id: "FileManipulator", name: "File Manipulator", description: "Edited 10 files", icon: "๐Ÿ“", rarity: "common", maxProgress: 10, }, FileArchitect: { id: "FileArchitect", name: "File Architect", description: "Edited 100 files", icon: "๐Ÿ›๏ธ", rarity: "rare", maxProgress: 100, }, FileEngineer: { id: "FileEngineer", name: "File Engineer", description: "Edited 500 files", icon: "โš™๏ธ", rarity: "epic", maxProgress: 500, }, FileLegend: { id: "FileLegend", name: "File Legend", description: "Edited 1,000 files - legendary file manipulation!", icon: "๐ŸŒŸ", rarity: "legendary", maxProgress: 1000, }, // ============================================ // Conversation Milestones // ============================================ ConversationStarter: { id: "ConversationStarter", name: "Conversation Starter", description: "Exchanged 10 messages", icon: "๐Ÿ’ฌ", rarity: "common", maxProgress: 10, }, ChattyKathy: { id: "ChattyKathy", name: "Chatty Kathy", description: "100 messages exchanged", icon: "๐Ÿ—ฃ๏ธ", rarity: "common", maxProgress: 100, }, Conversationalist: { id: "Conversationalist", name: "Master Conversationalist", description: "1,000 messages! We're really connecting!", icon: "๐Ÿ’–", rarity: "rare", maxProgress: 1000, }, ChatMarathon: { id: "ChatMarathon", name: "Chat Marathon", description: "5,000 messages exchanged!", icon: "๐Ÿƒโ€โ™€๏ธ", rarity: "epic", maxProgress: 5000, }, ChatLegend: { id: "ChatLegend", name: "Chat Legend", description: "10,000 messages - a legendary conversationalist!", icon: "๐Ÿ‘‘", rarity: "legendary", maxProgress: 10000, }, // ============================================ // Tool Usage // ============================================ Toolsmith: { id: "Toolsmith", name: "Toolsmith", description: "Used 5 different tools", icon: "๐Ÿ”จ", rarity: "common", maxProgress: 5, }, ToolMaster: { id: "ToolMaster", name: "Tool Master", description: "Used 10 different tools efficiently", icon: "๐Ÿ› ๏ธ", rarity: "rare", maxProgress: 10, }, // ============================================ // Time-Based Achievements // ============================================ EarlyBird: { id: "EarlyBird", name: "Early Bird", description: "Started a session between 5 AM and 7 AM", icon: "๐Ÿฆ", rarity: "common", }, NightOwl: { id: "NightOwl", name: "Night Owl", description: "Coding after midnight", icon: "๐Ÿฆ‰", rarity: "common", }, AllNighter: { id: "AllNighter", name: "All Nighter", description: "Worked through the night (2 AM - 5 AM)", icon: "๐ŸŒ™", rarity: "rare", }, WeekendWarrior: { id: "WeekendWarrior", name: "Weekend Warrior", description: "Coding on a weekend", icon: "โš”๏ธ", rarity: "common", }, DedicatedDeveloper: { id: "DedicatedDeveloper", name: "Dedicated Developer", description: "Coded for 30 days in a row", icon: "๐Ÿ†", rarity: "legendary", maxProgress: 30, }, // ============================================ // Search and Exploration // ============================================ Explorer: { id: "Explorer", name: "Explorer", description: "Used search tools 50 times", icon: "๐Ÿ”", rarity: "common", maxProgress: 50, }, MasterSearcher: { id: "MasterSearcher", name: "Master Searcher", description: "Searched 500 times across files", icon: "๐Ÿ•ต๏ธโ€โ™€๏ธ", rarity: "rare", maxProgress: 500, }, // ============================================ // Session Achievements // ============================================ QuickSession: { id: "QuickSession", name: "Quick Session", description: "Completed a productive session in under 5 minutes", icon: "โšก", rarity: "common", }, FocusedWork: { id: "FocusedWork", name: "Focused Work", description: "Worked for 30 minutes straight", icon: "๐ŸŽฏ", rarity: "common", }, DeepDive: { id: "DeepDive", name: "Deep Dive", description: "Worked for 2 hours continuously", icon: "๐ŸŠโ€โ™€๏ธ", rarity: "rare", }, MarathonSession: { id: "MarathonSession", name: "Marathon Session", description: "5+ hour coding session!", icon: "๐Ÿƒโ€โ™€๏ธ", rarity: "epic", }, UltraMarathon: { id: "UltraMarathon", name: "Ultra Marathon", description: "8 hour coding session!", icon: "๐Ÿฆธโ€โ™€๏ธ", rarity: "epic", }, CodingRetreat: { id: "CodingRetreat", name: "Coding Retreat", description: "12 hour coding session - take care of yourself!", icon: "๐Ÿ•๏ธ", rarity: "legendary", }, // ============================================ // Special Achievements // ============================================ FirstMessage: { id: "FirstMessage", name: "First Message", description: "Sent your first message to Hikari", icon: "โœจ", rarity: "common", maxProgress: 1, }, FirstTool: { id: "FirstTool", name: "First Tool", description: "Used your first tool", icon: "๐Ÿ”ง", rarity: "common", maxProgress: 1, }, FirstCodeBlock: { id: "FirstCodeBlock", name: "First Code", description: "Generated your first code block", icon: "๐Ÿ“ฆ", rarity: "common", maxProgress: 1, }, FirstFileEdit: { id: "FirstFileEdit", name: "First Edit", description: "Made your first file edit", icon: "โœ๏ธ", rarity: "common", maxProgress: 1, }, Polyglot: { id: "Polyglot", name: "Polyglot", description: "Generated code in 5+ languages in one session", icon: "๐ŸŒ", rarity: "rare", maxProgress: 5, }, SpeedCoder: { id: "SpeedCoder", name: "Speed Coder", description: "Generated 10 code blocks in 10 minutes", icon: "๐Ÿš€", rarity: "rare", }, ClaudeConnoisseur: { id: "ClaudeConnoisseur", name: "Claude Connoisseur", description: "Used all available Claude models", icon: "๐ŸŽจ", rarity: "epic", maxProgress: 5, }, MarathonCoder: { id: "MarathonCoder", name: "Marathon Coder", description: "10,000 tokens in a single session", icon: "๐Ÿƒโ€โ™‚๏ธ", rarity: "epic", maxProgress: 10000, }, // ============================================ // Relationship & Greetings // ============================================ GoodMorning: { id: "GoodMorning", name: "Good Morning!", description: "Greeted Hikari with a good morning", icon: "๐ŸŒ…", rarity: "common", maxProgress: 1, }, GoodNight: { id: "GoodNight", name: "Sweet Dreams", description: "Said good night to Hikari", icon: "๐ŸŒƒ", rarity: "common", maxProgress: 1, }, ThankYou: { id: "ThankYou", name: "Grateful Heart", description: "Thanked Hikari for her help", icon: "๐Ÿ™", rarity: "common", maxProgress: 1, }, LoveYou: { id: "LoveYou", name: "Heartfelt", description: "Expressed love to Hikari", icon: "๐Ÿ’•", rarity: "rare", maxProgress: 1, }, HelloHikari: { id: "HelloHikari", name: "Hello Hikari!", description: "Greeted Hikari by name", icon: "๐Ÿ‘‹", rarity: "common", maxProgress: 1, }, HowAreYou: { id: "HowAreYou", name: "Caring Friend", description: "Asked how Hikari is doing", icon: "๐Ÿ’ญ", rarity: "common", maxProgress: 1, }, MissedYou: { id: "MissedYou", name: "Missed You", description: "Told Hikari you missed her", icon: "๐Ÿฅบ", rarity: "rare", maxProgress: 1, }, BackAgain: { id: "BackAgain", name: "Back Again", description: "Announced your return", icon: "๐Ÿ”™", rarity: "common", maxProgress: 1, }, // ============================================ // Personality & Fun // ============================================ EmojiUser: { id: "EmojiUser", name: "Emoji User", description: "Used an emoji in a message", icon: "๐Ÿ˜„", rarity: "common", maxProgress: 1, }, QuestionMaster: { id: "QuestionMaster", name: "Question Master", description: "Asked 20 questions with ?", icon: "โ“", rarity: "common", maxProgress: 20, }, CapsLock: { id: "CapsLock", name: "CAPS LOCK", description: "SENT A MESSAGE IN ALL CAPS", icon: "๐Ÿ”Š", rarity: "common", maxProgress: 1, }, PleaseAndThankYou: { id: "PleaseAndThankYou", name: "Polite Programmer", description: "Uses please in messages", icon: "๐ŸŽฉ", rarity: "common", maxProgress: 1, }, // ============================================ // Emotional // ============================================ Frustrated: { id: "Frustrated", name: "Frustrated", description: "Expressed frustration (we all have those days)", icon: "๐Ÿ˜ค", rarity: "common", maxProgress: 1, }, Excited: { id: "Excited", name: "Excited", description: "Expressed excitement!", icon: "๐ŸŽ‰", rarity: "common", maxProgress: 1, }, Confused: { id: "Confused", name: "Confused", description: "Expressed confusion", icon: "๐Ÿ˜•", rarity: "common", maxProgress: 1, }, Curious: { id: "Curious", name: "Curious Mind", description: "Asked why or how something works", icon: "๐Ÿค”", rarity: "common", maxProgress: 1, }, Impressed: { id: "Impressed", name: "Impressed", description: "Was impressed by something", icon: "๐Ÿ˜ฒ", rarity: "common", maxProgress: 1, }, // ============================================ // Git & Development // ============================================ GitGuru: { id: "GitGuru", name: "Git Guru", description: "Used git commands 10 times", icon: "๐ŸŒฒ", rarity: "common", maxProgress: 10, }, TestWriter: { id: "TestWriter", name: "Test Writer", description: "Created test files", icon: "๐Ÿงช", rarity: "common", maxProgress: 1, }, Debugger: { id: "Debugger", name: "Debugger", description: "Fixed bugs (messages with fix, bug, error)", icon: "๐Ÿ›", rarity: "common", maxProgress: 1, }, CommitKing: { id: "CommitKing", name: "Commit King", description: "Made 50 commits", icon: "๐Ÿ“", rarity: "rare", maxProgress: 50, }, CommitLegend: { id: "CommitLegend", name: "Commit Legend", description: "Made 200 commits!", icon: "๐Ÿ…", rarity: "epic", maxProgress: 200, }, BranchMaster: { id: "BranchMaster", name: "Branch Master", description: "Created 10 branches", icon: "๐ŸŒฟ", rarity: "rare", maxProgress: 10, }, MergeExpert: { id: "MergeExpert", name: "Merge Expert", description: "Merged 20 PRs", icon: "๐Ÿ”€", rarity: "rare", maxProgress: 20, }, ConflictResolver: { id: "ConflictResolver", name: "Conflict Resolver", description: "Resolved merge conflicts", icon: "๐Ÿค", rarity: "rare", maxProgress: 1, }, // ============================================ // Tool Mastery // ============================================ BashMaster: { id: "BashMaster", name: "Bash Master", description: "Used Bash tool 50 times", icon: "๐Ÿ’ป", rarity: "rare", maxProgress: 50, }, FileExplorer: { id: "FileExplorer", name: "File Explorer", description: "Used Read tool 100 times", icon: "๐Ÿ“‚", rarity: "rare", maxProgress: 100, }, SearchExpert: { id: "SearchExpert", name: "Search Expert", description: "Used Grep tool 50 times", icon: "๐Ÿ”Ž", rarity: "rare", maxProgress: 50, }, EditMaster: { id: "EditMaster", name: "Edit Master", description: "Used Edit tool 100 times", icon: "โœ‚๏ธ", rarity: "rare", maxProgress: 100, }, WriteMaster: { id: "WriteMaster", name: "Write Master", description: "Used Write tool 50 times", icon: "๐Ÿ“", rarity: "rare", maxProgress: 50, }, GlobMaster: { id: "GlobMaster", name: "Glob Master", description: "Used Glob tool 100 times", icon: "๐ŸŒ", rarity: "rare", maxProgress: 100, }, TaskMaster: { id: "TaskMaster", name: "Task Master", description: "Used Task tool 50 times", icon: "๐Ÿ“‹", rarity: "rare", maxProgress: 50, }, WebFetcher: { id: "WebFetcher", name: "Web Fetcher", description: "Used WebFetch tool 20 times", icon: "๐ŸŒ", rarity: "rare", maxProgress: 20, }, McpExplorer: { id: "McpExplorer", name: "MCP Explorer", description: "Used MCP tools 50 times", icon: "๐Ÿ”ฎ", rarity: "epic", maxProgress: 50, }, // ============================================ // Daily Streaks // ============================================ WeekStreak: { id: "WeekStreak", name: "Week Streak", description: "7 days in a row!", icon: "๐Ÿ“…", rarity: "common", maxProgress: 7, }, TwoWeekStreak: { id: "TwoWeekStreak", name: "Two Week Streak", description: "14 days in a row!", icon: "๐Ÿ—“๏ธ", rarity: "rare", maxProgress: 14, }, MonthStreak: { id: "MonthStreak", name: "Month Streak", description: "30 days in a row!", icon: "๐Ÿ“†", rarity: "epic", maxProgress: 30, }, QuarterStreak: { id: "QuarterStreak", name: "Quarter Streak", description: "90 days in a row - incredible dedication!", icon: "๐ŸŽ–๏ธ", rarity: "legendary", maxProgress: 90, }, // ============================================ // Time Challenges // ============================================ MorningPerson: { id: "MorningPerson", name: "Morning Person", description: "10 sessions started before 9 AM", icon: "๐ŸŒ„", rarity: "common", maxProgress: 10, }, NightCoder: { id: "NightCoder", name: "Night Coder", description: "10 sessions after 10 PM", icon: "๐ŸŒƒ", rarity: "common", maxProgress: 10, }, LunchBreakCoder: { id: "LunchBreakCoder", name: "Lunch Break Coder", description: "Session during 12-1 PM", icon: "๐Ÿฑ", rarity: "common", maxProgress: 1, }, CoffeeTime: { id: "CoffeeTime", name: "Coffee Time", description: "Session during 3-4 PM", icon: "โ˜•", rarity: "common", maxProgress: 1, }, // ============================================ // Day-Specific // ============================================ MondayMotivation: { id: "MondayMotivation", name: "Monday Motivation", description: "Coding on Monday", icon: "๐Ÿ’ช", rarity: "common", maxProgress: 1, }, FridayFinisher: { id: "FridayFinisher", name: "Friday Finisher", description: "Coding on Friday", icon: "๐ŸŽŠ", rarity: "common", maxProgress: 1, }, HumpDay: { id: "HumpDay", name: "Hump Day", description: "Coding on Wednesday", icon: "๐Ÿซ", rarity: "common", maxProgress: 1, }, // ============================================ // Seasonal/Special Times // ============================================ NewYearCoder: { id: "NewYearCoder", name: "New Year Coder", description: "Coding on January 1st", icon: "๐ŸŽ†", rarity: "rare", maxProgress: 1, }, ValentinesDev: { id: "ValentinesDev", name: "Valentine's Dev", description: "Coding on February 14th", icon: "๐Ÿ’", rarity: "rare", maxProgress: 1, }, SpookyCode: { id: "SpookyCode", name: "Spooky Code", description: "Coding on October 31st", icon: "๐ŸŽƒ", rarity: "rare", maxProgress: 1, }, HolidayCoder: { id: "HolidayCoder", name: "Holiday Coder", description: "Coding on December 25th", icon: "๐ŸŽ„", rarity: "rare", maxProgress: 1, }, LeapDayCoder: { id: "LeapDayCoder", name: "Leap Day Coder", description: "Coding on February 29th - rare!", icon: "๐Ÿธ", rarity: "epic", maxProgress: 1, }, // ============================================ // Message Content // ============================================ LongMessage: { id: "LongMessage", name: "Long Message", description: "Sent a message over 500 characters", icon: "๐Ÿ“œ", rarity: "common", maxProgress: 1, }, NovelWriter: { id: "NovelWriter", name: "Novel Writer", description: "Sent a message over 2000 characters", icon: "๐Ÿ“–", rarity: "rare", maxProgress: 1, }, ShortAndSweet: { id: "ShortAndSweet", name: "Short and Sweet", description: "Completed a task with messages under 50 chars each", icon: "๐Ÿฌ", rarity: "rare", maxProgress: 1, }, CodeInMessage: { id: "CodeInMessage", name: "Code in Message", description: "Included code block in your message", icon: "๐Ÿ’ป", rarity: "common", maxProgress: 1, }, MarkdownMaster: { id: "MarkdownMaster", name: "Markdown Master", description: "Used markdown formatting in message", icon: "๐Ÿ“‹", rarity: "common", maxProgress: 1, }, // ============================================ // Programming Languages // ============================================ RustDeveloper: { id: "RustDeveloper", name: "Rust Developer", description: "Generated Rust code", icon: "๐Ÿฆ€", rarity: "common", maxProgress: 1, }, PythonDeveloper: { id: "PythonDeveloper", name: "Python Developer", description: "Generated Python code", icon: "๐Ÿ", rarity: "common", maxProgress: 1, }, JavaScriptDev: { id: "JavaScriptDev", name: "JavaScript Dev", description: "Generated JavaScript code", icon: "๐Ÿ“œ", rarity: "common", maxProgress: 1, }, TypeScriptDev: { id: "TypeScriptDev", name: "TypeScript Dev", description: "Generated TypeScript code", icon: "๐Ÿ’Ž", rarity: "common", maxProgress: 1, }, GoDeveloper: { id: "GoDeveloper", name: "Go Developer", description: "Generated Go code", icon: "๐Ÿน", rarity: "common", maxProgress: 1, }, CppDeveloper: { id: "CppDeveloper", name: "C++ Developer", description: "Generated C++ code", icon: "โš™๏ธ", rarity: "common", maxProgress: 1, }, JavaDeveloper: { id: "JavaDeveloper", name: "Java Developer", description: "Generated Java code", icon: "โ˜•", rarity: "common", maxProgress: 1, }, HtmlCssDev: { id: "HtmlCssDev", name: "HTML/CSS Dev", description: "Generated HTML/CSS code", icon: "๐ŸŽจ", rarity: "common", maxProgress: 1, }, SqlDeveloper: { id: "SqlDeveloper", name: "SQL Developer", description: "Generated SQL code", icon: "๐Ÿ—„๏ธ", rarity: "common", maxProgress: 1, }, ShellScripter: { id: "ShellScripter", name: "Shell Scripter", description: "Generated shell/bash scripts", icon: "๐Ÿš", rarity: "common", maxProgress: 1, }, FullStackDev: { id: "FullStackDev", name: "Full Stack Dev", description: "Generated code in 10+ languages", icon: "๐ŸŒˆ", rarity: "epic", maxProgress: 10, }, // ============================================ // Project Types // ============================================ FrontendDev: { id: "FrontendDev", name: "Frontend Dev", description: "Worked on frontend files", icon: "๐Ÿ–ผ๏ธ", rarity: "common", maxProgress: 1, }, BackendDev: { id: "BackendDev", name: "Backend Dev", description: "Worked on backend files", icon: "โš™๏ธ", rarity: "common", maxProgress: 1, }, ConfigEditor: { id: "ConfigEditor", name: "Config Editor", description: "Edited config files", icon: "โš™๏ธ", rarity: "common", maxProgress: 1, }, DocWriter: { id: "DocWriter", name: "Doc Writer", description: "Edited documentation", icon: "๐Ÿ“š", rarity: "common", maxProgress: 1, }, // ============================================ // Error Handling // ============================================ ErrorHunter: { id: "ErrorHunter", name: "Error Hunter", description: "Fixed 10 errors", icon: "๐ŸŽฏ", rarity: "common", maxProgress: 10, }, ExceptionSlayer: { id: "ExceptionSlayer", name: "Exception Slayer", description: "Fixed 50 errors", icon: "โš”๏ธ", rarity: "rare", maxProgress: 50, }, BugExterminator: { id: "BugExterminator", name: "Bug Exterminator", description: "Fixed 100 bugs", icon: "๐Ÿชฒ", rarity: "epic", maxProgress: 100, }, // ============================================ // Refactoring // ============================================ CleanCoder: { id: "CleanCoder", name: "Clean Coder", description: "Refactored code", icon: "๐Ÿงน", rarity: "common", maxProgress: 1, }, Optimizer: { id: "Optimizer", name: "Optimizer", description: "Optimized performance", icon: "โšก", rarity: "rare", maxProgress: 1, }, Simplifier: { id: "Simplifier", name: "Simplifier", description: "Simplified complex code", icon: "โœจ", rarity: "rare", maxProgress: 1, }, // ============================================ // Testing // ============================================ TestNovice: { id: "TestNovice", name: "Test Novice", description: "Wrote 10 tests", icon: "๐Ÿงช", rarity: "common", maxProgress: 10, }, TestEnthusiast: { id: "TestEnthusiast", name: "Test Enthusiast", description: "Wrote 50 tests", icon: "๐Ÿ”ฌ", rarity: "rare", maxProgress: 50, }, TestMaster: { id: "TestMaster", name: "Test Master", description: "Wrote 100 tests", icon: "๐Ÿ†", rarity: "epic", maxProgress: 100, }, CoverageKing: { id: "CoverageKing", name: "Coverage King", description: "Achieved test coverage mentions", icon: "๐Ÿ‘‘", rarity: "epic", maxProgress: 1, }, // ============================================ // Documentation // ============================================ Documenter: { id: "Documenter", name: "Documenter", description: "Wrote documentation", icon: "๐Ÿ“", rarity: "common", maxProgress: 1, }, CommentWriter: { id: "CommentWriter", name: "Comment Writer", description: "Added comments to code", icon: "๐Ÿ’ฌ", rarity: "common", maxProgress: 1, }, ReadmeHero: { id: "ReadmeHero", name: "README Hero", description: "Created/edited README files", icon: "๐Ÿ“–", rarity: "common", maxProgress: 1, }, // ============================================ // API & Integration // ============================================ ApiExplorer: { id: "ApiExplorer", name: "API Explorer", description: "Worked with APIs", icon: "๐Ÿ”Œ", rarity: "common", maxProgress: 1, }, DatabaseDev: { id: "DatabaseDev", name: "Database Dev", description: "Worked with databases", icon: "๐Ÿ—„๏ธ", rarity: "common", maxProgress: 1, }, CloudCoder: { id: "CloudCoder", name: "Cloud Coder", description: "Worked with cloud services", icon: "โ˜๏ธ", rarity: "common", maxProgress: 1, }, // ============================================ // Special Milestones // ============================================ CenturyClub: { id: "CenturyClub", name: "Century Club", description: "100 sessions", icon: "๐Ÿ’ฏ", rarity: "rare", maxProgress: 100, }, ThousandSessions: { id: "ThousandSessions", name: "Thousand Sessions", description: "1000 sessions!", icon: "๐ŸŽŠ", rarity: "epic", maxProgress: 1000, }, Veteran: { id: "Veteran", name: "Veteran", description: "Used Hikari for 30+ days total", icon: "๐ŸŽ–๏ธ", rarity: "rare", maxProgress: 30, }, OldTimer: { id: "OldTimer", name: "Old Timer", description: "Used Hikari for 90+ days total", icon: "๐Ÿง“", rarity: "epic", maxProgress: 90, }, Loyalist: { id: "Loyalist", name: "Loyalist", description: "Used Hikari for 365+ days total", icon: "๐Ÿ†", rarity: "legendary", maxProgress: 365, }, // ============================================ // Fun & Easter Eggs // ============================================ Perfectionist: { id: "Perfectionist", name: "Perfectionist", description: "Redo something 5 times", icon: "โœจ", rarity: "common", maxProgress: 5, }, Persistent: { id: "Persistent", name: "Persistent", description: "Asked the same question 3 times", icon: "๐Ÿ”„", rarity: "common", maxProgress: 3, }, Patient: { id: "Patient", name: "Patient", description: "Waited for a long response", icon: "โณ", rarity: "common", maxProgress: 1, }, Speedy: { id: "Speedy", name: "Speedy", description: "Sent 10 messages in 1 minute", icon: "๐Ÿ’จ", rarity: "rare", maxProgress: 10, }, // ============================================ // UI Exploration // ============================================ MultiTasker: { id: "MultiTasker", name: "Multi-Tasker", description: "Used multiple conversations", icon: "๐ŸชŸ", rarity: "common", maxProgress: 1, }, Minimalist: { id: "Minimalist", name: "Minimalist", description: "Used compact mode", icon: "๐Ÿ“ฆ", rarity: "common", maxProgress: 1, }, PrivacyFirst: { id: "PrivacyFirst", name: "Privacy First", description: "Used streamer mode", icon: "๐Ÿ”’", rarity: "common", maxProgress: 1, }, ThemeChanger: { id: "ThemeChanger", name: "Theme Changer", description: "Changed themes", icon: "๐ŸŽจ", rarity: "common", maxProgress: 1, }, SettingsTweaker: { id: "SettingsTweaker", name: "Settings Tweaker", description: "Adjusted settings", icon: "โš™๏ธ", rarity: "common", maxProgress: 1, }, // ============================================ // Achievement Meta // ============================================ AchievementHunter: { id: "AchievementHunter", name: "Achievement Hunter", description: "Unlocked 25 achievements", icon: "๐Ÿ…", rarity: "rare", maxProgress: 25, }, Completionist: { id: "Completionist", name: "Completionist", description: "Unlocked 50 achievements", icon: "๐Ÿ†", rarity: "epic", maxProgress: 50, }, MasterUnlocker: { id: "MasterUnlocker", name: "Master Unlocker", description: "Unlocked 100 achievements", icon: "๐Ÿ”“", rarity: "epic", maxProgress: 100, }, PlatinumStatus: { id: "PlatinumStatus", name: "Platinum Status", description: "Unlocked all achievements!", icon: "๐Ÿ’Ž", rarity: "legendary", }, // ============================================ // Clipboard & Snippets // ============================================ ClipboardCollector: { id: "ClipboardCollector", name: "Clipboard Collector", description: "Used clipboard history", icon: "๐Ÿ“‹", rarity: "common", maxProgress: 1, }, SnippetCreator: { id: "SnippetCreator", name: "Snippet Creator", description: "Created a snippet", icon: "โœ‚๏ธ", rarity: "common", maxProgress: 1, }, SnippetMaster: { id: "SnippetMaster", name: "Snippet Master", description: "Created 20 snippets", icon: "๐Ÿ“š", rarity: "rare", maxProgress: 20, }, // ============================================ // Other Features // ============================================ QuickActionUser: { id: "QuickActionUser", name: "Quick Action User", description: "Used quick actions", icon: "โšก", rarity: "common", maxProgress: 1, }, HistoryBuff: { id: "HistoryBuff", name: "History Buff", description: "Browsed history", icon: "๐Ÿ“œ", rarity: "common", maxProgress: 1, }, Archivist: { id: "Archivist", name: "Archivist", description: "Exported sessions", icon: "๐Ÿ—ƒ๏ธ", rarity: "common", maxProgress: 1, }, SessionExporter: { id: "SessionExporter", name: "Session Exporter", description: "Exported a session", icon: "๐Ÿ“ค", rarity: "common", maxProgress: 1, }, GitPanelUser: { id: "GitPanelUser", name: "Git Panel User", description: "Used the Git panel", icon: "๐ŸŒฒ", rarity: "common", maxProgress: 1, }, FeatureExplorer: { id: "FeatureExplorer", name: "Feature Explorer", description: "Used 10+ features", icon: "๐Ÿ—บ๏ธ", rarity: "rare", maxProgress: 10, }, }; // Initialize all achievements as locked const initialAchievements: Record = {} as Record< AchievementId, Achievement >; for (const [id, def] of Object.entries(achievementDefinitions)) { initialAchievements[id as AchievementId] = { ...def, unlocked: false, progress: 0, }; } // Create the main store function createAchievementsStore() { const { subscribe, update } = writable({ achievements: initialAchievements, totalUnlocked: 0, lastUnlocked: null, }); return { subscribe, unlockAchievement: (event: AchievementUnlockedEvent, playSound: boolean = true) => { update((state) => { const achievement = state.achievements[event.achievement.id]; if (achievement && !achievement.unlocked) { achievement.unlocked = true; achievement.unlockedAt = event.achievement.unlocked_at ? new Date(event.achievement.unlocked_at) : new Date(); state.totalUnlocked++; state.lastUnlocked = achievement; // Play achievement sound only for new unlocks, not when loading saved ones if (playSound) { try { playAchievementSound(); } catch (error) { console.error("Failed to play achievement sound:", error); } } } return state; }); }, updateProgress: (id: AchievementId, progress: number) => { update((state) => { const achievement = state.achievements[id]; if (achievement) { achievement.progress = progress; } return state; }); }, reset: () => { update(() => ({ achievements: initialAchievements, totalUnlocked: 0, lastUnlocked: null, })); }, }; } export const achievementsStore = createAchievementsStore(); // Derived stores for different views export const unlockedAchievements = derived(achievementsStore, ($store) => Object.values($store.achievements).filter((a) => a.unlocked) ); export const lockedAchievements = derived(achievementsStore, ($store) => Object.values($store.achievements).filter((a) => !a.unlocked) ); export const achievementsByRarity = derived(achievementsStore, ($store) => { const byRarity: Record = { common: [], rare: [], epic: [], legendary: [], }; for (const achievement of Object.values($store.achievements)) { byRarity[achievement.rarity].push(achievement); } return byRarity; }); export const achievementProgress = derived(achievementsStore, ($store) => { const total = Object.keys($store.achievements).length; return { unlocked: $store.totalUnlocked, total, percentage: Math.round(($store.totalUnlocked / total) * 100), }; }); // Initialize achievement listener export async function initAchievementsListener() { // Listen for achievement unlocked events await listen("achievement:unlocked", (event) => { achievementsStore.unlockAchievement(event.payload); }); // Load saved achievements from persistent storage try { const savedAchievements = await invoke("load_saved_achievements"); // Update the store with saved achievements (don't play sounds) for (const event of savedAchievements) { achievementsStore.unlockAchievement(event, false); } } catch (error) { console.error("Failed to load saved achievements:", error); } } // Export achievement categories for the display panel export const achievementCategories = [ { name: "Token Milestones", description: "Track your token generation progress", ids: [ "FirstSteps", "GrowingStrong", "BlossomingCoder", "TokenMaster", "TokenBillionaire", "TokenTreasure", ] as AchievementId[], }, { name: "Code Generation", description: "Achievements for generating code", ids: [ "HelloWorld", "CodeWizard", "ThousandBlocks", "CodeFactory", "CodeEmpire", ] as AchievementId[], }, { name: "File Operations", description: "Working with files and projects", ids: ["FileManipulator", "FileArchitect", "FileEngineer", "FileLegend"] as AchievementId[], }, { name: "Conversations", description: "Building our relationship through chat", ids: [ "ConversationStarter", "ChattyKathy", "Conversationalist", "ChatMarathon", "ChatLegend", ] as AchievementId[], }, { name: "Tools & Skills", description: "Mastering different tools", ids: ["Toolsmith", "ToolMaster"] as AchievementId[], }, { name: "Time-Based", description: "When you code matters too!", ids: [ "EarlyBird", "NightOwl", "AllNighter", "WeekendWarrior", "DedicatedDeveloper", ] as AchievementId[], }, { name: "Search & Explore", description: "Finding what you need", ids: ["Explorer", "MasterSearcher"] as AchievementId[], }, { name: "Session Records", description: "Your coding session achievements", ids: [ "QuickSession", "FocusedWork", "DeepDive", "MarathonSession", "UltraMarathon", "CodingRetreat", "MarathonCoder", ] as AchievementId[], }, { name: "Relationship & Greetings", description: "Our special moments together", ids: [ "GoodMorning", "GoodNight", "ThankYou", "LoveYou", "HelloHikari", "HowAreYou", "MissedYou", "BackAgain", ] as AchievementId[], }, { name: "Personality & Fun", description: "Express yourself!", ids: ["EmojiUser", "CapsLock", "QuestionMaster", "PleaseAndThankYou"] as AchievementId[], }, { name: "Emotional", description: "All the feels", ids: ["Frustrated", "Excited", "Confused", "Curious", "Impressed"] as AchievementId[], }, { name: "Git & Development", description: "Version control mastery", ids: [ "GitGuru", "TestWriter", "Debugger", "CommitKing", "CommitLegend", "BranchMaster", "MergeExpert", "ConflictResolver", ] as AchievementId[], }, { name: "Tool Mastery", description: "Master of all tools", ids: [ "BashMaster", "FileExplorer", "SearchExpert", "EditMaster", "WriteMaster", "GlobMaster", "TaskMaster", "WebFetcher", "McpExplorer", ] as AchievementId[], }, { name: "Daily Streaks", description: "Keep the momentum going!", ids: ["WeekStreak", "TwoWeekStreak", "MonthStreak", "QuarterStreak"] as AchievementId[], }, { name: "Time Challenges", description: "When you code", ids: ["MorningPerson", "NightCoder", "LunchBreakCoder", "CoffeeTime"] as AchievementId[], }, { name: "Day-Specific", description: "Special days for coding", ids: ["MondayMotivation", "FridayFinisher", "HumpDay"] as AchievementId[], }, { name: "Seasonal", description: "Holiday coding!", ids: [ "NewYearCoder", "ValentinesDev", "SpookyCode", "HolidayCoder", "LeapDayCoder", ] as AchievementId[], }, { name: "Message Content", description: "How you communicate", ids: [ "LongMessage", "NovelWriter", "ShortAndSweet", "CodeInMessage", "MarkdownMaster", ] as AchievementId[], }, { name: "Programming Languages", description: "Languages you've used", ids: [ "RustDeveloper", "PythonDeveloper", "JavaScriptDev", "TypeScriptDev", "GoDeveloper", "CppDeveloper", "JavaDeveloper", "HtmlCssDev", "SqlDeveloper", "ShellScripter", "FullStackDev", ] as AchievementId[], }, { name: "Project Types", description: "Types of work you do", ids: ["FrontendDev", "BackendDev", "ConfigEditor", "DocWriter"] as AchievementId[], }, { name: "Error Handling", description: "Bug squashing achievements", ids: ["ErrorHunter", "ExceptionSlayer", "BugExterminator"] as AchievementId[], }, { name: "Refactoring", description: "Code improvement", ids: ["CleanCoder", "Optimizer", "Simplifier"] as AchievementId[], }, { name: "Testing", description: "Test-driven achievements", ids: ["TestNovice", "TestEnthusiast", "TestMaster", "CoverageKing"] as AchievementId[], }, { name: "Documentation", description: "Document your work", ids: ["Documenter", "CommentWriter", "ReadmeHero"] as AchievementId[], }, { name: "API & Integration", description: "Working with services", ids: ["ApiExplorer", "DatabaseDev", "CloudCoder"] as AchievementId[], }, { name: "Special Milestones", description: "Long-term achievements", ids: ["CenturyClub", "ThousandSessions", "Veteran", "OldTimer", "Loyalist"] as AchievementId[], }, { name: "Fun & Easter Eggs", description: "Hidden gems", ids: ["Perfectionist", "Persistent", "Patient", "Speedy"] as AchievementId[], }, { name: "UI Exploration", description: "Explore Hikari's features", ids: [ "MultiTasker", "Minimalist", "PrivacyFirst", "ThemeChanger", "SettingsTweaker", ] as AchievementId[], }, { name: "Achievement Meta", description: "Achievements about achievements", ids: [ "AchievementHunter", "Completionist", "MasterUnlocker", "PlatinumStatus", ] as AchievementId[], }, { name: "Clipboard & Snippets", description: "Clipboard and snippet features", ids: ["ClipboardCollector", "SnippetCreator", "SnippetMaster"] as AchievementId[], }, { name: "Other Features", description: "Miscellaneous features", ids: [ "QuickActionUser", "HistoryBuff", "Archivist", "SessionExporter", "GitPanelUser", "FeatureExplorer", ] as AchievementId[], }, { name: "Special", description: "Unique accomplishments", ids: [ "FirstMessage", "FirstTool", "FirstCodeBlock", "FirstFileEdit", "Polyglot", "SpeedCoder", "ClaudeConnoisseur", ] as AchievementId[], }, ];