@corti/dictation-web 0.0.0-rc.359 → 0.0.0-test.571

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.
Files changed (223) hide show
  1. package/README.md +163 -102
  2. package/dist/CortiDictation.d.ts +6 -2
  3. package/dist/CortiDictation.js +36 -14
  4. package/dist/CortiDictation.js.map +1 -1
  5. package/dist/bundle.js +3888 -1787
  6. package/dist/components/audio-visualiser.d.ts +5 -3
  7. package/dist/components/audio-visualiser.js +38 -46
  8. package/dist/components/audio-visualiser.js.map +1 -1
  9. package/dist/components/corti-dictation.d.ts +136 -0
  10. package/dist/components/corti-dictation.js +273 -0
  11. package/dist/components/corti-dictation.js.map +1 -0
  12. package/dist/components/device-selector.d.ts +14 -0
  13. package/dist/components/device-selector.js +75 -0
  14. package/dist/components/device-selector.js.map +1 -0
  15. package/dist/components/keybinding-selector.d.ts +14 -0
  16. package/dist/components/keybinding-selector.js +81 -0
  17. package/dist/components/keybinding-selector.js.map +1 -0
  18. package/dist/components/language-selector.d.ts +15 -0
  19. package/dist/components/language-selector.js +74 -0
  20. package/dist/components/language-selector.js.map +1 -0
  21. package/dist/components/mode-selector.d.ts +14 -0
  22. package/dist/components/mode-selector.js +73 -0
  23. package/dist/components/mode-selector.js.map +1 -0
  24. package/dist/components/recording-button.d.ts +31 -0
  25. package/dist/components/recording-button.js +262 -0
  26. package/dist/components/recording-button.js.map +1 -0
  27. package/dist/components/settings-menu.d.ts +12 -14
  28. package/dist/components/settings-menu.js +68 -153
  29. package/dist/components/settings-menu.js.map +1 -1
  30. package/dist/constants.d.ts +8 -2
  31. package/dist/constants.js +38 -12
  32. package/dist/constants.js.map +1 -1
  33. package/dist/contexts/dictation-context.d.ts +107 -0
  34. package/dist/contexts/dictation-context.js +290 -0
  35. package/dist/contexts/dictation-context.js.map +1 -0
  36. package/dist/controllers/DictationController.d.ts +35 -0
  37. package/dist/controllers/DictationController.js +130 -0
  38. package/dist/controllers/DictationController.js.map +1 -0
  39. package/dist/controllers/MediaController.d.ts +31 -0
  40. package/dist/controllers/MediaController.js +99 -0
  41. package/dist/controllers/MediaController.js.map +1 -0
  42. package/dist/controllers/devices-controller.d.ts +26 -0
  43. package/dist/controllers/devices-controller.js +99 -0
  44. package/dist/controllers/devices-controller.js.map +1 -0
  45. package/dist/controllers/dictation-controller.d.ts +29 -0
  46. package/dist/controllers/dictation-controller.js +179 -0
  47. package/dist/controllers/dictation-controller.js.map +1 -0
  48. package/dist/controllers/keybinding-controller.d.ts +17 -0
  49. package/dist/controllers/keybinding-controller.js +80 -0
  50. package/dist/controllers/keybinding-controller.js.map +1 -0
  51. package/dist/controllers/languages-controller.d.ts +26 -0
  52. package/dist/controllers/languages-controller.js +83 -0
  53. package/dist/controllers/languages-controller.js.map +1 -0
  54. package/dist/controllers/media-controller.d.ts +24 -0
  55. package/dist/controllers/media-controller.js +115 -0
  56. package/dist/controllers/media-controller.js.map +1 -0
  57. package/dist/index.d.ts +11 -1
  58. package/dist/index.js +39 -3
  59. package/dist/index.js.map +1 -1
  60. package/dist/package.json +14 -0
  61. package/dist/src/components/audio-visualiser.d.ts +14 -0
  62. package/dist/src/components/audio-visualiser.js +57 -0
  63. package/dist/src/components/audio-visualiser.js.map +1 -0
  64. package/dist/src/components/corti-dictation.d.ts +123 -0
  65. package/dist/src/components/corti-dictation.js +224 -0
  66. package/dist/src/components/corti-dictation.js.map +1 -0
  67. package/dist/src/components/device-selector.d.ts +24 -0
  68. package/dist/src/components/device-selector.js +106 -0
  69. package/dist/src/components/device-selector.js.map +1 -0
  70. package/dist/src/components/language-selector.d.ts +24 -0
  71. package/dist/src/components/language-selector.js +100 -0
  72. package/dist/src/components/language-selector.js.map +1 -0
  73. package/dist/src/components/recording-button.d.ts +37 -0
  74. package/dist/src/components/recording-button.js +203 -0
  75. package/dist/src/components/recording-button.js.map +1 -0
  76. package/dist/src/components/settings-menu.d.ts +16 -0
  77. package/dist/src/components/settings-menu.js +80 -0
  78. package/dist/src/components/settings-menu.js.map +1 -0
  79. package/dist/src/constants.d.ts +4 -0
  80. package/dist/src/constants.js +37 -0
  81. package/dist/src/constants.js.map +1 -0
  82. package/dist/src/contexts/dictation-context.d.ts +97 -0
  83. package/dist/src/contexts/dictation-context.js +208 -0
  84. package/dist/src/contexts/dictation-context.js.map +1 -0
  85. package/dist/src/controllers/DictationController.d.ts +35 -0
  86. package/dist/src/controllers/DictationController.js +130 -0
  87. package/dist/src/controllers/DictationController.js.map +1 -0
  88. package/dist/src/controllers/MediaController.d.ts +31 -0
  89. package/dist/src/controllers/MediaController.js +99 -0
  90. package/dist/src/controllers/MediaController.js.map +1 -0
  91. package/dist/src/icons/icons.d.ts +17 -0
  92. package/dist/src/icons/icons.js +158 -0
  93. package/dist/src/icons/icons.js.map +1 -0
  94. package/dist/src/styles/ComponentStyles.d.ts +2 -0
  95. package/dist/src/styles/ComponentStyles.js +18 -0
  96. package/dist/src/styles/ComponentStyles.js.map +1 -0
  97. package/dist/src/styles/audio-visualiser.d.ts +2 -0
  98. package/dist/src/styles/audio-visualiser.js +33 -0
  99. package/dist/src/styles/audio-visualiser.js.map +1 -0
  100. package/dist/src/styles/buttons.d.ts +2 -0
  101. package/dist/src/styles/buttons.js +52 -0
  102. package/dist/src/styles/buttons.js.map +1 -0
  103. package/dist/src/styles/callout.d.ts +2 -0
  104. package/dist/src/styles/callout.js +23 -0
  105. package/dist/src/styles/callout.js.map +1 -0
  106. package/dist/src/styles/default-theme.d.ts +2 -0
  107. package/dist/src/styles/default-theme.js +50 -0
  108. package/dist/src/styles/default-theme.js.map +1 -0
  109. package/dist/src/styles/recording-button.d.ts +2 -0
  110. package/dist/src/styles/recording-button.js +8 -0
  111. package/dist/src/styles/recording-button.js.map +1 -0
  112. package/dist/src/styles/select.d.ts +2 -0
  113. package/dist/src/styles/select.js +36 -0
  114. package/dist/src/styles/select.js.map +1 -0
  115. package/dist/src/styles/settings-menu.d.ts +2 -0
  116. package/dist/src/styles/settings-menu.js +34 -0
  117. package/dist/src/styles/settings-menu.js.map +1 -0
  118. package/dist/src/types.d.ts +7 -0
  119. package/dist/src/types.js +2 -0
  120. package/dist/src/types.js.map +1 -0
  121. package/dist/src/utils/auth.d.ts +9 -0
  122. package/dist/src/utils/auth.js +21 -0
  123. package/dist/src/utils/auth.js.map +1 -0
  124. package/dist/src/utils/converters.d.ts +4 -0
  125. package/dist/src/utils/converters.js +8 -0
  126. package/dist/src/utils/converters.js.map +1 -0
  127. package/dist/src/utils/devices.d.ts +26 -0
  128. package/dist/src/utils/devices.js +53 -0
  129. package/dist/src/utils/devices.js.map +1 -0
  130. package/dist/src/utils/events.d.ts +44 -0
  131. package/dist/src/utils/events.js +88 -0
  132. package/dist/src/utils/events.js.map +1 -0
  133. package/dist/src/utils/languages.d.ts +7 -0
  134. package/dist/src/utils/languages.js +29 -0
  135. package/dist/src/utils/languages.js.map +1 -0
  136. package/dist/src/utils/media.d.ts +6 -0
  137. package/dist/src/utils/media.js +39 -0
  138. package/dist/src/utils/media.js.map +1 -0
  139. package/dist/src/utils/token.d.ts +13 -0
  140. package/dist/src/utils/token.js +60 -0
  141. package/dist/src/utils/token.js.map +1 -0
  142. package/dist/src/utils/validation.d.ts +1 -0
  143. package/dist/src/utils/validation.js +7 -0
  144. package/dist/src/utils/validation.js.map +1 -0
  145. package/dist/stories/audio-visualiser.stories.d.ts +39 -0
  146. package/dist/stories/audio-visualiser.stories.js +71 -0
  147. package/dist/stories/audio-visualiser.stories.js.map +1 -0
  148. package/dist/stories/corti-dictation.stories.d.ts +27 -0
  149. package/dist/stories/corti-dictation.stories.js +129 -0
  150. package/dist/stories/corti-dictation.stories.js.map +1 -0
  151. package/dist/stories/device-selector.stories.d.ts +18 -0
  152. package/dist/stories/device-selector.stories.js +84 -0
  153. package/dist/stories/device-selector.stories.js.map +1 -0
  154. package/dist/stories/language-selector.stories.d.ts +18 -0
  155. package/dist/stories/language-selector.stories.js +53 -0
  156. package/dist/stories/language-selector.stories.js.map +1 -0
  157. package/dist/stories/recording-button.stories.d.ts +27 -0
  158. package/dist/stories/recording-button.stories.js +90 -0
  159. package/dist/stories/recording-button.stories.js.map +1 -0
  160. package/dist/stories/settings-menu.stories.d.ts +23 -0
  161. package/dist/stories/settings-menu.stories.js +156 -0
  162. package/dist/stories/settings-menu.stories.js.map +1 -0
  163. package/dist/styles/ComponentStyles.js +6 -41
  164. package/dist/styles/ComponentStyles.js.map +1 -1
  165. package/dist/styles/audio-visualiser.d.ts +2 -0
  166. package/dist/styles/audio-visualiser.js +33 -0
  167. package/dist/styles/audio-visualiser.js.map +1 -0
  168. package/dist/styles/buttons.js +19 -26
  169. package/dist/styles/buttons.js.map +1 -1
  170. package/dist/styles/callout.js +7 -17
  171. package/dist/styles/callout.js.map +1 -1
  172. package/dist/styles/component-styles.d.ts +3 -0
  173. package/dist/styles/component-styles.js +32 -0
  174. package/dist/styles/component-styles.js.map +1 -0
  175. package/dist/styles/default-theme.d.ts +2 -0
  176. package/dist/styles/default-theme.js +14 -0
  177. package/dist/styles/default-theme.js.map +1 -0
  178. package/dist/styles/keybinding-selector.d.ts +2 -0
  179. package/dist/styles/keybinding-selector.js +72 -0
  180. package/dist/styles/keybinding-selector.js.map +1 -0
  181. package/dist/styles/mode-selector.d.ts +2 -0
  182. package/dist/styles/mode-selector.js +54 -0
  183. package/dist/styles/mode-selector.js.map +1 -0
  184. package/dist/styles/recording-button.d.ts +2 -0
  185. package/dist/styles/recording-button.js +8 -0
  186. package/dist/styles/recording-button.js.map +1 -0
  187. package/dist/styles/select.d.ts +1 -1
  188. package/dist/styles/select.js +14 -18
  189. package/dist/styles/select.js.map +1 -1
  190. package/dist/styles/settings-menu.d.ts +2 -0
  191. package/dist/styles/settings-menu.js +42 -0
  192. package/dist/styles/settings-menu.js.map +1 -0
  193. package/dist/tsconfig.stories.tsbuildinfo +1 -0
  194. package/dist/types.d.ts +9 -8
  195. package/dist/types.js.map +1 -1
  196. package/dist/utils/auth.d.ts +9 -0
  197. package/dist/utils/auth.js +21 -0
  198. package/dist/utils/auth.js.map +1 -0
  199. package/dist/utils/converters.d.ts +4 -0
  200. package/dist/utils/converters.js +8 -0
  201. package/dist/utils/converters.js.map +1 -0
  202. package/dist/utils/devices.d.ts +26 -0
  203. package/dist/utils/devices.js +53 -0
  204. package/dist/utils/devices.js.map +1 -0
  205. package/dist/utils/events.d.ts +53 -0
  206. package/dist/utils/events.js +102 -0
  207. package/dist/utils/events.js.map +1 -0
  208. package/dist/utils/keybinding.d.ts +49 -0
  209. package/dist/utils/keybinding.js +140 -0
  210. package/dist/utils/keybinding.js.map +1 -0
  211. package/dist/utils/languages.d.ts +8 -0
  212. package/dist/utils/languages.js +29 -0
  213. package/dist/utils/languages.js.map +1 -0
  214. package/dist/utils/media.d.ts +6 -0
  215. package/dist/utils/media.js +39 -0
  216. package/dist/utils/media.js.map +1 -0
  217. package/dist/utils/token.d.ts +13 -0
  218. package/dist/utils/token.js +60 -0
  219. package/dist/utils/token.js.map +1 -0
  220. package/dist/utils/validation.d.ts +1 -0
  221. package/dist/utils/validation.js +7 -0
  222. package/dist/utils/validation.js.map +1 -0
  223. package/package.json +29 -55
@@ -0,0 +1,262 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _DictationRecordingButton_instances, _DictationRecordingButton_mediaController, _DictationRecordingButton_dictationController, _DictationRecordingButton_keybindingController, _DictationRecordingButton_handleMouseDown, _DictationRecordingButton_handleMouseUp, _DictationRecordingButton_handleMouseLeave, _DictationRecordingButton_handleWebSocketMessage, _DictationRecordingButton_handleWebSocketError, _DictationRecordingButton_handleWebSocketClose, _DictationRecordingButton_handleStart, _DictationRecordingButton_handleStop;
13
+ import { consume } from "@lit/context";
14
+ import { html, LitElement } from "lit";
15
+ import { customElement, property, state } from "lit/decorators.js";
16
+ import { AUDIO_CHUNK_INTERVAL_MS } from "../constants.js";
17
+ import { accessTokenContext, authConfigContext, debugDisplayAudioContext, dictationConfigContext, keybindingContext, modeContext, recordingStateContext, regionContext, selectedDeviceContext, socketProxyContext, socketUrlContext, tenantNameContext, } from "../contexts/dictation-context.js";
18
+ import { DictationController, } from "../controllers/dictation-controller.js";
19
+ import { KeybindingController } from "../controllers/keybinding-controller.js";
20
+ import { MediaController } from "../controllers/media-controller.js";
21
+ import ButtonStyles from "../styles/buttons.js";
22
+ import RecordingButtonStyles from "../styles/recording-button.js";
23
+ import { audioLevelChangedEvent, commandEvent, errorEvent, networkActivityEvent, recordingStateChangedEvent, streamClosedEvent, transcriptEvent, usageEvent, } from "../utils/events.js";
24
+ import "./audio-visualiser.js";
25
+ import "../icons/icons.js";
26
+ let DictationRecordingButton = class DictationRecordingButton extends LitElement {
27
+ constructor() {
28
+ super(...arguments);
29
+ _DictationRecordingButton_instances.add(this);
30
+ this._recordingState = "stopped";
31
+ this.allowButtonFocus = false;
32
+ _DictationRecordingButton_mediaController.set(this, new MediaController(this));
33
+ _DictationRecordingButton_dictationController.set(this, new DictationController(this));
34
+ _DictationRecordingButton_keybindingController.set(this, new KeybindingController(this));
35
+ _DictationRecordingButton_handleWebSocketMessage.set(this, (message) => {
36
+ switch (message.type) {
37
+ case "CONFIG_ACCEPTED":
38
+ __classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").mediaRecorder?.start(AUDIO_CHUNK_INTERVAL_MS);
39
+ __classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").startAudioLevelMonitoring((level) => {
40
+ this.dispatchEvent(audioLevelChangedEvent(level));
41
+ });
42
+ this.dispatchEvent(recordingStateChangedEvent("recording"));
43
+ break;
44
+ case "CONFIG_DENIED":
45
+ this.dispatchEvent(errorEvent(`Config denied: ${message.reason ?? "Unknown reason"}`));
46
+ __classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStop).call(this);
47
+ break;
48
+ case "CONFIG_TIMEOUT":
49
+ this.dispatchEvent(errorEvent("Config timeout"));
50
+ __classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStop).call(this);
51
+ break;
52
+ case "transcript":
53
+ this.dispatchEvent(transcriptEvent(message));
54
+ break;
55
+ case "command":
56
+ this.dispatchEvent(commandEvent(message));
57
+ break;
58
+ case "usage":
59
+ this.dispatchEvent(usageEvent(message));
60
+ break;
61
+ case "error":
62
+ this.dispatchEvent(errorEvent(message.error));
63
+ __classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStop).call(this);
64
+ break;
65
+ }
66
+ });
67
+ _DictationRecordingButton_handleWebSocketError.set(this, (error) => {
68
+ this.dispatchEvent(errorEvent("Socket error: " + error.message));
69
+ __classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStop).call(this);
70
+ });
71
+ _DictationRecordingButton_handleWebSocketClose.set(this, (event) => {
72
+ this.dispatchEvent(streamClosedEvent(event));
73
+ });
74
+ }
75
+ startRecording() {
76
+ if (this._recordingState !== "stopped") {
77
+ return;
78
+ }
79
+ __classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStart).call(this);
80
+ }
81
+ stopRecording() {
82
+ if (this._recordingState === "stopped") {
83
+ return;
84
+ }
85
+ if (this._recordingState === "initializing") {
86
+ this.addEventListener("recording-state-changed", (event) => {
87
+ if (event.detail
88
+ .state === "recording") {
89
+ __classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStop).call(this);
90
+ }
91
+ }, {
92
+ once: true,
93
+ });
94
+ return;
95
+ }
96
+ __classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStop).call(this);
97
+ }
98
+ toggleRecording() {
99
+ if (this._recordingState === "stopped") {
100
+ __classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStart).call(this);
101
+ }
102
+ else if (this._recordingState === "recording") {
103
+ __classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStop).call(this);
104
+ }
105
+ }
106
+ render() {
107
+ const isLoading = this._recordingState === "initializing" ||
108
+ this._recordingState === "stopping";
109
+ const isRecording = this._recordingState === "recording";
110
+ return html `
111
+ <button
112
+ @mousedown=${__classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleMouseDown)}
113
+ @mouseup=${__classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleMouseUp)}
114
+ @mouseleave=${__classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleMouseLeave)}
115
+ ?disabled=${isLoading}
116
+ class=${isRecording ? "red" : "accent"}
117
+ aria-label=${isRecording ? "Stop recording" : "Start recording"}
118
+ aria-pressed=${isRecording}
119
+ >
120
+ ${isLoading
121
+ ? html `<icon-loading-spinner />`
122
+ : isRecording
123
+ ? html `<icon-recording />`
124
+ : html `<icon-mic-on />`}
125
+ <dictation-audio-visualiser
126
+ .level=${__classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").audioLevel}
127
+ ?active=${isRecording}
128
+ />
129
+ </button>
130
+ `;
131
+ }
132
+ };
133
+ _DictationRecordingButton_mediaController = new WeakMap();
134
+ _DictationRecordingButton_dictationController = new WeakMap();
135
+ _DictationRecordingButton_keybindingController = new WeakMap();
136
+ _DictationRecordingButton_handleWebSocketMessage = new WeakMap();
137
+ _DictationRecordingButton_handleWebSocketError = new WeakMap();
138
+ _DictationRecordingButton_handleWebSocketClose = new WeakMap();
139
+ _DictationRecordingButton_instances = new WeakSet();
140
+ _DictationRecordingButton_handleMouseDown = function _DictationRecordingButton_handleMouseDown(event) {
141
+ if (!this.allowButtonFocus) {
142
+ event.preventDefault();
143
+ }
144
+ if (this._mode === "push-to-talk") {
145
+ this.startRecording();
146
+ }
147
+ };
148
+ _DictationRecordingButton_handleMouseUp = function _DictationRecordingButton_handleMouseUp() {
149
+ if (this._mode === "push-to-talk") {
150
+ this.stopRecording();
151
+ return;
152
+ }
153
+ if (this._mode === "toggle-to-talk") {
154
+ this.toggleRecording();
155
+ }
156
+ };
157
+ _DictationRecordingButton_handleMouseLeave = function _DictationRecordingButton_handleMouseLeave() {
158
+ if (this._mode === "push-to-talk") {
159
+ this.stopRecording();
160
+ }
161
+ };
162
+ _DictationRecordingButton_handleStart = async function _DictationRecordingButton_handleStart() {
163
+ this.dispatchEvent(recordingStateChangedEvent("initializing"));
164
+ try {
165
+ await __classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").initialize(() => {
166
+ if (this._recordingState === "recording") {
167
+ this.dispatchEvent(errorEvent("Recording device access was lost."));
168
+ __classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStop).call(this);
169
+ }
170
+ });
171
+ const isNewConnection = await __classPrivateFieldGet(this, _DictationRecordingButton_dictationController, "f").connect(__classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").mediaRecorder, this._dictationConfig, {
172
+ onClose: __classPrivateFieldGet(this, _DictationRecordingButton_handleWebSocketClose, "f"),
173
+ onError: __classPrivateFieldGet(this, _DictationRecordingButton_handleWebSocketError, "f"),
174
+ onMessage: __classPrivateFieldGet(this, _DictationRecordingButton_handleWebSocketMessage, "f"),
175
+ onNetworkActivity: (direction, data) => {
176
+ this.dispatchEvent(networkActivityEvent(direction, data));
177
+ },
178
+ });
179
+ // configuration has been accepted before
180
+ if (!isNewConnection) {
181
+ __classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").mediaRecorder?.start(AUDIO_CHUNK_INTERVAL_MS);
182
+ __classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").startAudioLevelMonitoring((level) => {
183
+ this.dispatchEvent(audioLevelChangedEvent(level));
184
+ });
185
+ this.dispatchEvent(recordingStateChangedEvent("recording"));
186
+ }
187
+ }
188
+ catch (error) {
189
+ this.dispatchEvent(errorEvent(error));
190
+ await __classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStop).call(this);
191
+ }
192
+ };
193
+ _DictationRecordingButton_handleStop = async function _DictationRecordingButton_handleStop() {
194
+ this.dispatchEvent(recordingStateChangedEvent("stopping"));
195
+ try {
196
+ __classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").stopAudioLevelMonitoring();
197
+ await __classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").stopRecording();
198
+ await __classPrivateFieldGet(this, _DictationRecordingButton_dictationController, "f").disconnect(__classPrivateFieldGet(this, _DictationRecordingButton_handleWebSocketClose, "f"));
199
+ await __classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").cleanup();
200
+ }
201
+ catch (error) {
202
+ this.dispatchEvent(errorEvent(error));
203
+ }
204
+ this.dispatchEvent(recordingStateChangedEvent("stopped"));
205
+ };
206
+ DictationRecordingButton.styles = [RecordingButtonStyles, ButtonStyles];
207
+ __decorate([
208
+ consume({ context: recordingStateContext, subscribe: true }),
209
+ state()
210
+ ], DictationRecordingButton.prototype, "_recordingState", void 0);
211
+ __decorate([
212
+ consume({ context: selectedDeviceContext, subscribe: true }),
213
+ state()
214
+ ], DictationRecordingButton.prototype, "_selectedDevice", void 0);
215
+ __decorate([
216
+ consume({ context: accessTokenContext, subscribe: true }),
217
+ state()
218
+ ], DictationRecordingButton.prototype, "_accessToken", void 0);
219
+ __decorate([
220
+ consume({ context: authConfigContext, subscribe: true }),
221
+ state()
222
+ ], DictationRecordingButton.prototype, "_authConfig", void 0);
223
+ __decorate([
224
+ consume({ context: regionContext, subscribe: true }),
225
+ state()
226
+ ], DictationRecordingButton.prototype, "_region", void 0);
227
+ __decorate([
228
+ consume({ context: tenantNameContext, subscribe: true }),
229
+ state()
230
+ ], DictationRecordingButton.prototype, "_tenantName", void 0);
231
+ __decorate([
232
+ consume({ context: dictationConfigContext, subscribe: true }),
233
+ state()
234
+ ], DictationRecordingButton.prototype, "_dictationConfig", void 0);
235
+ __decorate([
236
+ consume({ context: socketUrlContext, subscribe: true }),
237
+ state()
238
+ ], DictationRecordingButton.prototype, "_socketUrl", void 0);
239
+ __decorate([
240
+ consume({ context: socketProxyContext, subscribe: true }),
241
+ state()
242
+ ], DictationRecordingButton.prototype, "_socketProxy", void 0);
243
+ __decorate([
244
+ consume({ context: debugDisplayAudioContext, subscribe: true }),
245
+ state()
246
+ ], DictationRecordingButton.prototype, "_debug_displayAudio", void 0);
247
+ __decorate([
248
+ consume({ context: keybindingContext, subscribe: true }),
249
+ state()
250
+ ], DictationRecordingButton.prototype, "_keybinding", void 0);
251
+ __decorate([
252
+ consume({ context: modeContext, subscribe: true }),
253
+ state()
254
+ ], DictationRecordingButton.prototype, "_mode", void 0);
255
+ __decorate([
256
+ property({ type: Boolean })
257
+ ], DictationRecordingButton.prototype, "allowButtonFocus", void 0);
258
+ DictationRecordingButton = __decorate([
259
+ customElement("dictation-recording-button")
260
+ ], DictationRecordingButton);
261
+ export { DictationRecordingButton };
262
+ //# sourceMappingURL=recording-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recording-button.js","sourceRoot":"","sources":["../../src/components/recording-button.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Corti } from \"@corti/sdk\";\nimport { consume } from \"@lit/context\";\nimport { type CSSResultGroup, html, LitElement } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { AUDIO_CHUNK_INTERVAL_MS } from \"../constants.js\";\nimport {\n accessTokenContext,\n authConfigContext,\n debugDisplayAudioContext,\n dictationConfigContext,\n keybindingContext,\n modeContext,\n recordingStateContext,\n regionContext,\n selectedDeviceContext,\n socketProxyContext,\n socketUrlContext,\n tenantNameContext,\n} from \"../contexts/dictation-context.js\";\nimport {\n DictationController,\n type TranscribeMessage,\n} from \"../controllers/dictation-controller.js\";\nimport { KeybindingController } from \"../controllers/keybinding-controller.js\";\nimport { MediaController } from \"../controllers/media-controller.js\";\nimport ButtonStyles from \"../styles/buttons.js\";\nimport RecordingButtonStyles from \"../styles/recording-button.js\";\nimport type { DictationMode, ProxyOptions, RecordingState } from \"../types.js\";\nimport {\n audioLevelChangedEvent,\n commandEvent,\n errorEvent,\n networkActivityEvent,\n type RecordingStateChangedEventDetail,\n recordingStateChangedEvent,\n streamClosedEvent,\n transcriptEvent,\n usageEvent,\n} from \"../utils/events.js\";\n\nimport \"./audio-visualiser.js\";\nimport \"../icons/icons.js\";\n\n@customElement(\"dictation-recording-button\")\nexport class DictationRecordingButton extends LitElement {\n @consume({ context: recordingStateContext, subscribe: true })\n @state()\n _recordingState: RecordingState = \"stopped\";\n\n @consume({ context: selectedDeviceContext, subscribe: true })\n @state()\n _selectedDevice?: MediaDeviceInfo;\n\n @consume({ context: accessTokenContext, subscribe: true })\n @state()\n _accessToken?: string;\n\n @consume({ context: authConfigContext, subscribe: true })\n @state()\n _authConfig?: Corti.BearerOptions;\n\n @consume({ context: regionContext, subscribe: true })\n @state()\n _region?: string;\n\n @consume({ context: tenantNameContext, subscribe: true })\n @state()\n _tenantName?: string;\n\n @consume({ context: dictationConfigContext, subscribe: true })\n @state()\n _dictationConfig?: Corti.TranscribeConfig;\n\n @consume({ context: socketUrlContext, subscribe: true })\n @state()\n _socketUrl?: string;\n\n @consume({ context: socketProxyContext, subscribe: true })\n @state()\n _socketProxy?: ProxyOptions;\n\n @consume({ context: debugDisplayAudioContext, subscribe: true })\n @state()\n _debug_displayAudio?: boolean;\n\n @consume({ context: keybindingContext, subscribe: true })\n @state()\n _keybinding?: string | null;\n\n @consume({ context: modeContext, subscribe: true })\n @state()\n _mode?: DictationMode;\n\n @property({ type: Boolean })\n allowButtonFocus: boolean = false;\n\n #mediaController = new MediaController(this);\n #dictationController = new DictationController(this);\n #keybindingController = new KeybindingController(this);\n\n static styles: CSSResultGroup = [RecordingButtonStyles, ButtonStyles];\n\n #handleMouseDown(event: MouseEvent): void {\n if (!this.allowButtonFocus) {\n event.preventDefault();\n }\n\n if (this._mode === \"push-to-talk\") {\n this.startRecording();\n }\n }\n\n #handleMouseUp(): void {\n if (this._mode === \"push-to-talk\") {\n this.stopRecording();\n return;\n }\n\n if (this._mode === \"toggle-to-talk\") {\n this.toggleRecording();\n }\n }\n\n #handleMouseLeave(): void {\n if (this._mode === \"push-to-talk\") {\n this.stopRecording();\n }\n }\n\n #handleWebSocketMessage = (message: TranscribeMessage): void => {\n switch (message.type) {\n case \"CONFIG_ACCEPTED\":\n this.#mediaController.mediaRecorder?.start(AUDIO_CHUNK_INTERVAL_MS);\n this.#mediaController.startAudioLevelMonitoring((level) => {\n this.dispatchEvent(audioLevelChangedEvent(level));\n });\n this.dispatchEvent(recordingStateChangedEvent(\"recording\"));\n break;\n case \"CONFIG_DENIED\":\n this.dispatchEvent(\n errorEvent(`Config denied: ${message.reason ?? \"Unknown reason\"}`),\n );\n this.#handleStop();\n break;\n case \"CONFIG_TIMEOUT\":\n this.dispatchEvent(errorEvent(\"Config timeout\"));\n this.#handleStop();\n break;\n case \"transcript\":\n this.dispatchEvent(transcriptEvent(message));\n break;\n case \"command\":\n this.dispatchEvent(commandEvent(message));\n break;\n case \"usage\":\n this.dispatchEvent(usageEvent(message));\n break;\n case \"error\":\n this.dispatchEvent(errorEvent(message.error));\n this.#handleStop();\n break;\n }\n };\n\n #handleWebSocketError = (error: Error): void => {\n this.dispatchEvent(errorEvent(\"Socket error: \" + error.message));\n this.#handleStop();\n };\n\n #handleWebSocketClose = (event: unknown): void => {\n this.dispatchEvent(streamClosedEvent(event));\n };\n\n async #handleStart(): Promise<void> {\n this.dispatchEvent(recordingStateChangedEvent(\"initializing\"));\n\n try {\n await this.#mediaController.initialize(() => {\n if (this._recordingState === \"recording\") {\n this.dispatchEvent(errorEvent(\"Recording device access was lost.\"));\n this.#handleStop();\n }\n });\n\n const isNewConnection = await this.#dictationController.connect(\n this.#mediaController.mediaRecorder,\n this._dictationConfig,\n {\n onClose: this.#handleWebSocketClose,\n onError: this.#handleWebSocketError,\n onMessage: this.#handleWebSocketMessage,\n onNetworkActivity: (direction, data) => {\n this.dispatchEvent(networkActivityEvent(direction, data));\n },\n },\n );\n\n // configuration has been accepted before\n if (!isNewConnection) {\n this.#mediaController.mediaRecorder?.start(AUDIO_CHUNK_INTERVAL_MS);\n this.#mediaController.startAudioLevelMonitoring((level) => {\n this.dispatchEvent(audioLevelChangedEvent(level));\n });\n this.dispatchEvent(recordingStateChangedEvent(\"recording\"));\n }\n } catch (error) {\n this.dispatchEvent(errorEvent(error));\n await this.#handleStop();\n }\n }\n\n async #handleStop(): Promise<void> {\n this.dispatchEvent(recordingStateChangedEvent(\"stopping\"));\n\n try {\n this.#mediaController.stopAudioLevelMonitoring();\n await this.#mediaController.stopRecording();\n\n await this.#dictationController.disconnect(this.#handleWebSocketClose);\n await this.#mediaController.cleanup();\n } catch (error) {\n this.dispatchEvent(errorEvent(error));\n }\n\n this.dispatchEvent(recordingStateChangedEvent(\"stopped\"));\n }\n\n public startRecording(): void {\n if (this._recordingState !== \"stopped\") {\n return;\n }\n\n this.#handleStart();\n }\n\n public stopRecording(): void {\n if (this._recordingState === \"stopped\") {\n return;\n }\n\n if (this._recordingState === \"initializing\") {\n this.addEventListener(\n \"recording-state-changed\",\n (event) => {\n if (\n (event as CustomEvent<RecordingStateChangedEventDetail>).detail\n .state === \"recording\"\n ) {\n this.#handleStop();\n }\n },\n {\n once: true,\n },\n );\n return;\n }\n\n this.#handleStop();\n }\n\n public toggleRecording(): void {\n if (this._recordingState === \"stopped\") {\n this.#handleStart();\n } else if (this._recordingState === \"recording\") {\n this.#handleStop();\n }\n }\n\n render() {\n const isLoading =\n this._recordingState === \"initializing\" ||\n this._recordingState === \"stopping\";\n const isRecording = this._recordingState === \"recording\";\n\n return html`\n <button\n @mousedown=${this.#handleMouseDown}\n @mouseup=${this.#handleMouseUp}\n @mouseleave=${this.#handleMouseLeave}\n ?disabled=${isLoading}\n class=${isRecording ? \"red\" : \"accent\"}\n aria-label=${isRecording ? \"Stop recording\" : \"Start recording\"}\n aria-pressed=${isRecording}\n >\n ${\n isLoading\n ? html`<icon-loading-spinner />`\n : isRecording\n ? html`<icon-recording />`\n : html`<icon-mic-on />`\n }\n <dictation-audio-visualiser\n .level=${this.#mediaController.audioLevel}\n ?active=${isRecording}\n />\n </button>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"dictation-recording-button\": DictationRecordingButton;\n }\n}\n"]}
@@ -1,20 +1,18 @@
1
- import { LitElement, TemplateResult, CSSResultGroup } from 'lit';
2
- export declare class SettingsMenu extends LitElement {
3
- selectedDevice: MediaDeviceInfo | undefined;
4
- selectedLanguage: string;
5
- settingsDisabled: boolean;
6
- private _devices;
7
- get effectiveSelectedLanguage(): string;
8
- constructor();
9
- connectedCallback(): Promise<void>;
10
- private handleDevicesChange;
1
+ import { type CSSResultGroup, LitElement, nothing } from "lit";
2
+ import type { ConfigurableSettings, RecordingState } from "../types.js";
3
+ import "./device-selector.js";
4
+ import "./keybinding-selector.js";
5
+ import "./language-selector.js";
6
+ import "./mode-selector.js";
7
+ import "../icons/icons.js";
8
+ export declare class DictationSettingsMenu extends LitElement {
9
+ _recordingState: RecordingState;
10
+ settingsEnabled: ConfigurableSettings[];
11
11
  static styles: CSSResultGroup;
12
- private _selectDevice;
13
- private _selectLanguage;
14
- render(): TemplateResult;
12
+ render(): import("lit-html").TemplateResult<1> | typeof nothing;
15
13
  }
16
14
  declare global {
17
15
  interface HTMLElementTagNameMap {
18
- 'settings-menu': SettingsMenu;
16
+ "dictation-settings-menu": DictationSettingsMenu;
19
17
  }
20
18
  }
@@ -4,182 +4,97 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- // mic-selector.ts
8
- import { LitElement, html, css } from 'lit';
9
- import { customElement, property, state } from 'lit/decorators.js';
10
- import ButtonStyles from '../styles/buttons.js';
11
- import SelectStyles from '../styles/select.js';
12
- import { LANGUAGES_SUPPORTED } from '../constants.js';
13
- import { getAudioDevices, getLanguageName } from '../utils.js';
14
- import CalloutStyles from '../styles/callout.js';
15
- let SettingsMenu = class SettingsMenu extends LitElement {
16
- get effectiveSelectedLanguage() {
17
- return this.selectedLanguage || LANGUAGES_SUPPORTED[0] || '';
18
- }
7
+ import { consume } from "@lit/context";
8
+ import { html, LitElement, nothing } from "lit";
9
+ import { customElement, property, state } from "lit/decorators.js";
10
+ import { recordingStateContext } from "../contexts/dictation-context.js";
11
+ import ButtonStyles from "../styles/buttons.js";
12
+ import CalloutStyles from "../styles/callout.js";
13
+ import SettingsMenuStyles from "../styles/settings-menu.js";
14
+ import { commaSeparatedConverter } from "../utils/converters.js";
15
+ import "./device-selector.js";
16
+ import "./keybinding-selector.js";
17
+ import "./language-selector.js";
18
+ import "./mode-selector.js";
19
+ import "../icons/icons.js";
20
+ let DictationSettingsMenu = class DictationSettingsMenu extends LitElement {
19
21
  constructor() {
20
- super();
21
- this.selectedLanguage = '';
22
- this.settingsDisabled = false;
23
- this._devices = [];
24
- navigator.mediaDevices.addEventListener('devicechange', this.handleDevicesChange.bind(this));
25
- }
26
- // on load, get the available devices
27
- async connectedCallback() {
28
- super.connectedCallback();
29
- const deviceResponse = await getAudioDevices();
30
- this._devices = deviceResponse.devices;
31
- }
32
- async handleDevicesChange() {
33
- const deviceResponse = await getAudioDevices();
34
- this._devices = deviceResponse.devices;
35
- }
36
- _selectDevice(deviceId) {
37
- // Find the device object
38
- const device = this._devices.find(d => d.deviceId === deviceId);
39
- if (!device) {
40
- return;
41
- }
42
- this.selectedDevice = device;
43
- this.dispatchEvent(new CustomEvent('recording-devices-changed', {
44
- detail: {
45
- devices: this._devices,
46
- selectedDevice: device,
47
- },
48
- bubbles: true,
49
- composed: true,
50
- }));
51
- }
52
- _selectLanguage(language) {
53
- if (!LANGUAGES_SUPPORTED.includes(language)) {
54
- return;
55
- }
56
- this.selectedLanguage = language;
57
- this.dispatchEvent(new CustomEvent('language-changed', {
58
- detail: {
59
- language: language,
60
- },
61
- bubbles: true,
62
- composed: true,
63
- }));
22
+ super(...arguments);
23
+ this._recordingState = "stopped";
24
+ this.settingsEnabled = ["device", "language"];
64
25
  }
65
26
  render() {
27
+ if (this.settingsEnabled?.length === 0) {
28
+ return nothing;
29
+ }
30
+ const isRecording = this._recordingState === "recording";
31
+ const showDeviceSelector = this.settingsEnabled.includes("device");
32
+ const showLanguageSelector = this.settingsEnabled.includes("language");
33
+ const showModeSelector = this.settingsEnabled.includes("mode");
34
+ const showKeybinding = this.settingsEnabled.includes("keybinding");
66
35
  return html `
67
36
  <div class="mic-selector">
68
37
  <button id="settings-popover-button" popovertarget="settings-popover">
69
- <icon-settings></icon-settings>
38
+ <icon-settings />
70
39
  </button>
71
40
  <div id="settings-popover" popover>
72
41
  <div class="settings-wrapper">
73
- ${this.settingsDisabled
42
+ ${isRecording
74
43
  ? html `
75
44
  <div class="callout warn">
76
45
  Recording is in progress. Stop recording to change settings.
77
46
  </div>
78
47
  `
79
- : ''}
80
- <div class="form-group">
81
- <label id="device-select-label" for="device-select">
82
- Recording Device
83
- </label>
84
- <select
85
- id="device-select"
86
- aria-labelledby="device-select-label"
87
- @change=${(e) => {
88
- this._selectDevice(e.target.value);
89
- }}
90
- ?disabled=${this.settingsDisabled}
91
- >
92
- ${this._devices.map(device => html `
93
- <option
94
- value=${device.deviceId}
95
- ?selected=${this.selectedDevice?.deviceId ===
96
- device.deviceId}
97
- >
98
- ${device.label || 'Unknown Device'}
99
- </option>
100
- `)}
101
- </select>
102
- </div>
103
- <div class="form-group">
104
- <label id="language-select-label" for="language-select">
105
- Dictation Language
106
- </label>
107
- <select
108
- id="language-select"
109
- aria-labelledby="language-select-label"
110
- @change=${(e) => {
111
- this._selectLanguage(e.target.value);
112
- }}
113
- ?disabled=${this.settingsDisabled}
114
- >
115
- ${LANGUAGES_SUPPORTED.map(language => html `
116
- <option
117
- value=${language}
118
- ?selected=${this.effectiveSelectedLanguage === language}
119
- >
120
- ${getLanguageName(language)}
121
- </option>
122
- `)}
123
- </select>
124
- </div>
48
+ : nothing}
49
+ ${showDeviceSelector
50
+ ? html `<dictation-device-selector
51
+ ?disabled=${isRecording}
52
+ />`
53
+ : nothing}
54
+ ${showLanguageSelector
55
+ ? html `<dictation-language-selector
56
+ ?disabled=${isRecording}
57
+ />`
58
+ : nothing}
59
+ ${showModeSelector || showKeybinding
60
+ ? html `
61
+ <div class="settings-group">
62
+ ${showModeSelector
63
+ ? html `<dictation-mode-selector
64
+ ?disabled=${isRecording}
65
+ />`
66
+ : nothing}
67
+ ${showKeybinding
68
+ ? html `<dictation-keybinding-selector
69
+ ?disabled=${isRecording}
70
+ />`
71
+ : nothing}
72
+ </div>
73
+ `
74
+ : nothing}
125
75
  </div>
126
76
  </div>
127
77
  </div>
128
78
  `;
129
79
  }
130
80
  };
131
- SettingsMenu.styles = [
132
- css `
133
- :host {
134
- display: block;
135
- font-family: var(--component-font-family);
136
- }
137
- /* Retain the anchor-name styling for this component */
138
- #settings-popover-button {
139
- anchor-name: --settings_popover_btn;
140
- }
141
- [popover] {
142
- margin: 0;
143
- padding: 16px;
144
- border: 0;
145
- background: var(--card-background);
146
- border: 1px solid var(--card-border-color);
147
- border-radius: var(--card-border-radius);
148
- box-shadow: var(--card-box-shadow);
149
- z-index: 1000;
150
- max-width: 260px;
151
- width: 100%;
152
- min-width: 200px;
153
- position-anchor: --settings_popover_btn;
154
- position-area: bottom span-right;
155
- position-visibility: always;
156
- position-try-fallbacks: flip-inline;
157
- overflow-x: hidden;
158
- }
159
- .settings-wrapper {
160
- display: flex;
161
- flex-direction: column;
162
- gap: 20px;
163
- }
164
- `,
81
+ DictationSettingsMenu.styles = [
82
+ SettingsMenuStyles,
165
83
  ButtonStyles,
166
- SelectStyles,
167
84
  CalloutStyles,
168
85
  ];
169
86
  __decorate([
170
- property({ type: Object })
171
- ], SettingsMenu.prototype, "selectedDevice", void 0);
172
- __decorate([
173
- property({ type: String })
174
- ], SettingsMenu.prototype, "selectedLanguage", void 0);
175
- __decorate([
176
- property({ type: Boolean })
177
- ], SettingsMenu.prototype, "settingsDisabled", void 0);
178
- __decorate([
87
+ consume({ context: recordingStateContext, subscribe: true }),
179
88
  state()
180
- ], SettingsMenu.prototype, "_devices", void 0);
181
- SettingsMenu = __decorate([
182
- customElement('settings-menu')
183
- ], SettingsMenu);
184
- export { SettingsMenu };
89
+ ], DictationSettingsMenu.prototype, "_recordingState", void 0);
90
+ __decorate([
91
+ property({
92
+ converter: commaSeparatedConverter,
93
+ type: Array,
94
+ })
95
+ ], DictationSettingsMenu.prototype, "settingsEnabled", void 0);
96
+ DictationSettingsMenu = __decorate([
97
+ customElement("dictation-settings-menu")
98
+ ], DictationSettingsMenu);
99
+ export { DictationSettingsMenu };
185
100
  //# sourceMappingURL=settings-menu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"settings-menu.js","sourceRoot":"","sources":["../../src/components/settings-menu.ts"],"names":[],"mappings":"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","sourcesContent":["// mic-selector.ts\nimport { LitElement, html, css, TemplateResult, CSSResultGroup } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport ButtonStyles from '../styles/buttons.js';\nimport SelectStyles from '../styles/select.js';\nimport { LANGUAGES_SUPPORTED } from '../constants.js';\nimport { getAudioDevices, getLanguageName } from '../utils.js';\nimport CalloutStyles from '../styles/callout.js';\n\n@customElement('settings-menu')\nexport class SettingsMenu extends LitElement {\n @property({ type: Object })\n selectedDevice: MediaDeviceInfo | undefined;\n\n @property({ type: String })\n selectedLanguage: string = '';\n\n @property({ type: Boolean })\n settingsDisabled: boolean = false;\n\n @state()\n private _devices: MediaDeviceInfo[] = [];\n\n get effectiveSelectedLanguage(): string {\n return this.selectedLanguage || LANGUAGES_SUPPORTED[0] || '';\n }\n\n constructor() {\n super();\n navigator.mediaDevices.addEventListener(\n 'devicechange',\n this.handleDevicesChange.bind(this),\n );\n }\n\n // on load, get the available devices\n async connectedCallback(): Promise<void> {\n super.connectedCallback();\n const deviceResponse = await getAudioDevices();\n this._devices = deviceResponse.devices;\n }\n\n private async handleDevicesChange() {\n const deviceResponse = await getAudioDevices();\n this._devices = deviceResponse.devices;\n }\n\n static styles: CSSResultGroup = [\n css`\n :host {\n display: block;\n font-family: var(--component-font-family);\n }\n /* Retain the anchor-name styling for this component */\n #settings-popover-button {\n anchor-name: --settings_popover_btn;\n }\n [popover] {\n margin: 0;\n padding: 16px;\n border: 0;\n background: var(--card-background);\n border: 1px solid var(--card-border-color);\n border-radius: var(--card-border-radius);\n box-shadow: var(--card-box-shadow);\n z-index: 1000;\n max-width: 260px;\n width: 100%;\n min-width: 200px;\n position-anchor: --settings_popover_btn;\n position-area: bottom span-right;\n position-visibility: always;\n position-try-fallbacks: flip-inline;\n overflow-x: hidden;\n }\n .settings-wrapper {\n display: flex;\n flex-direction: column;\n gap: 20px;\n }\n `,\n ButtonStyles,\n SelectStyles,\n CalloutStyles,\n ];\n private _selectDevice(deviceId: string): void {\n // Find the device object\n const device = this._devices.find(d => d.deviceId === deviceId);\n if (!device) {\n return;\n }\n this.selectedDevice = device;\n this.dispatchEvent(\n new CustomEvent('recording-devices-changed', {\n detail: {\n devices: this._devices,\n selectedDevice: device,\n },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n private _selectLanguage(language: string): void {\n if (!LANGUAGES_SUPPORTED.includes(language)) {\n return;\n }\n this.selectedLanguage = language;\n this.dispatchEvent(\n new CustomEvent('language-changed', {\n detail: {\n language: language,\n },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n render(): TemplateResult {\n return html`\n <div class=\"mic-selector\">\n <button id=\"settings-popover-button\" popovertarget=\"settings-popover\">\n <icon-settings></icon-settings>\n </button>\n <div id=\"settings-popover\" popover>\n <div class=\"settings-wrapper\">\n ${this.settingsDisabled\n ? html`\n <div class=\"callout warn\">\n Recording is in progress. Stop recording to change settings.\n </div>\n `\n : ''}\n <div class=\"form-group\">\n <label id=\"device-select-label\" for=\"device-select\">\n Recording Device\n </label>\n <select\n id=\"device-select\"\n aria-labelledby=\"device-select-label\"\n @change=${(e: Event) => {\n this._selectDevice((e.target as HTMLSelectElement).value);\n }}\n ?disabled=${this.settingsDisabled}\n >\n ${this._devices.map(\n device => html`\n <option\n value=${device.deviceId}\n ?selected=${this.selectedDevice?.deviceId ===\n device.deviceId}\n >\n ${device.label || 'Unknown Device'}\n </option>\n `,\n )}\n </select>\n </div>\n <div class=\"form-group\">\n <label id=\"language-select-label\" for=\"language-select\">\n Dictation Language\n </label>\n <select\n id=\"language-select\"\n aria-labelledby=\"language-select-label\"\n @change=${(e: Event) => {\n this._selectLanguage((e.target as HTMLSelectElement).value);\n }}\n ?disabled=${this.settingsDisabled}\n >\n ${LANGUAGES_SUPPORTED.map(\n language => html`\n <option\n value=${language}\n ?selected=${this.effectiveSelectedLanguage === language}\n >\n ${getLanguageName(language)}\n </option>\n `,\n )}\n </select>\n </div>\n </div>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'settings-menu': SettingsMenu;\n }\n}\n"]}
1
+ {"version":3,"file":"settings-menu.js","sourceRoot":"","sources":["../../src/components/settings-menu.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAuB,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,YAAY,MAAM,sBAAsB,CAAC;AAChD,OAAO,aAAa,MAAM,sBAAsB,CAAC;AACjD,OAAO,kBAAkB,MAAM,4BAA4B,CAAC;AAE5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,sBAAsB,CAAC;AAC9B,OAAO,0BAA0B,CAAC;AAClC,OAAO,wBAAwB,CAAC;AAChC,OAAO,oBAAoB,CAAC;AAC5B,OAAO,mBAAmB,CAAC;AAGpB,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,UAAU;IAA9C;;QAGL,oBAAe,GAAmB,SAAS,CAAC;QAM5C,oBAAe,GAA2B,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IA4EnE,CAAC;IApEC,MAAM;QACJ,IAAI,IAAI,CAAC,eAAe,EAAE,MAAM,KAAK,CAAC,EAAE,CAAC;YACvC,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,KAAK,WAAW,CAAC;QACzD,MAAM,kBAAkB,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnE,MAAM,oBAAoB,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACvE,MAAM,gBAAgB,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC/D,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAEnE,OAAO,IAAI,CAAA;;;;;;;cAQD,WAAW;YACT,CAAC,CAAC,IAAI,CAAA;;;;iBAIL;YACD,CAAC,CAAC,OACN;cAEE,kBAAkB;YAChB,CAAC,CAAC,IAAI,CAAA;8BACQ,WAAW;mBACtB;YACH,CAAC,CAAC,OACN;cAEE,oBAAoB;YAClB,CAAC,CAAC,IAAI,CAAA;8BACQ,WAAW;mBACtB;YACH,CAAC,CAAC,OACN;cAEE,gBAAgB,IAAI,cAAc;YAChC,CAAC,CAAC,IAAI,CAAA;;sBAGA,gBAAgB;gBACd,CAAC,CAAC,IAAI,CAAA;wCACU,WAAW;6BACtB;gBACL,CAAC,CAAC,OACN;sBAEE,cAAc;gBACZ,CAAC,CAAC,IAAI,CAAA;wCACU,WAAW;6BACtB;gBACL,CAAC,CAAC,OACN;;iBAEH;YACD,CAAC,CAAC,OACN;;;;KAIP,CAAC;IACJ,CAAC;;AAzEM,4BAAM,GAAmB;IAC9B,kBAAkB;IAClB,YAAY;IACZ,aAAa;CACd,AAJY,CAIX;AAZF;IAFC,OAAO,CAAC,EAAE,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC5D,KAAK,EAAE;8DACoC;AAM5C;IAJC,QAAQ,CAAC;QACR,SAAS,EAAE,uBAAuB;QAClC,IAAI,EAAE,KAAK;KACZ,CAAC;8DAC+D;AATtD,qBAAqB;IADjC,aAAa,CAAC,yBAAyB,CAAC;GAC5B,qBAAqB,CAqFjC","sourcesContent":["import { consume } from \"@lit/context\";\nimport { type CSSResultGroup, html, LitElement, nothing } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { recordingStateContext } from \"../contexts/dictation-context.js\";\nimport ButtonStyles from \"../styles/buttons.js\";\nimport CalloutStyles from \"../styles/callout.js\";\nimport SettingsMenuStyles from \"../styles/settings-menu.js\";\nimport type { ConfigurableSettings, RecordingState } from \"../types.js\";\nimport { commaSeparatedConverter } from \"../utils/converters.js\";\n\nimport \"./device-selector.js\";\nimport \"./keybinding-selector.js\";\nimport \"./language-selector.js\";\nimport \"./mode-selector.js\";\nimport \"../icons/icons.js\";\n\n@customElement(\"dictation-settings-menu\")\nexport class DictationSettingsMenu extends LitElement {\n @consume({ context: recordingStateContext, subscribe: true })\n @state()\n _recordingState: RecordingState = \"stopped\";\n\n @property({\n converter: commaSeparatedConverter,\n type: Array,\n })\n settingsEnabled: ConfigurableSettings[] = [\"device\", \"language\"];\n\n static styles: CSSResultGroup = [\n SettingsMenuStyles,\n ButtonStyles,\n CalloutStyles,\n ];\n\n render() {\n if (this.settingsEnabled?.length === 0) {\n return nothing;\n }\n\n const isRecording = this._recordingState === \"recording\";\n const showDeviceSelector = this.settingsEnabled.includes(\"device\");\n const showLanguageSelector = this.settingsEnabled.includes(\"language\");\n const showModeSelector = this.settingsEnabled.includes(\"mode\");\n const showKeybinding = this.settingsEnabled.includes(\"keybinding\");\n\n return html`\n <div class=\"mic-selector\">\n <button id=\"settings-popover-button\" popovertarget=\"settings-popover\">\n <icon-settings />\n </button>\n <div id=\"settings-popover\" popover>\n <div class=\"settings-wrapper\">\n ${\n isRecording\n ? html`\n <div class=\"callout warn\">\n Recording is in progress. Stop recording to change settings.\n </div>\n `\n : nothing\n }\n ${\n showDeviceSelector\n ? html`<dictation-device-selector\n ?disabled=${isRecording}\n />`\n : nothing\n }\n ${\n showLanguageSelector\n ? html`<dictation-language-selector\n ?disabled=${isRecording}\n />`\n : nothing\n }\n ${\n showModeSelector || showKeybinding\n ? html`\n <div class=\"settings-group\">\n ${\n showModeSelector\n ? html`<dictation-mode-selector\n ?disabled=${isRecording}\n />`\n : nothing\n }\n ${\n showKeybinding\n ? html`<dictation-keybinding-selector\n ?disabled=${isRecording}\n />`\n : nothing\n }\n </div>\n `\n : nothing\n }\n </div>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"dictation-settings-menu\": DictationSettingsMenu;\n }\n}\n"]}