diff --git a/README.md b/README.md index 96f57ce..7826d0a 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,10 @@ This project is licensed under the AGPL 3.0 - see the [LICENSE](LICENSE) file fo All Versia assets (icon, logo, banners, etc) are licensed under [CC-BY-NC-SA-4.0](https://creativecommons.org/licenses/by-nc-sa/4.0). +## Misskey Audio + +The `public/packs/audio/misskey` directory contains audio files from the Misskey project, which are licensed under the [AGPL 3.0](https://github.com/misskey-dev/misskey/blob/refs/heads/develop/LICENSE). + # Acknowledgments ## Projects diff --git a/components/composer/composer.vue b/components/composer/composer.vue index 85b86c7..7729bc9 100644 --- a/components/composer/composer.vue +++ b/components/composer/composer.vue @@ -120,6 +120,7 @@ import Files from "./files.vue"; const { Control_Enter, Command_Enter } = useMagicKeys(); const ctrlEnterSend = useSetting(SettingIds.CtrlEnterToSend); +const { play } = useAudio(); const fileInput = ref(null); onMounted(() => { @@ -217,6 +218,7 @@ const submit = async () => { }); useEvent("composer:send-edit", data); + play("publish"); useEvent("composer:close"); } else { const { data } = await client.value.postStatus(state.content, { @@ -236,6 +238,7 @@ const submit = async () => { }); useEvent("composer:send", data as Status); + play("publish"); useEvent("composer:close"); } } catch (_e) { diff --git a/components/notes/actions.vue b/components/notes/actions.vue index e499e75..cd71564 100644 --- a/components/notes/actions.vue +++ b/components/notes/actions.vue @@ -52,6 +52,7 @@ const emit = defineEmits<{ quote: []; delete: []; }>(); +const { play } = useAudio(); const confirmLikes = useSetting(SettingIds.ConfirmLike); const confirmReblogs = useSetting(SettingIds.ConfirmReblog); @@ -70,6 +71,7 @@ const like = async () => { } } + play("like"); const id = toast.loading(m.slimy_candid_tiger_read()); const { data } = await client.value.favouriteStatus(noteId); toast.dismiss(id); @@ -148,4 +150,4 @@ const numberFormat = (number = 0) => maximumFractionDigits: 1, }).format(number) : undefined; - \ No newline at end of file + diff --git a/composables/Audio.ts b/composables/Audio.ts new file mode 100644 index 0000000..3dd3800 --- /dev/null +++ b/composables/Audio.ts @@ -0,0 +1,64 @@ +export type AudioNames = "publish" | "like"; + +export type AudioManifest = Record; + +export const useAudio = (): { + play: (name: AudioNames) => void; +} => { + const audio = new Audio(); + + const play = (name: AudioNames) => { + const audioData = audioManifest.manifest.value?.[name]; + + if (!audioData) { + throw new Error(`Audio not found: ${name}`); + } + + const src = audioData.src[ + Math.floor(Math.random() * audioData.src.length) + ] as string; + + audio.src = src; + audio.play(); + }; + + return { play }; +}; + +export const useAudioManifest = () => { + const audioTheme = ref("misskey" as const); + const url = computed(() => `/packs/audio/${audioTheme.value}.json`); + + // Fetch from /packs/audio/:name.json + const manifest = ref(null as null | AudioManifest); + + // Fetch the manifest + watch( + url, + async (url) => { + const response = await fetch(url); + + if (!response.ok) { + throw new Error( + `Failed to fetch audio theme manifest at ${url}`, + ); + } + + manifest.value = await response.json(); + + // Preload all audio files + if (manifest.value) { + for (const audioData of Object.values(manifest.value)) { + for (const src of audioData.src) { + new Audio(src); + } + } + } + }, + { immediate: true }, + ); + + return { audioTheme, manifest, url }; +}; + +export const audioManifest = useAudioManifest(); diff --git a/public/packs/audio/misskey.json b/public/packs/audio/misskey.json new file mode 100644 index 0000000..3e85051 --- /dev/null +++ b/public/packs/audio/misskey.json @@ -0,0 +1,14 @@ +{ + "publish": { + "src": [ + "/packs/audio/misskey/n-aec-4va.mp3", + "/packs/audio/misskey/n-aec-4vb.mp3" + ] + }, + "like": { + "src": [ + "/packs/audio/misskey/bubble1.mp3", + "/packs/audio/misskey/bubble2.mp3" + ] + } +} diff --git a/public/packs/audio/misskey/bubble1.mp3 b/public/packs/audio/misskey/bubble1.mp3 new file mode 100644 index 0000000..05b8ef8 Binary files /dev/null and b/public/packs/audio/misskey/bubble1.mp3 differ diff --git a/public/packs/audio/misskey/bubble2.mp3 b/public/packs/audio/misskey/bubble2.mp3 new file mode 100644 index 0000000..8b4f8df Binary files /dev/null and b/public/packs/audio/misskey/bubble2.mp3 differ diff --git a/public/packs/audio/misskey/n-aec-4va.mp3 b/public/packs/audio/misskey/n-aec-4va.mp3 new file mode 100644 index 0000000..2ef7024 Binary files /dev/null and b/public/packs/audio/misskey/n-aec-4va.mp3 differ diff --git a/public/packs/audio/misskey/n-aec-4vb.mp3 b/public/packs/audio/misskey/n-aec-4vb.mp3 new file mode 100644 index 0000000..a8ad112 Binary files /dev/null and b/public/packs/audio/misskey/n-aec-4vb.mp3 differ