Skip to content

Commit 0b24669

Browse files
committed
[RZA-250159]: fixed keyboard and audio toggle button issue
1 parent c6e305b commit 0b24669

File tree

7 files changed

+39
-154
lines changed

7 files changed

+39
-154
lines changed

src/assets/styles/draw.css

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -304,20 +304,7 @@
304304
}
305305

306306
@media (max-width: 480px) {
307-
#keyboard-trigger {
308-
height: 32px !important;
309-
width: 32px !important;
310-
}
311307

312-
.share-trigger-button {
313-
height: 32px !important;
314-
width: 32px !important;
315-
}
316-
317-
.share-trigger-button svg {
318-
height: 12px !important;
319-
width: 12px !important;
320-
}
321308

322309
.controls {
323310
right: 0;
@@ -349,4 +336,4 @@
349336

350337
.controls {
351338
z-index: 100;
352-
}
339+
}

src/assets/styles/varnmala/reader.css

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@
2828
padding: 0.5rem;
2929
}
3030

31-
.container__reader > .letter {
31+
.container__reader>.letter {
3232
width: 100%;
3333
box-sizing: border-box;
34-
margin-left: 4rem;
3534
display: flex;
3635
align-items: center;
3736
justify-content: space-evenly;
@@ -187,12 +186,12 @@
187186
font-size: min(200rem, 70vw);
188187
}
189188

190-
.container__reader > .letter {
189+
.container__reader>.letter {
191190
justify-content: center;
192191
margin-left: auto;
193192
}
194193

195194
.mute-button {
196195
font-size: min(1.5rem, 6vw);
197196
}
198-
}
197+
}

src/components/ControllerContainer.astro

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import BackgroundToggle from "@/components/draw/BgToggle.astro";
77
import ResetButton from "@/components/draw/ResetButton.astro";
88
import SharePopover from "@/components/ShareButton.astro";
99
import Help from "@/components/Help.astro";
10-
import Speak from "@/components/Speaker.astro";
10+
import AudioToggle from "@/components/Speaker.astro";
1111
import KeyboardTrigger from "@/components/KeyboardTrigger.astro";
1212
---
1313

@@ -22,7 +22,7 @@ import KeyboardTrigger from "@/components/KeyboardTrigger.astro";
2222
<KeyboardTrigger />
2323
<SharePopover />
2424
</div>
25-
<Speak />
25+
<AudioToggle />
2626
<Help
2727
title="Draw Keyboard"
2828
description="Draw letters by sliding your finger across the keys! Try the buttons to change the style, make it BIG or small, change the images, pick cool backgrounds, and customize font colors!"
@@ -57,6 +57,7 @@ import KeyboardTrigger from "@/components/KeyboardTrigger.astro";
5757
isKeyboardNav = false;
5858
controlButtons.forEach((btn) => btn.classList.remove("keyboard-focus"));
5959
});
60+
//for the audio feature
6061
document.addEventListener("keydown", (event) => {
6162
const e = event as KeyboardEvent;
6263
if (e.key === "Tab") {

src/components/KeyboardTrigger.astro

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,24 @@
22
import KeyboardIcon from "@/assets/icons/KeyboardIcon.svg";
33
---
44

5-
<button id="keyboard-trigger" aria-label="Toggle virtual keyboard">
5+
<button id="keyboard-trigger" class="show_on_touch" aria-label="Toggle virtual keyboard">
66
<KeyboardIcon />
77
</button>
88

99
<style>
10+
@media (hover: none), (pointer: coarse) {
11+
.show_on_touch {
12+
display: flex !important;
13+
}
14+
}
15+
1016
#keyboard-trigger {
1117
background-color: transparent;
1218
color: var(--primary);
1319
border: 1px solid var(--primary);
1420
border-radius: 50%;
1521
width: 49px;
1622
height: 49px;
17-
display: flex;
1823
align-items: center;
1924
justify-content: center;
2025
cursor: pointer;
@@ -33,6 +38,9 @@ import KeyboardIcon from "@/assets/icons/KeyboardIcon.svg";
3338
</style>
3439

3540
<script>
41+
const showOnTouchElement = document.querySelector(".show_on_touch");
42+
const isTouchDevice = window.matchMedia("(hover: none), (pointer: coarse)").matches;
43+
(showOnTouchElement as HTMLElement).style.display = isTouchDevice ? "flex" : "none";
3644
let currentHiddenInput: HTMLInputElement | null = null;
3745
let isKeyboardForcedOpen: boolean = false;
3846

src/components/Speaker.astro

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@ declare global {
55
}
66
}
77
8-
//Append this to script section where you want to add this feature:
8+
//Append this to script on keydown section where you want to add this feature:
99
/*
10-
document.addEventListener('keydown', (event) => {
11-
const key = event.key;
12-
if (key.length === 1 && key.match(/[a-z]/i)) {
13-
if (window.playLetterSound) {
14-
window.playLetterSound(key.toLowerCase());
15-
}
10+
const attachAudio = (key: string) => {
11+
if (/[A-Z]/i.test(key)) {
12+
window?.playLetterSound(key.toLowerCase());
1613
}
14+
};
15+
document.addEventListener("keydown", (event) => {
16+
const {key} =event;
17+
attachAudio(key)
1718
});
1819
*/
1920
---

src/pages/draw.astro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import "@/assets/styles/draw.css";
33
import Back from "@/components/Back.astro";
44
import ControlsContainer from "@/components/ControllerContainer.astro";
5-
import Keyboard from "@/components/DrawKeyboard.astro";
5+
import DrawComponent from "@/components/DrawKeyboard.astro";
66
import MobileSplash from "@/components/MobileSplash.astro";
77
import BaseLayout from "@/layouts/Base";
88
@@ -19,5 +19,5 @@ const meta = {
1919
<Fragment slot="header-right">
2020
<ControlsContainer />
2121
</Fragment>
22-
<Keyboard />
22+
<DrawComponent />
2323
</BaseLayout>

src/pages/varnmala/listen.astro

Lines changed: 12 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import BaseLayout from "@/layouts/Base";
55
import BackButton from "@/components/BackButton.astro";
66
import SharePopover from "@/components/ShareButton.astro";
77
import KeyboardTrigger from "@/components/KeyboardTrigger.astro";
8+
import Speaker from "@/components/Speaker.astro";
89
910
const 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

Comments
 (0)