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

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 (189) hide show
  1. package/README.md +14 -5
  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 +2802 -1571
  6. package/dist/components/audio-visualiser.d.ts +3 -2
  7. package/dist/components/audio-visualiser.js +29 -40
  8. package/dist/components/audio-visualiser.js.map +1 -1
  9. package/dist/components/corti-dictation.d.ts +123 -0
  10. package/dist/components/corti-dictation.js +224 -0
  11. package/dist/components/corti-dictation.js.map +1 -0
  12. package/dist/components/device-selector.d.ts +24 -0
  13. package/dist/components/device-selector.js +106 -0
  14. package/dist/components/device-selector.js.map +1 -0
  15. package/dist/components/language-selector.d.ts +24 -0
  16. package/dist/components/language-selector.js +100 -0
  17. package/dist/components/language-selector.js.map +1 -0
  18. package/dist/components/recording-button.d.ts +37 -0
  19. package/dist/components/recording-button.js +203 -0
  20. package/dist/components/recording-button.js.map +1 -0
  21. package/dist/components/settings-menu.d.ts +9 -13
  22. package/dist/components/settings-menu.js +42 -147
  23. package/dist/components/settings-menu.js.map +1 -1
  24. package/dist/constants.d.ts +3 -2
  25. package/dist/constants.js +33 -12
  26. package/dist/constants.js.map +1 -1
  27. package/dist/contexts/dictation-context.d.ts +97 -0
  28. package/dist/contexts/dictation-context.js +208 -0
  29. package/dist/contexts/dictation-context.js.map +1 -0
  30. package/dist/controllers/DictationController.d.ts +35 -0
  31. package/dist/controllers/DictationController.js +130 -0
  32. package/dist/controllers/DictationController.js.map +1 -0
  33. package/dist/controllers/MediaController.d.ts +31 -0
  34. package/dist/controllers/MediaController.js +99 -0
  35. package/dist/controllers/MediaController.js.map +1 -0
  36. package/dist/index.d.ts +9 -1
  37. package/dist/index.js +29 -3
  38. package/dist/index.js.map +1 -1
  39. package/dist/package.json +14 -0
  40. package/dist/src/components/audio-visualiser.d.ts +13 -0
  41. package/dist/src/components/audio-visualiser.js +54 -0
  42. package/dist/src/components/audio-visualiser.js.map +1 -0
  43. package/dist/src/components/corti-dictation.d.ts +108 -0
  44. package/dist/src/components/corti-dictation.js +201 -0
  45. package/dist/src/components/corti-dictation.js.map +1 -0
  46. package/dist/src/components/device-selector.d.ts +24 -0
  47. package/dist/src/components/device-selector.js +106 -0
  48. package/dist/src/components/device-selector.js.map +1 -0
  49. package/dist/src/components/language-selector.d.ts +24 -0
  50. package/dist/src/components/language-selector.js +100 -0
  51. package/dist/src/components/language-selector.js.map +1 -0
  52. package/dist/src/components/recording-button.d.ts +33 -0
  53. package/dist/src/components/recording-button.js +179 -0
  54. package/dist/src/components/recording-button.js.map +1 -0
  55. package/dist/src/components/settings-menu.d.ts +16 -0
  56. package/dist/src/components/settings-menu.js +80 -0
  57. package/dist/src/components/settings-menu.js.map +1 -0
  58. package/dist/src/constants.d.ts +4 -0
  59. package/dist/src/constants.js +19 -0
  60. package/dist/src/constants.js.map +1 -0
  61. package/dist/src/contexts/dictation-context.d.ts +83 -0
  62. package/dist/src/contexts/dictation-context.js +188 -0
  63. package/dist/src/contexts/dictation-context.js.map +1 -0
  64. package/dist/src/controllers/DictationController.d.ts +30 -0
  65. package/dist/src/controllers/DictationController.js +111 -0
  66. package/dist/src/controllers/DictationController.js.map +1 -0
  67. package/dist/src/controllers/MediaController.d.ts +25 -0
  68. package/dist/src/controllers/MediaController.js +83 -0
  69. package/dist/src/controllers/MediaController.js.map +1 -0
  70. package/dist/src/icons/icons.d.ts +17 -0
  71. package/dist/src/icons/icons.js +158 -0
  72. package/dist/src/icons/icons.js.map +1 -0
  73. package/dist/src/styles/ComponentStyles.d.ts +2 -0
  74. package/dist/src/styles/ComponentStyles.js +18 -0
  75. package/dist/src/styles/ComponentStyles.js.map +1 -0
  76. package/dist/src/styles/audio-visualiser.d.ts +2 -0
  77. package/dist/src/styles/audio-visualiser.js +33 -0
  78. package/dist/src/styles/audio-visualiser.js.map +1 -0
  79. package/dist/src/styles/buttons.d.ts +2 -0
  80. package/dist/src/styles/buttons.js +52 -0
  81. package/dist/src/styles/buttons.js.map +1 -0
  82. package/dist/src/styles/callout.d.ts +2 -0
  83. package/dist/src/styles/callout.js +23 -0
  84. package/dist/src/styles/callout.js.map +1 -0
  85. package/dist/src/styles/default-theme.d.ts +2 -0
  86. package/dist/src/styles/default-theme.js +50 -0
  87. package/dist/src/styles/default-theme.js.map +1 -0
  88. package/dist/src/styles/recording-button.d.ts +2 -0
  89. package/dist/src/styles/recording-button.js +8 -0
  90. package/dist/src/styles/recording-button.js.map +1 -0
  91. package/dist/src/styles/select.d.ts +2 -0
  92. package/dist/src/styles/select.js +36 -0
  93. package/dist/src/styles/select.js.map +1 -0
  94. package/dist/src/styles/settings-menu.d.ts +2 -0
  95. package/dist/src/styles/settings-menu.js +34 -0
  96. package/dist/src/styles/settings-menu.js.map +1 -0
  97. package/dist/src/types.d.ts +2 -0
  98. package/dist/src/types.js +2 -0
  99. package/dist/src/types.js.map +1 -0
  100. package/dist/src/utils/auth.d.ts +9 -0
  101. package/dist/src/utils/auth.js +21 -0
  102. package/dist/src/utils/auth.js.map +1 -0
  103. package/dist/src/utils/converters.d.ts +4 -0
  104. package/dist/src/utils/converters.js +5 -0
  105. package/dist/src/utils/converters.js.map +1 -0
  106. package/dist/src/utils/devices.d.ts +26 -0
  107. package/dist/src/utils/devices.js +53 -0
  108. package/dist/src/utils/devices.js.map +1 -0
  109. package/dist/src/utils/events.d.ts +37 -0
  110. package/dist/src/utils/events.js +88 -0
  111. package/dist/src/utils/events.js.map +1 -0
  112. package/dist/src/utils/languages.d.ts +7 -0
  113. package/dist/src/utils/languages.js +28 -0
  114. package/dist/src/utils/languages.js.map +1 -0
  115. package/dist/src/utils/media.d.ts +6 -0
  116. package/dist/src/utils/media.js +27 -0
  117. package/dist/src/utils/media.js.map +1 -0
  118. package/dist/src/utils/token.d.ts +13 -0
  119. package/dist/src/utils/token.js +59 -0
  120. package/dist/src/utils/token.js.map +1 -0
  121. package/dist/src/utils/validation.d.ts +1 -0
  122. package/dist/src/utils/validation.js +7 -0
  123. package/dist/src/utils/validation.js.map +1 -0
  124. package/dist/stories/audio-visualiser.stories.d.ts +39 -0
  125. package/dist/stories/audio-visualiser.stories.js +71 -0
  126. package/dist/stories/audio-visualiser.stories.js.map +1 -0
  127. package/dist/stories/corti-dictation.stories.d.ts +27 -0
  128. package/dist/stories/corti-dictation.stories.js +129 -0
  129. package/dist/stories/corti-dictation.stories.js.map +1 -0
  130. package/dist/stories/device-selector.stories.d.ts +18 -0
  131. package/dist/stories/device-selector.stories.js +84 -0
  132. package/dist/stories/device-selector.stories.js.map +1 -0
  133. package/dist/stories/language-selector.stories.d.ts +18 -0
  134. package/dist/stories/language-selector.stories.js +53 -0
  135. package/dist/stories/language-selector.stories.js.map +1 -0
  136. package/dist/stories/recording-button.stories.d.ts +27 -0
  137. package/dist/stories/recording-button.stories.js +90 -0
  138. package/dist/stories/recording-button.stories.js.map +1 -0
  139. package/dist/stories/settings-menu.stories.d.ts +23 -0
  140. package/dist/stories/settings-menu.stories.js +156 -0
  141. package/dist/stories/settings-menu.stories.js.map +1 -0
  142. package/dist/styles/ComponentStyles.js +6 -41
  143. package/dist/styles/ComponentStyles.js.map +1 -1
  144. package/dist/styles/audio-visualiser.d.ts +2 -0
  145. package/dist/styles/audio-visualiser.js +33 -0
  146. package/dist/styles/audio-visualiser.js.map +1 -0
  147. package/dist/styles/buttons.js +19 -25
  148. package/dist/styles/buttons.js.map +1 -1
  149. package/dist/styles/callout.js +7 -17
  150. package/dist/styles/callout.js.map +1 -1
  151. package/dist/styles/default-theme.d.ts +2 -0
  152. package/dist/styles/default-theme.js +14 -0
  153. package/dist/styles/default-theme.js.map +1 -0
  154. package/dist/styles/recording-button.d.ts +2 -0
  155. package/dist/styles/recording-button.js +8 -0
  156. package/dist/styles/recording-button.js.map +1 -0
  157. package/dist/styles/select.js +9 -9
  158. package/dist/styles/select.js.map +1 -1
  159. package/dist/styles/settings-menu.d.ts +2 -0
  160. package/dist/styles/settings-menu.js +34 -0
  161. package/dist/styles/settings-menu.js.map +1 -0
  162. package/dist/tsconfig.stories.tsbuildinfo +1 -0
  163. package/dist/types.d.ts +7 -8
  164. package/dist/types.js.map +1 -1
  165. package/dist/utils/auth.d.ts +9 -0
  166. package/dist/utils/auth.js +21 -0
  167. package/dist/utils/auth.js.map +1 -0
  168. package/dist/utils/converters.d.ts +4 -0
  169. package/dist/utils/converters.js +8 -0
  170. package/dist/utils/converters.js.map +1 -0
  171. package/dist/utils/devices.d.ts +26 -0
  172. package/dist/utils/devices.js +53 -0
  173. package/dist/utils/devices.js.map +1 -0
  174. package/dist/utils/events.d.ts +44 -0
  175. package/dist/utils/events.js +88 -0
  176. package/dist/utils/events.js.map +1 -0
  177. package/dist/utils/languages.d.ts +7 -0
  178. package/dist/utils/languages.js +29 -0
  179. package/dist/utils/languages.js.map +1 -0
  180. package/dist/utils/media.d.ts +6 -0
  181. package/dist/utils/media.js +39 -0
  182. package/dist/utils/media.js.map +1 -0
  183. package/dist/utils/token.d.ts +13 -0
  184. package/dist/utils/token.js +59 -0
  185. package/dist/utils/token.js.map +1 -0
  186. package/dist/utils/validation.d.ts +1 -0
  187. package/dist/utils/validation.js +7 -0
  188. package/dist/utils/validation.js.map +1 -0
  189. package/package.json +23 -50
@@ -0,0 +1,24 @@
1
+ import { LitElement, type PropertyValues } from "lit";
2
+ export declare class LanguageSelector extends LitElement {
3
+ private _languages?;
4
+ private _dictationConfig?;
5
+ disabled: boolean;
6
+ _region?: string;
7
+ /**
8
+ * Internal cache of loaded languages to check if languages were auto-loaded or provided via property
9
+ * @private
10
+ */
11
+ private _loadedLanguages;
12
+ private _languagesAutoLoaded;
13
+ static styles: import("lit").CSSResult;
14
+ connectedCallback(): Promise<void>;
15
+ updated(changedProperties: PropertyValues<this>): void;
16
+ private _loadLanguages;
17
+ private _handleSelectLanguage;
18
+ render(): import("lit-html").TemplateResult<1>;
19
+ }
20
+ declare global {
21
+ interface HTMLElementTagNameMap {
22
+ "language-selector": LanguageSelector;
23
+ }
24
+ }
@@ -0,0 +1,100 @@
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
+ import { consume } from "@lit/context";
8
+ import { html, LitElement } from "lit";
9
+ import { customElement, property, state } from "lit/decorators.js";
10
+ import { dictationConfigContext, languagesContext, regionContext, } from "../contexts/dictation-context.js";
11
+ import SelectStyles from "../styles/select.js";
12
+ import { languageChangedEvent, languagesChangedEvent, } from "../utils/events.js";
13
+ import { getLanguageName, getLanguagesByRegion } from "../utils/languages.js";
14
+ let LanguageSelector = class LanguageSelector extends LitElement {
15
+ constructor() {
16
+ super(...arguments);
17
+ this.disabled = false;
18
+ /**
19
+ * Internal cache of loaded languages to check if languages were auto-loaded or provided via property
20
+ * @private
21
+ */
22
+ this._loadedLanguages = [];
23
+ }
24
+ _languagesAutoLoaded() {
25
+ return this._loadedLanguages === this._languages;
26
+ }
27
+ async connectedCallback() {
28
+ super.connectedCallback();
29
+ if (this._languages) {
30
+ return;
31
+ }
32
+ await this._loadLanguages();
33
+ }
34
+ updated(changedProperties) {
35
+ if (changedProperties.has("_region") && this._languagesAutoLoaded()) {
36
+ this._loadLanguages();
37
+ }
38
+ }
39
+ async _loadLanguages() {
40
+ const { languages, defaultLanguage } = getLanguagesByRegion(this._region);
41
+ this._loadedLanguages = languages;
42
+ const selectedLanguage = this._dictationConfig?.primaryLanguage ?? defaultLanguage;
43
+ this.dispatchEvent(languagesChangedEvent(languages, selectedLanguage));
44
+ // Dispatch backward compatible event
45
+ if (selectedLanguage) {
46
+ this.dispatchEvent(languageChangedEvent(selectedLanguage));
47
+ }
48
+ }
49
+ _handleSelectLanguage(e) {
50
+ const language = e.target.value;
51
+ this.dispatchEvent(languagesChangedEvent(this._languages || [], language));
52
+ // Dispatch backward compatible event
53
+ this.dispatchEvent(languageChangedEvent(language));
54
+ }
55
+ render() {
56
+ return html `
57
+ <div>
58
+ <label id="language-select-label" for="language-select">
59
+ Dictation Language
60
+ </label>
61
+ <select
62
+ id="language-select"
63
+ aria-labelledby="language-select-label"
64
+ @change=${this._handleSelectLanguage}
65
+ ?disabled=${this.disabled || !this._languages || this._languages.length === 0}
66
+ >
67
+ ${this._languages?.map((language) => html `
68
+ <option
69
+ value=${language}
70
+ ?selected=${this._dictationConfig?.primaryLanguage === language}
71
+ >
72
+ ${getLanguageName(language)}
73
+ </option>
74
+ `)}
75
+ </select>
76
+ </div>
77
+ `;
78
+ }
79
+ };
80
+ LanguageSelector.styles = SelectStyles;
81
+ __decorate([
82
+ consume({ context: languagesContext, subscribe: true }),
83
+ state()
84
+ ], LanguageSelector.prototype, "_languages", void 0);
85
+ __decorate([
86
+ consume({ context: dictationConfigContext, subscribe: true }),
87
+ state()
88
+ ], LanguageSelector.prototype, "_dictationConfig", void 0);
89
+ __decorate([
90
+ property({ type: Boolean })
91
+ ], LanguageSelector.prototype, "disabled", void 0);
92
+ __decorate([
93
+ consume({ context: regionContext, subscribe: true }),
94
+ state()
95
+ ], LanguageSelector.prototype, "_region", void 0);
96
+ LanguageSelector = __decorate([
97
+ customElement("language-selector")
98
+ ], LanguageSelector);
99
+ export { LanguageSelector };
100
+ //# sourceMappingURL=language-selector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language-selector.js","sourceRoot":"","sources":["../../src/components/language-selector.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Corti } from \"@corti/sdk\";\nimport { consume } from \"@lit/context\";\nimport { html, LitElement, type PropertyValues } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport {\n dictationConfigContext,\n languagesContext,\n regionContext,\n} from \"../contexts/dictation-context.js\";\nimport SelectStyles from \"../styles/select.js\";\nimport {\n languageChangedEvent,\n languagesChangedEvent,\n} from \"../utils/events.js\";\nimport { getLanguageName, getLanguagesByRegion } from \"../utils/languages.js\";\n\n@customElement(\"language-selector\")\nexport class LanguageSelector extends LitElement {\n @consume({ context: languagesContext, subscribe: true })\n @state()\n private _languages?: string[];\n\n @consume({ context: dictationConfigContext, subscribe: true })\n @state()\n private _dictationConfig?: Corti.TranscribeConfig;\n\n @property({ type: Boolean })\n disabled: boolean = false;\n\n @consume({ context: regionContext, subscribe: true })\n @state()\n _region?: string;\n\n /**\n * Internal cache of loaded languages to check if languages were auto-loaded or provided via property\n * @private\n */\n private _loadedLanguages: string[] = [];\n\n private _languagesAutoLoaded(): boolean {\n return this._loadedLanguages === this._languages;\n }\n\n static styles = SelectStyles;\n\n async connectedCallback(): Promise<void> {\n super.connectedCallback();\n\n if (this._languages) {\n return;\n }\n\n await this._loadLanguages();\n }\n\n updated(changedProperties: PropertyValues<this>): void {\n if (changedProperties.has(\"_region\") && this._languagesAutoLoaded()) {\n this._loadLanguages();\n }\n }\n\n private async _loadLanguages(): Promise<void> {\n const { languages, defaultLanguage } = getLanguagesByRegion(this._region);\n this._loadedLanguages = languages;\n\n const selectedLanguage =\n this._dictationConfig?.primaryLanguage ?? defaultLanguage;\n\n this.dispatchEvent(languagesChangedEvent(languages, selectedLanguage));\n\n // Dispatch backward compatible event\n if (selectedLanguage) {\n this.dispatchEvent(languageChangedEvent(selectedLanguage));\n }\n }\n\n private _handleSelectLanguage(e: Event): void {\n const language = (e.target as HTMLSelectElement).value;\n\n this.dispatchEvent(languagesChangedEvent(this._languages || [], language));\n\n // Dispatch backward compatible event\n this.dispatchEvent(languageChangedEvent(language));\n }\n\n render() {\n return html`\n <div>\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=${this._handleSelectLanguage}\n ?disabled=${this.disabled || !this._languages || this._languages.length === 0}\n >\n ${this._languages?.map(\n (language) => html`\n <option\n value=${language}\n ?selected=${this._dictationConfig?.primaryLanguage === language}\n >\n ${getLanguageName(language)}\n </option>\n `,\n )}\n </select>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"language-selector\": LanguageSelector;\n }\n}\n"]}
@@ -0,0 +1,37 @@
1
+ import type { Corti } from "@corti/sdk";
2
+ import { type CSSResultGroup, LitElement } from "lit";
3
+ import type { ProxyOptions } from "../types.js";
4
+ import "./audio-visualiser.js";
5
+ import "../icons/icons.js";
6
+ export declare class RecordingButton extends LitElement {
7
+ private _recordingState;
8
+ _selectedDevice?: MediaDeviceInfo;
9
+ _accessToken?: string;
10
+ _authConfig?: Corti.BearerOptions;
11
+ _region?: string;
12
+ _tenantName?: string;
13
+ _dictationConfig?: Corti.TranscribeConfig;
14
+ _socketUrl?: string;
15
+ _socketProxy?: ProxyOptions;
16
+ _debug_displayAudio?: boolean;
17
+ preventFocus: boolean;
18
+ private _mediaController;
19
+ private _dictationController;
20
+ static styles: CSSResultGroup;
21
+ private _handleMouseDown;
22
+ private _handleWebSocketMessage;
23
+ private _handleWebSocketError;
24
+ private _handleWebSocketClose;
25
+ private _handleStart;
26
+ private _handleStop;
27
+ private _handleClick;
28
+ startRecording(): void;
29
+ stopRecording(): void;
30
+ toggleRecording(): void;
31
+ render(): import("lit-html").TemplateResult<1>;
32
+ }
33
+ declare global {
34
+ interface HTMLElementTagNameMap {
35
+ "recording-button": RecordingButton;
36
+ }
37
+ }
@@ -0,0 +1,203 @@
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
+ import { consume } from "@lit/context";
8
+ import { html, LitElement } from "lit";
9
+ import { customElement, property, state } from "lit/decorators.js";
10
+ import { accessTokenContext, authConfigContext, debugDisplayAudioContext, dictationConfigContext, recordingStateContext, regionContext, selectedDeviceContext, socketProxyContext, socketUrlContext, tenantNameContext, } from "../contexts/dictation-context.js";
11
+ import { DictationController, } from "../controllers/DictationController.js";
12
+ import { MediaController } from "../controllers/MediaController.js";
13
+ import ButtonStyles from "../styles/buttons.js";
14
+ import RecordingButtonStyles from "../styles/recording-button.js";
15
+ import { audioLevelChangedEvent, commandEvent, errorEvent, networkActivityEvent, recordingStateChangedEvent, streamClosedEvent, transcriptEvent, usageEvent, } from "../utils/events.js";
16
+ import "./audio-visualiser.js";
17
+ import "../icons/icons.js";
18
+ let RecordingButton = class RecordingButton extends LitElement {
19
+ constructor() {
20
+ super(...arguments);
21
+ this._recordingState = "stopped";
22
+ this.preventFocus = false;
23
+ this._mediaController = new MediaController(this);
24
+ this._dictationController = new DictationController(this);
25
+ this._handleWebSocketMessage = (message) => {
26
+ switch (message.type) {
27
+ case "CONFIG_ACCEPTED":
28
+ this._mediaController.mediaRecorder?.start(250);
29
+ this._mediaController.startAudioLevelMonitoring((level) => {
30
+ this.dispatchEvent(audioLevelChangedEvent(level));
31
+ });
32
+ this.dispatchEvent(recordingStateChangedEvent("recording"));
33
+ break;
34
+ case "CONFIG_DENIED":
35
+ this.dispatchEvent(errorEvent(`Config denied: ${message.reason ?? "Unknown reason"}`));
36
+ this._handleStop();
37
+ break;
38
+ case "CONFIG_TIMEOUT":
39
+ this.dispatchEvent(errorEvent("Config timeout"));
40
+ this._handleStop();
41
+ break;
42
+ case "transcript":
43
+ this.dispatchEvent(transcriptEvent(message));
44
+ break;
45
+ case "command":
46
+ this.dispatchEvent(commandEvent(message));
47
+ break;
48
+ case "usage":
49
+ this.dispatchEvent(usageEvent(message));
50
+ break;
51
+ case "error":
52
+ this.dispatchEvent(errorEvent(message.error));
53
+ this._handleStop();
54
+ break;
55
+ }
56
+ };
57
+ this._handleWebSocketError = (error) => {
58
+ this.dispatchEvent(errorEvent("Socket error: " + error.message));
59
+ this._handleStop();
60
+ };
61
+ this._handleWebSocketClose = (event) => {
62
+ this.dispatchEvent(streamClosedEvent(event));
63
+ };
64
+ }
65
+ _handleMouseDown(event) {
66
+ if (this.preventFocus) {
67
+ event.preventDefault();
68
+ }
69
+ }
70
+ async _handleStart() {
71
+ this.dispatchEvent(recordingStateChangedEvent("initializing"));
72
+ try {
73
+ await this._mediaController.initialize(() => {
74
+ if (this._recordingState === "recording") {
75
+ this.dispatchEvent(errorEvent("Microphone access was lost."));
76
+ this._handleStop();
77
+ }
78
+ });
79
+ await this._dictationController.connect(this._mediaController.mediaRecorder, this._dictationConfig, {
80
+ onClose: this._handleWebSocketClose,
81
+ onError: this._handleWebSocketError,
82
+ onMessage: this._handleWebSocketMessage,
83
+ onNetworkActivity: (direction, data) => {
84
+ this.dispatchEvent(networkActivityEvent(direction, data));
85
+ },
86
+ });
87
+ }
88
+ catch (error) {
89
+ this.dispatchEvent(errorEvent(error));
90
+ await this._handleStop();
91
+ }
92
+ }
93
+ async _handleStop() {
94
+ this.dispatchEvent(recordingStateChangedEvent("stopping"));
95
+ try {
96
+ this._mediaController.stopAudioLevelMonitoring();
97
+ await this._mediaController.stopRecording();
98
+ await this._dictationController.disconnect(this._handleWebSocketClose);
99
+ await this._mediaController.cleanup();
100
+ }
101
+ catch (error) {
102
+ this.dispatchEvent(errorEvent(error));
103
+ }
104
+ this.dispatchEvent(recordingStateChangedEvent("stopped"));
105
+ }
106
+ _handleClick() {
107
+ if (this._recordingState === "stopped") {
108
+ this._handleStart();
109
+ }
110
+ else if (this._recordingState === "recording") {
111
+ this._handleStop();
112
+ }
113
+ }
114
+ startRecording() {
115
+ if (this._recordingState !== "stopped") {
116
+ return;
117
+ }
118
+ this._handleStart();
119
+ }
120
+ stopRecording() {
121
+ if (this._recordingState !== "recording") {
122
+ return;
123
+ }
124
+ this._handleStop();
125
+ }
126
+ toggleRecording() {
127
+ this._handleClick();
128
+ }
129
+ render() {
130
+ const isLoading = this._recordingState === "initializing" ||
131
+ this._recordingState === "stopping";
132
+ const isRecording = this._recordingState === "recording";
133
+ return html `
134
+ <button
135
+ @mousedown=${this._handleMouseDown}
136
+ @click=${this._handleClick}
137
+ ?disabled=${isLoading}
138
+ class=${isRecording ? "red" : "accent"}
139
+ aria-label=${isRecording ? "Stop recording" : "Start recording"}
140
+ aria-pressed=${isRecording}
141
+ >
142
+ ${isLoading
143
+ ? html `<icon-loading-spinner></icon-loading-spinner>`
144
+ : isRecording
145
+ ? html `<icon-recording></icon-recording>`
146
+ : html `<icon-mic-on></icon-mic-on>`}
147
+ <audio-visualiser
148
+ .level=${this._mediaController.audioLevel}
149
+ ?active=${isRecording}
150
+ ></audio-visualiser>
151
+ </button>
152
+ `;
153
+ }
154
+ };
155
+ RecordingButton.styles = [RecordingButtonStyles, ButtonStyles];
156
+ __decorate([
157
+ consume({ context: recordingStateContext, subscribe: true }),
158
+ state()
159
+ ], RecordingButton.prototype, "_recordingState", void 0);
160
+ __decorate([
161
+ consume({ context: selectedDeviceContext, subscribe: true }),
162
+ state()
163
+ ], RecordingButton.prototype, "_selectedDevice", void 0);
164
+ __decorate([
165
+ consume({ context: accessTokenContext, subscribe: true }),
166
+ state()
167
+ ], RecordingButton.prototype, "_accessToken", void 0);
168
+ __decorate([
169
+ consume({ context: authConfigContext, subscribe: true }),
170
+ state()
171
+ ], RecordingButton.prototype, "_authConfig", void 0);
172
+ __decorate([
173
+ consume({ context: regionContext, subscribe: true }),
174
+ state()
175
+ ], RecordingButton.prototype, "_region", void 0);
176
+ __decorate([
177
+ consume({ context: tenantNameContext, subscribe: true }),
178
+ state()
179
+ ], RecordingButton.prototype, "_tenantName", void 0);
180
+ __decorate([
181
+ consume({ context: dictationConfigContext, subscribe: true }),
182
+ state()
183
+ ], RecordingButton.prototype, "_dictationConfig", void 0);
184
+ __decorate([
185
+ consume({ context: socketUrlContext, subscribe: true }),
186
+ state()
187
+ ], RecordingButton.prototype, "_socketUrl", void 0);
188
+ __decorate([
189
+ consume({ context: socketProxyContext, subscribe: true }),
190
+ state()
191
+ ], RecordingButton.prototype, "_socketProxy", void 0);
192
+ __decorate([
193
+ consume({ context: debugDisplayAudioContext, subscribe: true }),
194
+ state()
195
+ ], RecordingButton.prototype, "_debug_displayAudio", void 0);
196
+ __decorate([
197
+ property({ type: Boolean })
198
+ ], RecordingButton.prototype, "preventFocus", void 0);
199
+ RecordingButton = __decorate([
200
+ customElement("recording-button")
201
+ ], RecordingButton);
202
+ export { RecordingButton };
203
+ //# 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 {\n accessTokenContext,\n authConfigContext,\n debugDisplayAudioContext,\n dictationConfigContext,\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/DictationController.js\";\nimport { MediaController } from \"../controllers/MediaController.js\";\nimport ButtonStyles from \"../styles/buttons.js\";\nimport RecordingButtonStyles from \"../styles/recording-button.js\";\nimport type { ProxyOptions, RecordingState } from \"../types.js\";\nimport {\n audioLevelChangedEvent,\n commandEvent,\n errorEvent,\n networkActivityEvent,\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(\"recording-button\")\nexport class RecordingButton extends LitElement {\n @consume({ context: recordingStateContext, subscribe: true })\n @state()\n private _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 @property({ type: Boolean })\n preventFocus: boolean = false;\n\n private _mediaController = new MediaController(this);\n private _dictationController = new DictationController(this);\n\n static styles: CSSResultGroup = [RecordingButtonStyles, ButtonStyles];\n\n private _handleMouseDown(event: MouseEvent): void {\n if (this.preventFocus) {\n event.preventDefault();\n }\n }\n\n private _handleWebSocketMessage = (message: TranscribeMessage): void => {\n switch (message.type) {\n case \"CONFIG_ACCEPTED\":\n this._mediaController.mediaRecorder?.start(250);\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 private _handleWebSocketError = (error: Error): void => {\n this.dispatchEvent(errorEvent(\"Socket error: \" + error.message));\n this._handleStop();\n };\n\n private _handleWebSocketClose = (event: unknown): void => {\n this.dispatchEvent(streamClosedEvent(event));\n };\n\n private 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(\"Microphone access was lost.\"));\n this._handleStop();\n }\n });\n\n 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 } catch (error) {\n this.dispatchEvent(errorEvent(error));\n await this._handleStop();\n }\n }\n\n private 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 private _handleClick(): void {\n if (this._recordingState === \"stopped\") {\n this._handleStart();\n } else if (this._recordingState === \"recording\") {\n this._handleStop();\n }\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 !== \"recording\") {\n return;\n }\n\n this._handleStop();\n }\n\n public toggleRecording(): void {\n this._handleClick();\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 @click=${this._handleClick}\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></icon-loading-spinner>`\n : isRecording\n ? html`<icon-recording></icon-recording>`\n : html`<icon-mic-on></icon-mic-on>`\n }\n <audio-visualiser\n .level=${this._mediaController.audioLevel}\n ?active=${isRecording}\n ></audio-visualiser>\n </button>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"recording-button\": RecordingButton;\n }\n}\n"]}
@@ -1,20 +1,16 @@
1
- import { LitElement, TemplateResult, CSSResultGroup } from 'lit';
1
+ import { type CSSResultGroup, LitElement, nothing } from "lit";
2
+ import type { ConfigurableSettings, RecordingState } from "../types.js";
3
+ import "./device-selector.js";
4
+ import "./language-selector.js";
5
+ import "../icons/icons.js";
2
6
  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;
7
+ _recordingState: RecordingState;
8
+ settingsEnabled: ConfigurableSettings[];
11
9
  static styles: CSSResultGroup;
12
- private _selectDevice;
13
- private _selectLanguage;
14
- render(): TemplateResult;
10
+ render(): import("lit-html").TemplateResult<1> | typeof nothing;
15
11
  }
16
12
  declare global {
17
13
  interface HTMLElementTagNameMap {
18
- 'settings-menu': SettingsMenu;
14
+ "settings-menu": SettingsMenu;
19
15
  }
20
16
  }
@@ -4,65 +4,30 @@ 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';
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 "./language-selector.js";
17
+ import "../icons/icons.js";
15
18
  let SettingsMenu = class SettingsMenu extends LitElement {
16
- get effectiveSelectedLanguage() {
17
- return this.selectedLanguage || LANGUAGES_SUPPORTED[0] || '';
18
- }
19
19
  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
- }));
20
+ super(...arguments);
21
+ this._recordingState = "stopped";
22
+ this.settingsEnabled = ["device", "language"];
64
23
  }
65
24
  render() {
25
+ if (!this.settingsEnabled || this.settingsEnabled.length === 0) {
26
+ return nothing;
27
+ }
28
+ const isRecording = this._recordingState === "recording";
29
+ const showDeviceSelector = this.settingsEnabled.includes("device");
30
+ const showLanguageSelector = this.settingsEnabled.includes("language");
66
31
  return html `
67
32
  <div class="mic-selector">
68
33
  <button id="settings-popover-button" popovertarget="settings-popover">
@@ -70,58 +35,23 @@ let SettingsMenu = class SettingsMenu extends LitElement {
70
35
  </button>
71
36
  <div id="settings-popover" popover>
72
37
  <div class="settings-wrapper">
73
- ${this.settingsDisabled
38
+ ${isRecording
74
39
  ? html `
75
40
  <div class="callout warn">
76
41
  Recording is in progress. Stop recording to change settings.
77
42
  </div>
78
43
  `
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>
44
+ : nothing}
45
+ ${showDeviceSelector
46
+ ? html `<device-selector
47
+ ?disabled=${isRecording}
48
+ ></device-selector>`
49
+ : nothing}
50
+ ${showLanguageSelector
51
+ ? html `<language-selector
52
+ ?disabled=${isRecording}
53
+ ></language-selector>`
54
+ : nothing}
125
55
  </div>
126
56
  </div>
127
57
  </div>
@@ -129,57 +59,22 @@ let SettingsMenu = class SettingsMenu extends LitElement {
129
59
  }
130
60
  };
131
61
  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
- `,
62
+ SettingsMenuStyles,
165
63
  ButtonStyles,
166
- SelectStyles,
167
64
  CalloutStyles,
168
65
  ];
169
66
  __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([
67
+ consume({ context: recordingStateContext, subscribe: true }),
179
68
  state()
180
- ], SettingsMenu.prototype, "_devices", void 0);
69
+ ], SettingsMenu.prototype, "_recordingState", void 0);
70
+ __decorate([
71
+ property({
72
+ converter: commaSeparatedConverter,
73
+ type: Array,
74
+ })
75
+ ], SettingsMenu.prototype, "settingsEnabled", void 0);
181
76
  SettingsMenu = __decorate([
182
- customElement('settings-menu')
77
+ customElement("settings-menu")
183
78
  ], SettingsMenu);
184
79
  export { SettingsMenu };
185
80
  //# sourceMappingURL=settings-menu.js.map