generated from nhcarrigan/template
feat: achievement sound
This commit is contained in:
@@ -4,6 +4,7 @@ export enum NotificationType {
|
|||||||
PERMISSION = "permission",
|
PERMISSION = "permission",
|
||||||
CONNECTION = "connection",
|
CONNECTION = "connection",
|
||||||
TASK_START = "task_start",
|
TASK_START = "task_start",
|
||||||
|
ACHIEVEMENT = "achievement",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NotificationSound {
|
export interface NotificationSound {
|
||||||
@@ -45,4 +46,10 @@ export const NOTIFICATION_SOUNDS: Record<NotificationType, NotificationSound> =
|
|||||||
phrase: "Working on it!",
|
phrase: "Working on it!",
|
||||||
volume: 0.6,
|
volume: 0.6,
|
||||||
},
|
},
|
||||||
|
[NotificationType.ACHIEVEMENT]: {
|
||||||
|
type: NotificationType.ACHIEVEMENT,
|
||||||
|
filename: "achievement.mp3",
|
||||||
|
phrase: "Achievement Get~!",
|
||||||
|
volume: 0.8,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
// Achievement sound player using the notification system
|
||||||
|
|
||||||
|
import { soundPlayer } from '$lib/notifications';
|
||||||
|
import { NotificationType } from '$lib/notifications/types';
|
||||||
|
|
||||||
|
export function playAchievementSound() {
|
||||||
|
// Use the soundPlayer which respects global notification settings
|
||||||
|
soundPlayer.play(NotificationType.ACHIEVEMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test function for development
|
||||||
|
export function testAchievementSound() {
|
||||||
|
try {
|
||||||
|
playAchievementSound();
|
||||||
|
console.log('Achievement sound played successfully!');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error playing achievement sound:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ import { writable, derived } from 'svelte/store';
|
|||||||
import { listen } from '@tauri-apps/api/event';
|
import { listen } from '@tauri-apps/api/event';
|
||||||
import { invoke } from '@tauri-apps/api/core';
|
import { invoke } from '@tauri-apps/api/core';
|
||||||
import type { Achievement, AchievementUnlockedEvent, AchievementId } from '$lib/types/achievements';
|
import type { Achievement, AchievementUnlockedEvent, AchievementId } from '$lib/types/achievements';
|
||||||
|
import { playAchievementSound } from '$lib/sounds/achievement';
|
||||||
|
|
||||||
interface AchievementState {
|
interface AchievementState {
|
||||||
achievements: Record<AchievementId, Achievement>;
|
achievements: Record<AchievementId, Achievement>;
|
||||||
@@ -304,7 +305,7 @@ function createAchievementsStore() {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
subscribe,
|
subscribe,
|
||||||
unlockAchievement: (event: AchievementUnlockedEvent) => {
|
unlockAchievement: (event: AchievementUnlockedEvent, playSound: boolean = true) => {
|
||||||
update(state => {
|
update(state => {
|
||||||
const achievement = state.achievements[event.achievement.id];
|
const achievement = state.achievements[event.achievement.id];
|
||||||
if (achievement && !achievement.unlocked) {
|
if (achievement && !achievement.unlocked) {
|
||||||
@@ -312,6 +313,15 @@ function createAchievementsStore() {
|
|||||||
achievement.unlockedAt = event.achievement.unlocked_at ? new Date(event.achievement.unlocked_at) : new Date();
|
achievement.unlockedAt = event.achievement.unlocked_at ? new Date(event.achievement.unlocked_at) : new Date();
|
||||||
state.totalUnlocked++;
|
state.totalUnlocked++;
|
||||||
state.lastUnlocked = achievement;
|
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;
|
return state;
|
||||||
});
|
});
|
||||||
@@ -386,9 +396,9 @@ export async function initAchievementsListener() {
|
|||||||
try {
|
try {
|
||||||
const savedAchievements = await invoke<AchievementUnlockedEvent[]>('load_saved_achievements');
|
const savedAchievements = await invoke<AchievementUnlockedEvent[]>('load_saved_achievements');
|
||||||
|
|
||||||
// Update the store with saved achievements
|
// Update the store with saved achievements (don't play sounds)
|
||||||
for (const event of savedAchievements) {
|
for (const event of savedAchievements) {
|
||||||
achievementsStore.unlockAchievement(event);
|
achievementsStore.unlockAchievement(event, false);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load saved achievements:', error);
|
console.error('Failed to load saved achievements:', error);
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { testAchievementSound } from '$lib/sounds/achievement';
|
||||||
|
import { invoke } from '@tauri-apps/api/core';
|
||||||
|
|
||||||
|
async function testSound() {
|
||||||
|
testAchievementSound();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function triggerAchievement() {
|
||||||
|
// This will trigger an achievement that hasn't been unlocked yet
|
||||||
|
try {
|
||||||
|
await invoke('check_achievements', {
|
||||||
|
eventType: 'message_sent',
|
||||||
|
data: {}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to trigger achievement:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="container mx-auto p-8">
|
||||||
|
<h1 class="text-2xl font-bold mb-6">Achievement Sound Test</h1>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
<button
|
||||||
|
onclick={testSound}
|
||||||
|
class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors"
|
||||||
|
>
|
||||||
|
Test Achievement Sound
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onclick={triggerAchievement}
|
||||||
|
class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600 transition-colors"
|
||||||
|
>
|
||||||
|
Trigger Test Achievement
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<p class="text-sm text-gray-600 dark:text-gray-400 mt-4">
|
||||||
|
Click the first button to test just the sound effect.<br>
|
||||||
|
Click the second button to trigger a real achievement (if any are available to unlock).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
Binary file not shown.
Reference in New Issue
Block a user