@myscheme/voice-navigation-sdk 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -5
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +172 -32
- package/dist/microphone-handler.d.ts +7 -0
- package/dist/microphone-handler.d.ts.map +1 -1
- package/dist/microphone-handler.js +106 -22
- package/dist/navigation-controller.d.ts +9 -1
- package/dist/navigation-controller.d.ts.map +1 -1
- package/dist/navigation-controller.js +205 -6
- package/dist/server/azure-speech-handler.d.ts +1 -0
- package/dist/server/azure-speech-handler.d.ts.map +1 -1
- package/dist/server/azure-speech-handler.js +55 -16
- package/dist/server/bedrock-embedding-handler.d.ts +1 -0
- package/dist/server/bedrock-embedding-handler.d.ts.map +1 -1
- package/dist/server/bedrock-embedding-handler.js +84 -24
- package/dist/server/bedrock-handler.d.ts +1 -0
- package/dist/server/bedrock-handler.d.ts.map +1 -1
- package/dist/server/bedrock-handler.js +79 -22
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3 -0
- package/dist/services/bedrock.d.ts +3 -0
- package/dist/services/bedrock.d.ts.map +1 -1
- package/dist/services/bedrock.js +135 -1
- package/dist/services/voice-feedback.d.ts +46 -0
- package/dist/services/voice-feedback.d.ts.map +1 -0
- package/dist/services/voice-feedback.js +332 -0
- package/dist/types.d.ts +4 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +32 -7
- package/package.json +1 -1
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import * as sdk from "microsoft-cognitiveservices-speech-sdk";
|
|
2
|
+
export class VoiceFeedbackService {
|
|
3
|
+
constructor(config) {
|
|
4
|
+
this.synthesizer = null;
|
|
5
|
+
this.isSpeaking = false;
|
|
6
|
+
this.enabled = config.enabled ?? true;
|
|
7
|
+
this.language = config.language || "en-IN";
|
|
8
|
+
this.azureSpeechService = config.azureSpeechService;
|
|
9
|
+
this.bedrockService = config.bedrockService;
|
|
10
|
+
console.log("[VoiceFeedback] Service initialized - enabled:", this.enabled, "language:", this.language);
|
|
11
|
+
}
|
|
12
|
+
setEnabled(enabled) {
|
|
13
|
+
this.enabled = enabled;
|
|
14
|
+
console.log("[VoiceFeedback] Voice feedback", enabled ? "enabled" : "disabled");
|
|
15
|
+
if (!enabled && this.isSpeaking) {
|
|
16
|
+
this.stopSpeaking();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
isEnabled() {
|
|
20
|
+
return this.enabled;
|
|
21
|
+
}
|
|
22
|
+
setLanguage(language) {
|
|
23
|
+
this.language = language;
|
|
24
|
+
console.log("[VoiceFeedback] Language changed to:", language);
|
|
25
|
+
}
|
|
26
|
+
async initializeSynthesizer() {
|
|
27
|
+
if (this.synthesizer) {
|
|
28
|
+
console.log("[VoiceFeedback] Synthesizer already initialized");
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
console.log("[VoiceFeedback] Initializing synthesizer...");
|
|
32
|
+
try {
|
|
33
|
+
const tokenResponse = await this.azureSpeechService.fetchToken();
|
|
34
|
+
const speechConfig = sdk.SpeechConfig.fromAuthorizationToken(tokenResponse.token, tokenResponse.region);
|
|
35
|
+
const voiceName = this.getVoiceForLanguage(this.language);
|
|
36
|
+
speechConfig.speechSynthesisVoiceName = voiceName;
|
|
37
|
+
const audioConfig = sdk.AudioConfig.fromDefaultSpeakerOutput();
|
|
38
|
+
this.synthesizer = new sdk.SpeechSynthesizer(speechConfig, audioConfig);
|
|
39
|
+
console.log("[VoiceFeedback] Synthesizer initialized with voice:", voiceName);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
console.error("[VoiceFeedback] Failed to initialize synthesizer:", error);
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
getVoiceForLanguage(language) {
|
|
47
|
+
const voiceMap = {
|
|
48
|
+
"en-IN": "en-IN-NeerjaNeural",
|
|
49
|
+
"en-US": "en-US-AriaNeural",
|
|
50
|
+
"en-GB": "en-GB-SoniaNeural",
|
|
51
|
+
"hi-IN": "hi-IN-SwaraNeural",
|
|
52
|
+
"ta-IN": "ta-IN-PallaviNeural",
|
|
53
|
+
"te-IN": "te-IN-ShrutiNeural",
|
|
54
|
+
"bn-IN": "bn-IN-TanishaaNeural",
|
|
55
|
+
"mr-IN": "mr-IN-AarohiNeural",
|
|
56
|
+
"gu-IN": "gu-IN-DhwaniNeural",
|
|
57
|
+
"kn-IN": "kn-IN-SapnaNeural",
|
|
58
|
+
"ml-IN": "ml-IN-SobhanaNeural",
|
|
59
|
+
"pa-IN": "pa-IN-SwaraNeural",
|
|
60
|
+
};
|
|
61
|
+
return voiceMap[language] || voiceMap["en-IN"];
|
|
62
|
+
}
|
|
63
|
+
async generateFeedbackMessage(context) {
|
|
64
|
+
const { action, actionResult, transcript, elementInfo } = context;
|
|
65
|
+
const prompt = this.buildPromptForAction(action, actionResult, transcript, elementInfo);
|
|
66
|
+
console.log("[VoiceFeedback] Requesting AI message generation...");
|
|
67
|
+
try {
|
|
68
|
+
const response = await this.bedrockService.generateFeedbackMessage(prompt, this.language);
|
|
69
|
+
console.log("[VoiceFeedback] AI generated message:", response);
|
|
70
|
+
return response;
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
console.error("[VoiceFeedback] Failed to generate AI message:", error);
|
|
74
|
+
const fallback = this.getFallbackMessage(action, actionResult, elementInfo);
|
|
75
|
+
console.log("[VoiceFeedback] Using fallback message:", fallback);
|
|
76
|
+
return fallback;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
buildPromptForAction(action, actionResult, transcript, elementInfo) {
|
|
80
|
+
let prompt = `Generate a brief, natural spoken feedback message (max 10 words) for this voice navigation action:\n\n`;
|
|
81
|
+
prompt += `Action: ${action}\n`;
|
|
82
|
+
if (transcript) {
|
|
83
|
+
prompt += `User said: "${transcript}"\n`;
|
|
84
|
+
}
|
|
85
|
+
if (elementInfo) {
|
|
86
|
+
if (elementInfo.label) {
|
|
87
|
+
prompt += `Element description: ${elementInfo.label}\n`;
|
|
88
|
+
}
|
|
89
|
+
else if (elementInfo.text) {
|
|
90
|
+
prompt += `Element text: ${elementInfo.text}\n`;
|
|
91
|
+
}
|
|
92
|
+
if (elementInfo.type)
|
|
93
|
+
prompt += `Input type: ${elementInfo.type}\n`;
|
|
94
|
+
if (!elementInfo.label && !elementInfo.text && elementInfo.tag) {
|
|
95
|
+
prompt += `Element type: ${elementInfo.tag}\n`;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (actionResult) {
|
|
99
|
+
if (actionResult.info?.pageName) {
|
|
100
|
+
prompt += `Navigating to: ${actionResult.info.pageName}\n`;
|
|
101
|
+
}
|
|
102
|
+
if (actionResult.info?.direction) {
|
|
103
|
+
prompt += `Direction: ${actionResult.info.direction}\n`;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
prompt += `\nGenerate a concise, conversational confirmation message. Be specific about what happened.`;
|
|
107
|
+
return prompt;
|
|
108
|
+
}
|
|
109
|
+
getFallbackMessage(action, actionResult, elementInfo) {
|
|
110
|
+
if (action.startsWith("navigate_") && actionResult?.info?.pageName) {
|
|
111
|
+
return `Navigating to ${actionResult.info.pageName}`;
|
|
112
|
+
}
|
|
113
|
+
if ((action === "focus_next" ||
|
|
114
|
+
action === "tab_next" ||
|
|
115
|
+
action === "focus_previous" ||
|
|
116
|
+
action === "tab_back") &&
|
|
117
|
+
actionResult?.info?.elementTag) {
|
|
118
|
+
if (elementInfo?.label) {
|
|
119
|
+
return elementInfo.label;
|
|
120
|
+
}
|
|
121
|
+
return `${actionResult.info.elementTag}`;
|
|
122
|
+
}
|
|
123
|
+
const actionLabel = action.replace(/_/g, " ");
|
|
124
|
+
return actionLabel;
|
|
125
|
+
}
|
|
126
|
+
async speak(message) {
|
|
127
|
+
if (!this.enabled || !message) {
|
|
128
|
+
console.log("[VoiceFeedback] Skipping speak - enabled:", this.enabled, "message:", !!message);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
console.log("[VoiceFeedback] Attempting to speak:", message);
|
|
132
|
+
try {
|
|
133
|
+
await this.initializeSynthesizer();
|
|
134
|
+
if (!this.synthesizer) {
|
|
135
|
+
console.warn("[VoiceFeedback] Synthesizer not available after initialization");
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (this.isSpeaking) {
|
|
139
|
+
console.log("[VoiceFeedback] Canceling current speech to avoid stacking...");
|
|
140
|
+
this.stopSpeaking();
|
|
141
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
142
|
+
}
|
|
143
|
+
this.isSpeaking = true;
|
|
144
|
+
console.log("[VoiceFeedback] Starting speech synthesis...");
|
|
145
|
+
return new Promise((resolve, reject) => {
|
|
146
|
+
if (!this.synthesizer) {
|
|
147
|
+
reject(new Error("Synthesizer not initialized"));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
this.synthesizer.speakTextAsync(message, (result) => {
|
|
151
|
+
this.isSpeaking = false;
|
|
152
|
+
if (result.reason === sdk.ResultReason.SynthesizingAudioCompleted) {
|
|
153
|
+
console.log("[VoiceFeedback] Speech completed successfully");
|
|
154
|
+
resolve();
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
console.warn("[VoiceFeedback] Speech synthesis failed:", result.reason);
|
|
158
|
+
reject(new Error(`Speech synthesis failed: ${result.reason}`));
|
|
159
|
+
}
|
|
160
|
+
}, (error) => {
|
|
161
|
+
this.isSpeaking = false;
|
|
162
|
+
console.error("[VoiceFeedback] Speech synthesis error:", error);
|
|
163
|
+
reject(error);
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
this.isSpeaking = false;
|
|
169
|
+
console.error("[VoiceFeedback] Failed to speak feedback:", error);
|
|
170
|
+
throw error;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
stopSpeaking() {
|
|
174
|
+
if (this.synthesizer && this.isSpeaking) {
|
|
175
|
+
try {
|
|
176
|
+
this.synthesizer.close();
|
|
177
|
+
this.synthesizer = null;
|
|
178
|
+
this.isSpeaking = false;
|
|
179
|
+
console.log("[VoiceFeedback] Stopped speaking");
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
console.error("[VoiceFeedback] Error stopping speech:", error);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async provideFeedback(context) {
|
|
187
|
+
if (!this.enabled) {
|
|
188
|
+
console.log("[VoiceFeedback] Feedback disabled, skipping");
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
console.log("[VoiceFeedback] Providing feedback for action:", context.action);
|
|
192
|
+
const simpleActions = [
|
|
193
|
+
"scroll_up",
|
|
194
|
+
"scroll_down",
|
|
195
|
+
"scroll_left",
|
|
196
|
+
"scroll_right",
|
|
197
|
+
"scroll_top",
|
|
198
|
+
"scroll_bottom",
|
|
199
|
+
"page_up",
|
|
200
|
+
"page_down",
|
|
201
|
+
"zoom_in",
|
|
202
|
+
"zoom_out",
|
|
203
|
+
"click",
|
|
204
|
+
"enter",
|
|
205
|
+
"submit",
|
|
206
|
+
];
|
|
207
|
+
if (simpleActions.includes(context.action)) {
|
|
208
|
+
console.log("[VoiceFeedback] Using immediate fallback for simple action");
|
|
209
|
+
try {
|
|
210
|
+
const fallbackMessage = this.getFallbackMessage(context.action, context.actionResult, context.elementInfo);
|
|
211
|
+
await this.speak(fallbackMessage);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
console.error("[VoiceFeedback] Fallback failed:", error);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
const messagePromise = this.generateFeedbackMessage(context);
|
|
221
|
+
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("Feedback generation timeout")), 3000));
|
|
222
|
+
const message = await Promise.race([messagePromise, timeoutPromise]);
|
|
223
|
+
console.log("[VoiceFeedback] Generated message:", message);
|
|
224
|
+
if (!message) {
|
|
225
|
+
console.warn("[VoiceFeedback] No message generated");
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
await this.speak(message);
|
|
229
|
+
console.log("[VoiceFeedback] Feedback completed successfully");
|
|
230
|
+
}
|
|
231
|
+
catch (error) {
|
|
232
|
+
console.error("[VoiceFeedback] Error providing feedback:", error);
|
|
233
|
+
try {
|
|
234
|
+
const fallbackMessage = this.getFallbackMessage(context.action, context.actionResult, context.elementInfo);
|
|
235
|
+
console.log("[VoiceFeedback] Using fallback message:", fallbackMessage);
|
|
236
|
+
await this.speak(fallbackMessage);
|
|
237
|
+
}
|
|
238
|
+
catch (fallbackError) {
|
|
239
|
+
console.error("[VoiceFeedback] Fallback also failed:", fallbackError);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
async provideImmediateFeedback(message) {
|
|
244
|
+
if (!this.enabled) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
try {
|
|
248
|
+
await this.speak(message);
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
console.error("[VoiceFeedback] Error providing immediate feedback:", error);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
async announceFocusChange(element, direction) {
|
|
255
|
+
if (!this.enabled) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
const elementInfo = this.extractElementInfo(element);
|
|
259
|
+
await this.provideFeedback({
|
|
260
|
+
action: direction === "next" ? "focus_next" : "focus_previous",
|
|
261
|
+
actionResult: {
|
|
262
|
+
performed: true,
|
|
263
|
+
info: {
|
|
264
|
+
focused: true,
|
|
265
|
+
direction,
|
|
266
|
+
elementTag: element.tagName,
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
elementInfo,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
extractElementInfo(element) {
|
|
273
|
+
const info = {
|
|
274
|
+
tag: element.tagName.toLowerCase(),
|
|
275
|
+
};
|
|
276
|
+
const ariaLabel = element.getAttribute("aria-label");
|
|
277
|
+
const ariaLabelledBy = element.getAttribute("aria-labelledby");
|
|
278
|
+
const title = element.getAttribute("title");
|
|
279
|
+
const alt = element.getAttribute("alt");
|
|
280
|
+
const placeholder = element.getAttribute("placeholder");
|
|
281
|
+
let labelledByText = "";
|
|
282
|
+
if (ariaLabelledBy) {
|
|
283
|
+
const referencedElement = document.getElementById(ariaLabelledBy);
|
|
284
|
+
if (referencedElement) {
|
|
285
|
+
labelledByText = referencedElement.textContent?.trim() || "";
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
let childImageLabel = "";
|
|
289
|
+
if (!ariaLabel && !labelledByText && !title && !alt) {
|
|
290
|
+
const childImage = element.querySelector("img");
|
|
291
|
+
if (childImage) {
|
|
292
|
+
const imgAlt = childImage.getAttribute("alt");
|
|
293
|
+
const imgTitle = childImage.getAttribute("title");
|
|
294
|
+
childImageLabel = imgAlt || imgTitle || "";
|
|
295
|
+
}
|
|
296
|
+
if (!childImageLabel) {
|
|
297
|
+
const svgTitle = element.querySelector("svg title");
|
|
298
|
+
if (svgTitle) {
|
|
299
|
+
childImageLabel = svgTitle.textContent?.trim() || "";
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
let textContent = "";
|
|
304
|
+
if (!childImageLabel &&
|
|
305
|
+
(element instanceof HTMLButtonElement ||
|
|
306
|
+
element instanceof HTMLAnchorElement)) {
|
|
307
|
+
textContent = element.textContent?.trim().slice(0, 50) || "";
|
|
308
|
+
}
|
|
309
|
+
const associatedLabel = element.closest("label")?.textContent?.trim();
|
|
310
|
+
info.label =
|
|
311
|
+
ariaLabel ||
|
|
312
|
+
labelledByText ||
|
|
313
|
+
title ||
|
|
314
|
+
alt ||
|
|
315
|
+
childImageLabel ||
|
|
316
|
+
textContent ||
|
|
317
|
+
placeholder ||
|
|
318
|
+
associatedLabel;
|
|
319
|
+
info.text = textContent || alt || placeholder || undefined;
|
|
320
|
+
if (element instanceof HTMLInputElement) {
|
|
321
|
+
info.type = element.type;
|
|
322
|
+
}
|
|
323
|
+
return info;
|
|
324
|
+
}
|
|
325
|
+
dispose() {
|
|
326
|
+
this.stopSpeaking();
|
|
327
|
+
if (this.synthesizer) {
|
|
328
|
+
this.synthesizer.close();
|
|
329
|
+
this.synthesizer = null;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type CoreNavigationAction = "zoom_in" | "zoom_out" | "scroll_up" | "scroll_down" | "scroll_left" | "scroll_right" | "page_up" | "page_down" | "scroll_top" | "scroll_bottom" | "go_back" | "go_forward" | "reload_page" | "print_page" | "copy_url" | "open_menu" | "close_menu" | "focus_search" | "toggle_fullscreen" | "exit_fullscreen" | "play_media" | "pause_media" | "mute_media" | "unmute_media" | "search_content" | "stop" | "quit" | "tab_next" | "tab_back" | "click" | "enter" | "submit" | "move_left" | "move_right" | "move_up" | "move_down" | "move_beginning" | "move_end" | "select_all" | "select_line" | "type_text" | "cut" | "copy" | "paste" | "clear" | "unknown";
|
|
1
|
+
export type CoreNavigationAction = "zoom_in" | "zoom_out" | "scroll_up" | "scroll_down" | "scroll_left" | "scroll_right" | "page_up" | "page_down" | "scroll_top" | "scroll_bottom" | "go_back" | "go_forward" | "reload_page" | "print_page" | "copy_url" | "open_menu" | "close_menu" | "focus_search" | "toggle_fullscreen" | "exit_fullscreen" | "play_media" | "pause_media" | "mute_media" | "unmute_media" | "search_content" | "stop" | "quit" | "tab_next" | "tab_back" | "focus_next" | "focus_previous" | "click" | "enter" | "submit" | "activate" | "move_left" | "move_right" | "move_up" | "move_down" | "move_beginning" | "move_end" | "select_all" | "select_line" | "type_text" | "cut" | "copy" | "paste" | "clear" | "unknown";
|
|
2
2
|
export type NavigationAction = CoreNavigationAction | `navigate_${string}`;
|
|
3
3
|
export type ButtonPlacement = "bottom-right" | "bottom-left" | "top-right" | "top-left" | "center-right" | "center-left";
|
|
4
4
|
export interface UIConfig {
|
|
@@ -22,6 +22,9 @@ export interface NavigationConfig {
|
|
|
22
22
|
region?: string;
|
|
23
23
|
};
|
|
24
24
|
language?: string;
|
|
25
|
+
voiceFeedback?: {
|
|
26
|
+
enabled?: boolean;
|
|
27
|
+
};
|
|
25
28
|
autoStart?: boolean;
|
|
26
29
|
actionHandlers?: Partial<Record<NavigationAction, (context?: ActionContext) => void>>;
|
|
27
30
|
opensearch?: OpenSearchConfig;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/ui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAuC/E,eAAO,MAAM,2BAA2B,GACtC,YAAW,eAAgC,KAC1C,
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAuC/E,eAAO,MAAM,2BAA2B,GACtC,YAAW,eAAgC,KAC1C,IAkIF,CAAC;AAKF,eAAO,MAAM,qBAAqB,GAChC,YAAW,eAAgC,KAC1C,UAgEF,CAAC;AA+EF,eAAO,MAAM,oBAAoB,GAC/B,gBAAgB,MAAM,KACrB,OAAO,CAAC,UAAU,CAuEpB,CAAC;AAKF,eAAO,MAAM,YAAY,GAAI,IAAI,UAAU,EAAE,MAAM,MAAM,KAAG,IAE3D,CAAC;AAKF,eAAO,MAAM,QAAQ,GAAI,IAAI,UAAU,EAAE,OAAO,eAAe,KAAG,IA0DjE,CAAC;AAKF,eAAO,MAAM,gBAAgB,GAAI,IAAI,UAAU,EAAE,MAAM,MAAM,KAAG,IAE/D,CAAC;AAKF,eAAO,MAAM,qBAAqB,GAChC,IAAI,UAAU,EACd,YAAY,MAAM,EAClB,WAAW,OAAO,EAClB,OAAM,GAAQ,KACb,IAkBF,CAAC;AAKF,eAAO,MAAM,SAAS,GAAI,IAAI,UAAU,EAAE,OAAO,KAAK,KAAG,IAGxD,CAAC;AAKF,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE,SAAQ,GAAQ,KAAG,IAU1D,CAAC"}
|
package/dist/ui.js
CHANGED
|
@@ -85,6 +85,10 @@ export const injectFloatingControlStyles = (placement = "bottom-right") => {
|
|
|
85
85
|
color: #bae6fd;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
.navigate-control__status:empty {
|
|
89
|
+
display: none;
|
|
90
|
+
}
|
|
91
|
+
|
|
88
92
|
.navigate-control__transcript {
|
|
89
93
|
font-size: 0.95rem;
|
|
90
94
|
line-height: 1.4;
|
|
@@ -123,6 +127,15 @@ export const injectFloatingControlStyles = (placement = "bottom-right") => {
|
|
|
123
127
|
background: #7c3aed;
|
|
124
128
|
}
|
|
125
129
|
|
|
130
|
+
.navigate-control--hidden {
|
|
131
|
+
display: none !important;
|
|
132
|
+
visibility: hidden !important;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.navigate-control--hidden .navigate-control__panel {
|
|
136
|
+
display: none !important;
|
|
137
|
+
}
|
|
138
|
+
|
|
126
139
|
@media (max-width: 640px) {
|
|
127
140
|
.navigate-control {
|
|
128
141
|
${mobilePlacementStyles}
|
|
@@ -238,13 +251,12 @@ export const attachToCustomButton = async (buttonSelector) => {
|
|
|
238
251
|
if (!root) {
|
|
239
252
|
root = document.createElement("div");
|
|
240
253
|
root.id = "navigate-control-panel";
|
|
241
|
-
root.className = "navigate-control";
|
|
242
|
-
root.style.display = "none";
|
|
254
|
+
root.className = "navigate-control navigate-control--hidden";
|
|
243
255
|
}
|
|
244
256
|
root.dataset.state = root.dataset.state || "idle";
|
|
245
257
|
root.innerHTML = `
|
|
246
258
|
<div class="navigate-control__panel">
|
|
247
|
-
<div class="navigate-control__status"
|
|
259
|
+
<div class="navigate-control__status"></div>
|
|
248
260
|
<div class="navigate-control__transcript" role="status" aria-live="polite"></div>
|
|
249
261
|
<div class="navigate-control__action" aria-live="polite"></div>
|
|
250
262
|
</div>
|
|
@@ -264,6 +276,7 @@ export const attachToCustomButton = async (buttonSelector) => {
|
|
|
264
276
|
});
|
|
265
277
|
}
|
|
266
278
|
customButton.setAttribute("aria-pressed", "false");
|
|
279
|
+
customButton.dataset.voiceState = "idle";
|
|
267
280
|
if (!customButton.getAttribute("aria-label")) {
|
|
268
281
|
customButton.setAttribute("aria-label", "Start voice control");
|
|
269
282
|
}
|
|
@@ -282,6 +295,7 @@ export const updateStatus = (ui, text) => {
|
|
|
282
295
|
};
|
|
283
296
|
export const setState = (ui, state) => {
|
|
284
297
|
ui.root.dataset.state = state;
|
|
298
|
+
ui.button.dataset.voiceState = state;
|
|
285
299
|
const updateLabel = (text) => {
|
|
286
300
|
if (ui.label) {
|
|
287
301
|
ui.label.textContent = text;
|
|
@@ -292,9 +306,14 @@ export const setState = (ui, state) => {
|
|
|
292
306
|
updateLabel("Start");
|
|
293
307
|
ui.button.setAttribute("aria-pressed", "false");
|
|
294
308
|
ui.button.setAttribute("aria-label", "Start voice control");
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
309
|
+
if (ui.isCustomButton) {
|
|
310
|
+
updateStatus(ui, "");
|
|
311
|
+
updateTranscript(ui, "");
|
|
312
|
+
ui.action.textContent = "";
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
updateStatus(ui, "Tap to start voice control");
|
|
316
|
+
}
|
|
298
317
|
break;
|
|
299
318
|
case "loading":
|
|
300
319
|
updateLabel("Loading...");
|
|
@@ -314,11 +333,17 @@ export const setState = (ui, state) => {
|
|
|
314
333
|
break;
|
|
315
334
|
case "error":
|
|
316
335
|
updateLabel("Error");
|
|
336
|
+
ui.button.setAttribute("aria-pressed", "false");
|
|
317
337
|
ui.button.setAttribute("aria-label", "Error occurred");
|
|
318
338
|
break;
|
|
319
339
|
}
|
|
320
340
|
if (ui.isCustomButton) {
|
|
321
|
-
|
|
341
|
+
if (state === "idle" || state === "error") {
|
|
342
|
+
ui.root.classList.add("navigate-control--hidden");
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
ui.root.classList.remove("navigate-control--hidden");
|
|
346
|
+
}
|
|
322
347
|
}
|
|
323
348
|
};
|
|
324
349
|
export const updateTranscript = (ui, text) => {
|