@@ -5,6 +5,7 @@ import BaseLayout from "@/layouts/Base";
55import BackButton from " @/components/BackButton.astro" ;
66import SharePopover from " @/components/ShareButton.astro" ;
77import KeyboardTrigger from " @/components/KeyboardTrigger.astro" ;
8+ import Speaker from " @/components/Speaker.astro" ;
89
910const meta = {
1011 title: " Varnmala • Listen" ,
@@ -16,20 +17,7 @@ const meta = {
1617<BaseLayout meta ={ meta } >
1718 <BackButton />
1819 <Fragment slot =" header-right" >
19- <div class =" action" >
20- <button type =" button" title =" click audio" id =" mute" class =" mute-button mute-button-audio" ></button >
21- </div >
22-
23- <div class =" voices-dropdown" >
24- <button type =" button" id =" voices-btn" class =" voices-btn" >
25- <span id =" selected-voice-text" >Choose Voice</span > ▼
26- </button >
27- <div id =" voices-options" class =" voices-options" >
28- <div data-name =" " class =" voice-option" >Choose Voice</div >
29- <div data-name =" mudra" class =" voice-option" >👧 Mudra</div >
30- <div data-name =" rutvi" class =" voice-option" >👧 Rutvi</div >
31- </div >
32- </div >
20+ <Speaker />
3321 <KeyboardTrigger />
3422 <SharePopover />
3523 <Help
@@ -52,70 +40,6 @@ const meta = {
5240 import { getRandomValue } from "@/utils/index";
5341
5442 const mainBlock = document.querySelector("#letter") as HTMLElement;
55- const muteButton = document.querySelector("#mute") as HTMLButtonElement;
56- const audioPlayer = document.querySelector("#audioPlayer") as HTMLAudioElement;
57-
58- const voicesButton = document.querySelector("#voices-btn") as HTMLButtonElement;
59- const selectedVoiceText = document.querySelector("#selected-voice-text") as HTMLSpanElement;
60- const voicesOptionsContainer = document.querySelector("#voices-options") as HTMLElement;
61- const voiceOptionElements = Array.from(voicesOptionsContainer.querySelectorAll(".voice-option")) as HTMLElement[];
62-
63- let speakerName: string | null = null;
64- let isMuted = false;
65-
66- function setSpeaker(name: string | null | undefined, displayText: string) {
67- speakerName = name ?? null;
68- selectedVoiceText.textContent = displayText;
69-
70- voiceOptionElements.forEach((opt) => {
71- opt.classList.toggle("active", opt.dataset.name === name);
72- });
73- if (voicesOptionsContainer) {
74- voicesOptionsContainer.classList.remove("show");
75- }
76- }
77-
78- // Initially set the active voice (e.g., the first one)
79- if (voiceOptionElements.length > 0) {
80- //setActiveVoice(voiceOptionElements[0].dataset.name);
81- } else {
82- setSpeaker(null, "Choose Voice");
83- }
84-
85- if (voicesButton) {
86- voicesButton.addEventListener("click", (e) => {
87- e.stopPropagation();
88- voicesOptionsContainer?.classList.toggle("show");
89- });
90- }
91-
92- voiceOptionElements.forEach((option) => {
93- option.addEventListener("click", (e) => {
94- e.stopPropagation();
95- const target = e.currentTarget as HTMLElement;
96- setSpeaker(target.dataset.name, target.textContent || "Voice");
97- });
98- });
99-
100- document.addEventListener("click", (e) => {
101- if (
102- voicesButton &&
103- !voicesButton.contains(e.target as Node) &&
104- voicesOptionsContainer &&
105- !voicesOptionsContainer.contains(e.target as Node)
106- ) {
107- voicesOptionsContainer.classList.remove("show");
108- }
109- });
110-
111- if (muteButton) {
112- muteButton.addEventListener("click", (e: MouseEvent) => {
113- isMuted = !isMuted;
114- audioPlayer.muted = isMuted;
115- const target = e.target as HTMLButtonElement;
116- target.classList.toggle("mute");
117- });
118- }
11943
12044 const getEmoji = (letter: string): string => {
12145 type List = { [key: string]: number[] };
@@ -128,65 +52,30 @@ const meta = {
12852 return "";
12953 };
13054
131- const attachAudio = (key: string, isNumberSound = false) => {
132- if (!speakerName) {
133- console.warn("No speaker selected. Cannot play audio.");
134- return;
135- }
136-
137- let keyName;
138- let location = "/assets/media/";
139- if (isNumberSound) {
140- keyName = key.replace("Digit", "");
141- location += "numbers";
142- } else {
143- keyName = key.replace("Key", "").toLowerCase();
144- location += "alphabets";
145- }
146- const source = `${location}/${speakerName}/${keyName}.ogg`;
147-
148- if (audioPlayer) {
149- audioPlayer.src = source;
150- audioPlayer.load();
151- audioPlayer.oncanplaythrough = async () => {
152- if (!isMuted) {
153- try {
154- await audioPlayer.play();
155- } catch (playError: unknown) {
156- if (
157- playError instanceof Error &&
158- (playError.name === "NotAllowedError" || playError.name === "NotSupportedError")
159- ) {
160- console.error(`Audio play error for ${source}: ${playError.name}. User interaction might be required.`);
161- } else {
162- console.error(`Audio play error for ${source}:`, playError);
163- }
164- }
165- }
166- };
167- audioPlayer.onerror = () => {
168- console.error(`Error loading audio source: ${source}`, audioPlayer.error);
169- };
170- }
171- };
172-
17355 const isNonPrintingKey = (e: KeyboardEvent): boolean => {
17456 const { altKey, ctrlKey, metaKey, shiftKey } = e;
17557 return metaKey || ctrlKey || shiftKey || altKey;
17658 };
17759
60+ //for the audio feature
61+ const attachAudio = (key: string) => {
62+ if (/[A-Z]/i.test(key)) {
63+ window?.playLetterSound(key.toLowerCase());
64+ }
65+ };
66+
17867 document.addEventListener("keydown", (e: KeyboardEvent) => {
179- const { key, code } = e;
68+ const { key } = e;
18069 if (!mainBlock) return;
18170
18271 if (!isNonPrintingKey(e)) {
18372 if (/^[A-Z]$/i.test(key)) {
18473 const emoji = getEmoji(key);
18574 mainBlock.innerHTML = key + emoji;
186- if (muteButton) attachAudio(code );
75+ attachAudio(key );
18776 } else if (/^[0-9]$/.test(key)) {
18877 mainBlock.innerHTML = key;
189- if (muteButton) attachAudio(code, true );
78+ // attachAudio(key );
19079 } else {
19180 const x = String.fromCodePoint(112080);
19281 mainBlock.innerHTML = x;
0 commit comments