@longline/aqua-ui 1.0.196 → 1.0.198

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 (69) hide show
  1. package/aquaui-sprites.svg +1 -1
  2. package/containers/List/ListRow.d.ts +5 -0
  3. package/containers/List/ListRow.js +3 -3
  4. package/containers/Openable/Openable.d.ts +26 -0
  5. package/containers/Openable/Openable.js +76 -0
  6. package/containers/Openable/index.d.ts +1 -0
  7. package/containers/Openable/index.js +1 -0
  8. package/controls/Fab/Fab.d.ts +7 -1
  9. package/controls/Fab/Fab.js +21 -4
  10. package/controls/SpeechRecognizer/EditorRegistry.d.ts +8 -0
  11. package/controls/SpeechRecognizer/EditorRegistry.js +24 -0
  12. package/controls/SpeechRecognizer/SpeechRecognizer.d.ts +3 -0
  13. package/controls/SpeechRecognizer/SpeechRecognizer.js +118 -0
  14. package/controls/SpeechRecognizer/index.d.ts +1 -0
  15. package/controls/SpeechRecognizer/index.js +1 -0
  16. package/formatters/CountryFormatter/Countries.js +0 -1
  17. package/hooks/useAssemblyAIRecorder/SpeechManager.d.ts +12 -0
  18. package/hooks/useAssemblyAIRecorder/SpeechManager.js +26 -0
  19. package/hooks/useAssemblyAIRecorder/index.d.ts +1 -0
  20. package/hooks/useAssemblyAIRecorder/index.js +1 -0
  21. package/hooks/useAssemblyAIRecorder/stories/AssemblyAudioInput.d.ts +6 -0
  22. package/hooks/useAssemblyAIRecorder/stories/AssemblyAudioInput.js +17 -0
  23. package/hooks/useAssemblyAIRecorder/useAssemblyAIRecorder.d.ts +27 -0
  24. package/hooks/useAssemblyAIRecorder/useAssemblyAIRecorder.js +294 -0
  25. package/hooks/useOpenAIRecorder/index.d.ts +1 -0
  26. package/hooks/useOpenAIRecorder/index.js +1 -0
  27. package/hooks/useOpenAIRecorder/old/AudioInputNoHook.d.ts +8 -0
  28. package/hooks/useOpenAIRecorder/old/AudioInputNoHook.js +192 -0
  29. package/hooks/useOpenAIRecorder/old/AudioInputStandardMedia.d.ts +5 -0
  30. package/hooks/useOpenAIRecorder/old/AudioInputStandardMedia.js +170 -0
  31. package/hooks/useOpenAIRecorder/stories/OpenAIAudioInput.d.ts +8 -0
  32. package/hooks/useOpenAIRecorder/stories/OpenAIAudioInput.js +17 -0
  33. package/hooks/useOpenAIRecorder/useOpenAIRecorder.d.ts +22 -0
  34. package/hooks/useOpenAIRecorder/useOpenAIRecorder.js +223 -0
  35. package/hooks/useOpenAIStream/index.d.ts +1 -0
  36. package/hooks/useOpenAIStream/index.js +1 -0
  37. package/hooks/useOpenAIStream/stories/OpenAIStreamInput.d.ts +23 -0
  38. package/hooks/useOpenAIStream/stories/OpenAIStreamInput.js +66 -0
  39. package/hooks/useOpenAIStream/useOpenAIStream.d.ts +14 -0
  40. package/hooks/useOpenAIStream/useOpenAIStream.js +159 -0
  41. package/inputs/Editor/Editor.d.ts +13 -3
  42. package/inputs/Editor/Editor.js +27 -24
  43. package/inputs/Editor/buttons/CodeBlockButton.js +1 -1
  44. package/inputs/Editor/buttons/OpenAIButton.d.ts +25 -0
  45. package/inputs/Editor/buttons/OpenAIButton.js +208 -0
  46. package/inputs/Editor/buttons/OpenAIMenu.d.ts +9 -0
  47. package/inputs/Editor/buttons/OpenAIMenu.js +42 -0
  48. package/inputs/Editor/buttons/SpeechButton.d.ts +8 -0
  49. package/inputs/Editor/buttons/SpeechButton.js +31 -0
  50. package/inputs/Editor/extensions/MarkElement.d.ts +9 -0
  51. package/inputs/Editor/extensions/MarkElement.js +35 -0
  52. package/inputs/Editor/extensions/StreamNode.d.ts +3 -0
  53. package/inputs/Editor/extensions/StreamNode.js +33 -0
  54. package/inputs/Editor/menu/MenuBar.d.ts +14 -3
  55. package/inputs/Editor/menu/MenuBar.js +14 -15
  56. package/inputs/Editor/menu/MenuButton.d.ts +7 -1
  57. package/inputs/Editor/menu/MenuButton.js +4 -5
  58. package/inputs/Editor/menu/MenuSeparator.js +1 -1
  59. package/package.json +10 -3
  60. package/svg/editor/index.d.ts +1 -1
  61. package/svg/editor/index.js +1 -1
  62. package/svg/icons/index.d.ts +1 -0
  63. package/svg/icons/index.js +1 -0
  64. package/inputs/Editor/AudioVisualizer.d.ts +0 -7
  65. package/inputs/Editor/AudioVisualizer.js +0 -81
  66. package/inputs/Editor/SpeechRecognizer.d.ts +0 -9
  67. package/inputs/Editor/SpeechRecognizer.js +0 -39
  68. package/inputs/Editor/buttons/RecordButton.d.ts +0 -9
  69. package/inputs/Editor/buttons/RecordButton.js +0 -8
@@ -0,0 +1,35 @@
1
+ import { Mark, mergeAttributes } from '@tiptap/core';
2
+ /**
3
+ * Custom TipTap extension. This supports the `<mark>` element.
4
+ */
5
+ var MarkElement = Mark.create({
6
+ name: 'mark',
7
+ addOptions: function () {
8
+ return {
9
+ HTMLAttributes: {},
10
+ };
11
+ },
12
+ parseHTML: function () {
13
+ return [
14
+ {
15
+ tag: 'mark',
16
+ },
17
+ ];
18
+ },
19
+ renderHTML: function (_a) {
20
+ var HTMLAttributes = _a.HTMLAttributes;
21
+ return ['mark', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
22
+ },
23
+ addAttributes: function () {
24
+ return {
25
+ class: {
26
+ default: null,
27
+ },
28
+ style: {
29
+ default: null,
30
+ },
31
+ // Add any other supported attributes here
32
+ };
33
+ },
34
+ });
35
+ export { MarkElement };
@@ -0,0 +1,3 @@
1
+ import { Node } from '@tiptap/core';
2
+ declare const StreamNode: Node<any, any>;
3
+ export { StreamNode };
@@ -0,0 +1,33 @@
1
+ import { Node, mergeAttributes } from '@tiptap/core';
2
+ var StreamNode = Node.create({
3
+ name: 'stream', // <stream>
4
+ group: 'block',
5
+ content: 'inline*',
6
+ atom: false, // allow updating content
7
+ selectable: true,
8
+ addAttributes: function () {
9
+ return {
10
+ streamId: {
11
+ default: null,
12
+ parseHTML: function (element) { return element.getAttribute('data-stream-id'); },
13
+ renderHTML: function (attributes) {
14
+ return attributes.streamId
15
+ ? { 'data-stream-id': attributes.streamId }
16
+ : {};
17
+ },
18
+ },
19
+ };
20
+ },
21
+ parseHTML: function () {
22
+ return [
23
+ {
24
+ tag: 'div[data-stream-id]',
25
+ },
26
+ ];
27
+ },
28
+ renderHTML: function (_a) {
29
+ var HTMLAttributes = _a.HTMLAttributes;
30
+ return ['div', mergeAttributes(HTMLAttributes), 0];
31
+ },
32
+ });
33
+ export { StreamNode };
@@ -11,11 +11,22 @@ interface IProps {
11
11
  allowFullscreen?: boolean;
12
12
  /** Is editor currently fullscreen? This will affect toolbar positioning. */
13
13
  fullscreen?: boolean;
14
+ /**
15
+ * If set, adds code and code block buttons to MenuBar.
16
+ */
17
+ codeButtons?: boolean;
18
+ /**
19
+ * URL for OpenAI requests.
20
+ * If not present, no AI controls will be available.
21
+ */
22
+ openAIurl?: string;
23
+ /**
24
+ * URL for AssemblyAI requests.
25
+ * If not present, no AI controls will be available.
26
+ */
27
+ assemblyAIurl?: string;
14
28
  /** Fired when fullscreen mode must be toggled. */
15
29
  onToggleFullscreen: () => void;
16
- allowSpeechRecognition: boolean;
17
- recording: boolean;
18
- onRecord: () => void;
19
30
  }
20
31
  declare const MenuBar: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<IProps, never>> & string & Omit<(props: IProps) => React.JSX.Element, keyof React.Component<any, {}, any>>;
21
32
  export { MenuBar };
@@ -13,9 +13,8 @@ import { OrderedListButton } from '../buttons/OrderedListButton';
13
13
  import { BulletListButton } from '../buttons/BulletListButton';
14
14
  import { CodeBlockButton } from '../buttons/CodeBlockButton';
15
15
  import { FullscreenButton } from '../buttons/FullscreenButton';
16
- import { RecordButton } from '../buttons/RecordButton';
17
- import { SpeechRecognizer } from '../SpeechRecognizer';
18
- import { AudioVisualizer } from '../AudioVisualizer';
16
+ import { OpenAIButton } from '../buttons/OpenAIButton';
17
+ import { SpeechButton } from '../buttons/SpeechButton';
19
18
  var MenuBarBase = function (props) {
20
19
  if (!props.editor) {
21
20
  return null;
@@ -28,19 +27,19 @@ var MenuBarBase = function (props) {
28
27
  React.createElement(MenuSeparator, null),
29
28
  React.createElement(OrderedListButton, { editor: props.editor }),
30
29
  React.createElement(BulletListButton, { editor: props.editor }),
31
- React.createElement(MenuSeparator, null),
32
- React.createElement(CodeButton, { editor: props.editor }),
33
- React.createElement(CodeBlockButton, { editor: props.editor }),
34
- props.allowFullscreen && React.createElement(React.Fragment, null,
35
- React.createElement(MenuSeparator, null),
36
- React.createElement(FullscreenButton, { fullscreen: props.fullscreen, editor: props.editor, onClick: props.onToggleFullscreen })),
37
- props.allowSpeechRecognition && SpeechRecognizer.isAvailable() && React.createElement(React.Fragment, null,
30
+ props.codeButtons && React.createElement(React.Fragment, null,
38
31
  React.createElement(MenuSeparator, null),
39
- React.createElement(RecordButton, { editor: props.editor, recording: props.recording, onRecord: props.onRecord })),
40
- props.recording && React.createElement("div", null,
41
- React.createElement(AudioVisualizer, null)))));
32
+ React.createElement(CodeButton, { editor: props.editor }),
33
+ React.createElement(CodeBlockButton, { editor: props.editor })),
34
+ (props.openAIurl || props.allowFullscreen) && React.createElement(MenuSeparator, null),
35
+ props.openAIurl &&
36
+ React.createElement(OpenAIButton, { url: props.openAIurl, editor: props.editor }),
37
+ props.assemblyAIurl &&
38
+ React.createElement(SpeechButton, { url: props.assemblyAIurl, editor: props.editor }),
39
+ props.allowFullscreen &&
40
+ React.createElement(FullscreenButton, { fullscreen: props.fullscreen, editor: props.editor, onClick: props.onToggleFullscreen }))));
42
41
  };
43
- var MenuBar = styled(MenuBarBase)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n // Keep MenuBar at top of editor; it must not scroll when the editor\n // content scrolls.\n position: absolute;\n left: ", "px;\n top: ", "px;\n z-index: 1;\n"], ["\n // Keep MenuBar at top of editor; it must not scroll when the editor\n // content scrolls.\n position: absolute;\n left: ", "px;\n top: ", "px;\n z-index: 1;\n"])), function (p) { return p.fullscreen ? 32 : 0; }, function (p) { return p.fullscreen ? 32 : 0; });
44
- var Buttons = styled.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n border-radius: 4px;\n padding: 2px;\n\n // Flex-align buttons and separators:\n display: flex;\n flex-direction: row;\n gap: 4px;\n"], ["\n border-radius: 4px;\n padding: 2px;\n\n // Flex-align buttons and separators:\n display: flex;\n flex-direction: row;\n gap: 4px;\n"])));
42
+ var MenuBar = styled(MenuBarBase)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n // Keep MenuBar at top of editor; it must not scroll when the editor\n // content scrolls.\n position: sticky;\n left: ", "px;\n top: ", "px;\n z-index: 1;\n background-color: ", ";\n border-bottom: solid 1px ", ";\n"], ["\n // Keep MenuBar at top of editor; it must not scroll when the editor\n // content scrolls.\n position: sticky;\n left: ", "px;\n top: ", "px;\n z-index: 1;\n background-color: ", ";\n border-bottom: solid 1px ", ";\n"])), function (p) { return p.fullscreen ? 32 : 0; }, function (p) { return p.fullscreen ? 32 : 0; }, function (p) { return p.theme.colors.neutral[100]; }, function (p) { return p.theme.colors.neutral[80]; });
43
+ var Buttons = styled.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n border-radius: 4px;\n padding: 2px;\n\n // Flex-align buttons and separators:\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n gap: 4px;\n"], ["\n border-radius: 4px;\n padding: 2px;\n\n // Flex-align buttons and separators:\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n gap: 4px;\n"])));
45
44
  export { MenuBar };
46
45
  var templateObject_1, templateObject_2;
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { Editor } from '@tiptap/react';
3
+ import { IIconProps } from '../../../controls/Icon';
3
4
  interface IProps {
4
5
  /** @ignore */
5
6
  className?: string;
@@ -10,7 +11,7 @@ interface IProps {
10
11
  /**
11
12
  * URL of icon to show.
12
13
  */
13
- icon: string;
14
+ icon: string | IIconProps;
14
15
  /**
15
16
  * If set, button is disabled.
16
17
  * @default false
@@ -21,6 +22,11 @@ interface IProps {
21
22
  * @default false
22
23
  */
23
24
  active?: boolean;
25
+ /**
26
+ * If set, button is highlighted.
27
+ * @default false
28
+ */
29
+ highlighted?: boolean;
24
30
  /**
25
31
  * Optional hint. Can be JSX.
26
32
  */
@@ -14,13 +14,12 @@ var __assign = (this && this.__assign) || function () {
14
14
  return __assign.apply(this, arguments);
15
15
  };
16
16
  import * as React from 'react';
17
- import styled, { css, useTheme } from 'styled-components';
17
+ import styled, { css } from 'styled-components';
18
18
  import { usePopper } from 'react-popper';
19
19
  import { createPortal } from 'react-dom';
20
20
  import { Icon } from '../../../controls/Icon';
21
21
  import { MenuButtonHint } from './MenuButtonHint';
22
22
  var MenuButtonBase = function (props) {
23
- var theme = useTheme();
24
23
  var buttonRef = React.useRef(null);
25
24
  var hintRef = React.useRef(null);
26
25
  var handleMouseEnter = function () {
@@ -48,10 +47,10 @@ var MenuButtonBase = function (props) {
48
47
  ]
49
48
  }), styles = _a.styles, attributes = _a.attributes, update = _a.update;
50
49
  return (React.createElement("button", { className: props.className, disabled: props.disabled, onClick: props.onClick, ref: buttonRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave },
51
- React.createElement(Icon, { url: props.icon }),
50
+ React.createElement(Icon, __assign({}, (typeof props.icon === 'string' ? { url: props.icon } : props.icon))),
52
51
  buttonRef.current && createPortal(React.createElement(MenuButtonHint, { keys: props.keys, ref: hintRef, styles: styles, attributes: attributes }, props.hint), buttonRef.current)));
53
52
  };
54
- var MenuButtonStyled = styled(MenuButtonBase)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n // Size:\n position: relative;\n width: 26px;\n height: 26px;\n\n // Appearance:\n border: none;\n background-color: transparent;\n border-radius: 4px;\n cursor: pointer;\n outline: none;\n user-select: none;\n ", "\n &:active {\n background-color: ", ";\n }\n &:focus {\n outline: solid 2px ", ";\n }\n\n svg {\n fill: ", ";\n }\n ", "\n\n // Content:\n display: flex;\n justify-content: center;\n align-items: center;\n"], ["\n // Size:\n position: relative;\n width: 26px;\n height: 26px;\n\n // Appearance:\n border: none;\n background-color: transparent;\n border-radius: 4px;\n cursor: pointer;\n outline: none;\n user-select: none;\n ", "\n &:active {\n background-color: ", ";\n }\n &:focus {\n outline: solid 2px ", ";\n }\n\n svg {\n fill: ", ";\n }\n ", "\n\n // Content:\n display: flex;\n justify-content: center;\n align-items: center;\n"])), function (p) { return p.active && css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n background-color: ", ";\n "], ["\n background-color: ", ";\n "])), function (p) { return p.theme.colors.neutral[80]; }); }, function (p) { return p.theme.colors.neutral[80]; }, function (p) { return p.theme.colors.primary[1]; }, function (p) { return p.disabled ? p.theme.colors.neutral[80] : p.theme.colors.neutral[50]; }, function (p) { return !p.disabled && css(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n svg:hover {\n fill: ", ";\n }\n "], ["\n svg:hover {\n fill: ", ";\n }\n "])), p.theme.colors.neutral[30]); });
53
+ var MenuButtonStyled = styled(MenuButtonBase)(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n // Size:\n position: relative;\n width: 26px;\n height: 26px;\n\n // Appearance:\n border: none;\n background-color: transparent;\n border-radius: 4px;\n cursor: pointer;\n outline: none;\n user-select: none;\n ", "\n &:active {\n background-color: ", ";\n }\n ", "\n &:focus {\n outline: solid 2px ", ";\n }\n\n svg {\n fill: ", ";\n }\n ", "\n ", "\n\n // Content:\n display: flex;\n justify-content: center;\n align-items: center;\n"], ["\n // Size:\n position: relative;\n width: 26px;\n height: 26px;\n\n // Appearance:\n border: none;\n background-color: transparent;\n border-radius: 4px;\n cursor: pointer;\n outline: none;\n user-select: none;\n ", "\n &:active {\n background-color: ", ";\n }\n ", "\n &:focus {\n outline: solid 2px ", ";\n }\n\n svg {\n fill: ", ";\n }\n ", "\n ", "\n\n // Content:\n display: flex;\n justify-content: center;\n align-items: center;\n"])), function (p) { return p.active && css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n background-color: ", ";\n "], ["\n background-color: ", ";\n "])), function (p) { return p.theme.colors.neutral[80]; }); }, function (p) { return p.theme.colors.neutral[80]; }, function (p) { return p.highlighted && css(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n background-color: ", ";\n "], ["\n background-color: ", ";\n "])), function (p) { return p.theme.colors.primary[1]; }); }, function (p) { return p.theme.colors.primary[1]; }, function (p) { return p.disabled ? p.theme.colors.neutral[80] : p.theme.colors.neutral[50]; }, function (p) { return !p.disabled && css(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n svg:hover {\n fill: ", ";\n }\n "], ["\n svg:hover {\n fill: ", ";\n }\n "])), p.theme.colors.neutral[30]); }, function (p) { return p.highlighted && css(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n svg { fill: ", "; }\n svg:hover { fill: ", "; }\n "], ["\n svg { fill: ", "; }\n svg:hover { fill: ", "; }\n "])), p.theme.colors.neutral[100], p.theme.colors.neutral[100]); });
55
54
  var MenuButton = function (props) { return React.createElement(MenuButtonStyled, __assign({}, props)); };
56
55
  export { MenuButton };
57
- var templateObject_1, templateObject_2, templateObject_3;
56
+ var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5;
@@ -18,7 +18,7 @@ import styled from 'styled-components';
18
18
  var MenuSeparatorBase = function (props) {
19
19
  return React.createElement("div", { className: props.className });
20
20
  };
21
- var MenuSeparatorStyled = styled(MenuSeparatorBase)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n position: relative;\n width: 1px;\n margin-left: 2px;\n margin-right: 2px; \n &:before {\n content: '';\n position: absolute;\n top: 2px;\n left: 0;\n bottom: 2px;\n border-left: solid 1px ", ";\n }\n"], ["\n position: relative;\n width: 1px;\n margin-left: 2px;\n margin-right: 2px; \n &:before {\n content: '';\n position: absolute;\n top: 2px;\n left: 0;\n bottom: 2px;\n border-left: solid 1px ", ";\n }\n"])), function (p) { return p.theme.colors.neutral[80]; });
21
+ var MenuSeparatorStyled = styled(MenuSeparatorBase)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n position: relative;\n width: 1px;\n margin-left: 2px;\n margin-right: 2px; \n &:before {\n content: '';\n position: absolute;\n top: 4px;\n left: 0;\n bottom: 4px;\n border-left: solid 1px ", ";\n }\n"], ["\n position: relative;\n width: 1px;\n margin-left: 2px;\n margin-right: 2px; \n &:before {\n content: '';\n position: absolute;\n top: 4px;\n left: 0;\n bottom: 4px;\n border-left: solid 1px ", ";\n }\n"])), function (p) { return p.theme.colors.neutral[80]; });
22
22
  var MenuSeparator = function (props) { return React.createElement(MenuSeparatorStyled, __assign({}, props)); };
23
23
  export { MenuSeparator };
24
24
  var templateObject_1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@longline/aqua-ui",
3
- "version": "1.0.196",
3
+ "version": "1.0.198",
4
4
  "description": "AquaUI",
5
5
  "author": "Alexander van Oostenrijk / Longline Environment",
6
6
  "license": "Commercial",
@@ -17,8 +17,9 @@
17
17
  },
18
18
  "scripts": {
19
19
  "build": "webpack --config webpack.config.js && tsc --version && tsc",
20
- "storybook": "storybook dev -p 6006",
21
- "build-storybook": "storybook build",
20
+ "storybook": "cross-env OPENAI_RESPONSE_URL=http://api.flow/api/ai/openai/response-stream OPENAI_AUDIO_URL=http://api.flow/api/ai/openai/audio OPENAI_TRANSCRIBE_URL=http://api.flow/api/ai/openai/transcribe ASSEMBLYAI_TOKEN_URL=http://api.flow/api/ai/assemblyai/get-token storybook dev -p 6006",
21
+ "build-storybook": "cross-env OPENAI_RESPONSE_URL=http://api.flow/api/ai/openai/response-stream OPENAI_AUDIO_URL=http://api.flow/api/ai/openai/audio OPENAI_TRANSCRIBE_URL=http://api.flow/api/ai/openai/transcribe ASSEMBLYAI_TOKEN_URL=http://api.flow/api/ai/assemblyai/get-token storybook build",
22
+ "build-storybook-gitlab": "cross-env OPENAI_RESPONSE_URL=https://aquarisk.dev.longline.uk/api/ai/openai/response-stream OPENAI_AUDIO_URL=https://aquarisk.dev.longline.uk/api/ai/openai/audio OPENAI_TRANSCRIBE_URL=https://aquarisk.dev.longline.uk/api/ai/openai/transcribe ASSEMBLYAI_TOKEN_URL=https://aquarisk.dev.longline.uk/api/ai/assemblyai/get-token storybook build",
22
23
  "tsc": "tsc",
23
24
  "pub": "npm version patch && webpack --config webpack.config.js && tsc && cd dist && npm publish"
24
25
  },
@@ -28,7 +29,9 @@
28
29
  "@storybook/addon-links": "^9.0.0",
29
30
  "@storybook/addon-webpack5-compiler-swc": "^3.0.0",
30
31
  "@storybook/react-webpack5": "^9.0.0",
32
+ "@types/dom-speech-recognition": "^0.0.6",
31
33
  "copy-webpack-plugin": "^12.0.2",
34
+ "cross-env": "^7.0.3",
32
35
  "pngjs": "^7.0.0",
33
36
  "storybook": "^9.0.0",
34
37
  "svg-spritemap-webpack-plugin": "^4.5.1",
@@ -50,8 +53,12 @@
50
53
  "@types/react-dom": "^18.3.0",
51
54
  "awesome-debounce-promise": "^2.1.0",
52
55
  "country-flag-emoji-polyfill": "^0.1.8",
56
+ "extendable-media-recorder": "^9.2.26",
57
+ "extendable-media-recorder-wav-encoder": "^7.0.128",
53
58
  "gl-matrix": "^3.4.3",
54
59
  "mapbox-gl": "^3.9.4",
60
+ "marked": "^15.0.12",
61
+ "openai": "^5.0.1",
55
62
  "overlayscrollbars-react": "^0.5.6",
56
63
  "react": "^18.3.1",
57
64
  "react-dom": "^18.3.1",
@@ -1,11 +1,11 @@
1
1
  export declare enum Editor {
2
+ AI = "/aquaui-sprites.svg#editor-ai",
2
3
  Bold = "/aquaui-sprites.svg#editor-bold",
3
4
  BulletList = "/aquaui-sprites.svg#editor-bullet-list",
4
5
  Code = "/aquaui-sprites.svg#editor-code",
5
6
  CodeBlock = "/aquaui-sprites.svg#editor-code-block",
6
7
  Italic = "/aquaui-sprites.svg#editor-italic",
7
8
  Link = "/aquaui-sprites.svg#editor-link",
8
- Microphone = "/aquaui-sprites.svg#editor-microphone",
9
9
  OrderedList = "/aquaui-sprites.svg#editor-ordered-list",
10
10
  Strikethrough = "/aquaui-sprites.svg#editor-strikethrough"
11
11
  }
@@ -1,12 +1,12 @@
1
1
  export var Editor;
2
2
  (function (Editor) {
3
+ Editor["AI"] = "/aquaui-sprites.svg#editor-ai";
3
4
  Editor["Bold"] = "/aquaui-sprites.svg#editor-bold";
4
5
  Editor["BulletList"] = "/aquaui-sprites.svg#editor-bullet-list";
5
6
  Editor["Code"] = "/aquaui-sprites.svg#editor-code";
6
7
  Editor["CodeBlock"] = "/aquaui-sprites.svg#editor-code-block";
7
8
  Editor["Italic"] = "/aquaui-sprites.svg#editor-italic";
8
9
  Editor["Link"] = "/aquaui-sprites.svg#editor-link";
9
- Editor["Microphone"] = "/aquaui-sprites.svg#editor-microphone";
10
10
  Editor["OrderedList"] = "/aquaui-sprites.svg#editor-ordered-list";
11
11
  Editor["Strikethrough"] = "/aquaui-sprites.svg#editor-strikethrough";
12
12
  })(Editor || (Editor = {}));
@@ -31,6 +31,7 @@ export declare enum Icons {
31
31
  Leaf = "/aquaui-sprites.svg#icon-leaf",
32
32
  List = "/aquaui-sprites.svg#icon-list",
33
33
  Locked = "/aquaui-sprites.svg#icon-locked",
34
+ Microphone = "/aquaui-sprites.svg#icon-microphone",
34
35
  Minus = "/aquaui-sprites.svg#icon-minus",
35
36
  Plus = "/aquaui-sprites.svg#icon-plus",
36
37
  Reset = "/aquaui-sprites.svg#icon-reset",
@@ -32,6 +32,7 @@ export var Icons;
32
32
  Icons["Leaf"] = "/aquaui-sprites.svg#icon-leaf";
33
33
  Icons["List"] = "/aquaui-sprites.svg#icon-list";
34
34
  Icons["Locked"] = "/aquaui-sprites.svg#icon-locked";
35
+ Icons["Microphone"] = "/aquaui-sprites.svg#icon-microphone";
35
36
  Icons["Minus"] = "/aquaui-sprites.svg#icon-minus";
36
37
  Icons["Plus"] = "/aquaui-sprites.svg#icon-plus";
37
38
  Icons["Reset"] = "/aquaui-sprites.svg#icon-reset";
@@ -1,7 +0,0 @@
1
- import * as React from 'react';
2
- interface IProps {
3
- /** @ignore */
4
- className?: string;
5
- }
6
- declare const AudioVisualizer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<IProps, never>> & string & Omit<(props: IProps) => React.JSX.Element, keyof React.Component<any, {}, any>>;
7
- export { AudioVisualizer };
@@ -1,81 +0,0 @@
1
- var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
2
- if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
3
- return cooked;
4
- };
5
- import * as React from 'react';
6
- import styled from 'styled-components';
7
- var BUFFERLENGTH = 2048;
8
- var AudioVisualizerBase = function (props) {
9
- var streamRef = React.useRef(null);
10
- var mediaRecorderRef = React.useRef(null);
11
- var audioContextRef = React.useRef(null);
12
- var sourceRef = React.useRef(null);
13
- var analyserRef = React.useRef(null);
14
- var dataRef = React.useRef(null);
15
- var canvasRef = React.useRef(null);
16
- var canvasCtxRef = React.useRef(null);
17
- var frameRef = React.useRef(null);
18
- React.useEffect(function () {
19
- // On startup, create a MediaRecorder.
20
- navigator.mediaDevices.getUserMedia({ audio: true })
21
- .then(function (_stream) {
22
- streamRef.current = _stream;
23
- mediaRecorderRef.current = new MediaRecorder(_stream);
24
- // Get an audiocontext and associated source and analyzer.
25
- audioContextRef.current = new AudioContext();
26
- sourceRef.current = audioContextRef.current.createMediaStreamSource(_stream);
27
- analyserRef.current = audioContextRef.current.createAnalyser();
28
- analyserRef.current.fftSize = BUFFERLENGTH;
29
- dataRef.current = new Uint8Array(BUFFERLENGTH);
30
- sourceRef.current.connect(analyserRef.current);
31
- draw();
32
- })
33
- .catch(function (err) { return console.error("Media", err); });
34
- return function () {
35
- // Don't draw next frame.
36
- if (frameRef.current)
37
- cancelAnimationFrame(frameRef.current);
38
- if (streamRef.current) {
39
- if (sourceRef.current)
40
- sourceRef.current.disconnect();
41
- analyserRef.current = null;
42
- sourceRef.current = null;
43
- audioContextRef.current = null;
44
- mediaRecorderRef.current.stop();
45
- }
46
- };
47
- }, []);
48
- var draw = function () {
49
- var WIDTH = canvasRef.current.width;
50
- var HEIGHT = canvasRef.current.height;
51
- frameRef.current = requestAnimationFrame(draw);
52
- analyserRef.current.getByteTimeDomainData(dataRef.current);
53
- if (!canvasCtxRef.current)
54
- canvasCtxRef.current = canvasRef.current.getContext("2d");
55
- canvasCtxRef.current.fillStyle = "#f0f0f0";
56
- canvasCtxRef.current.fillRect(0, 0, WIDTH, HEIGHT);
57
- canvasCtxRef.current.lineWidth = 2;
58
- canvasCtxRef.current.strokeStyle = "rgb(0, 0, 0)";
59
- canvasCtxRef.current.beginPath();
60
- var sliceWidth = (WIDTH * 1.0) / BUFFERLENGTH;
61
- var x = 0;
62
- for (var i = 0; i < BUFFERLENGTH; i++) {
63
- var v = dataRef.current[i] / 128.0;
64
- var y = (v * HEIGHT) / 2;
65
- if (i === 0) {
66
- canvasCtxRef.current.moveTo(x, y);
67
- }
68
- else {
69
- canvasCtxRef.current.lineTo(x, y);
70
- }
71
- x += sliceWidth;
72
- }
73
- canvasCtxRef.current.lineTo(canvasRef.current.width, canvasRef.current.height / 2);
74
- canvasCtxRef.current.stroke();
75
- };
76
- return (React.createElement("div", { className: props.className },
77
- React.createElement("canvas", { ref: canvasRef })));
78
- };
79
- var AudioVisualizer = styled(AudioVisualizerBase)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n position: relative;\n width: 100px;\n height: 26px;\n border: none;\n box-sizing: border-box;\n background-color: #f0f0f0;\n border-radius: 4px;\n overflow: hidden;\n canvas {\n width: 100%;\n height: 100%;\n }\n"], ["\n position: relative;\n width: 100px;\n height: 26px;\n border: none;\n box-sizing: border-box;\n background-color: #f0f0f0;\n border-radius: 4px;\n overflow: hidden;\n canvas {\n width: 100%;\n height: 100%;\n }\n"])));
80
- export { AudioVisualizer };
81
- var templateObject_1;
@@ -1,9 +0,0 @@
1
- import * as React from 'react';
2
- interface IProps {
3
- onTranscript: (transcript: string) => void;
4
- }
5
- declare const SpeechRecognizer: {
6
- (props: IProps): React.ReactNode;
7
- isAvailable(): boolean;
8
- };
9
- export { SpeechRecognizer };
@@ -1,39 +0,0 @@
1
- import * as React from 'react';
2
- var SpeechRecognition = window['SpeechRecognition'] || window['webkitSpeechRecognition'];
3
- var SpeechRecognitionEvent = window['SpeechRecognitionEvent'] || window['webkitSpeechRecognitionEvent'];
4
- var SpeechRecognizer = function (props) {
5
- // Cancel if getUserMedia not supported.
6
- if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia)
7
- return null;
8
- // Cancel if SpeechRecognition not supported.
9
- if (!SpeechRecognition)
10
- return null;
11
- var recognitionRef = React.useRef(null);
12
- React.useEffect(function () {
13
- // Create a SpeechRecognition.
14
- recognitionRef.current = new SpeechRecognition();
15
- recognitionRef.current.continuous = true;
16
- recognitionRef.current.lang = "en-US";
17
- recognitionRef.current.onresult = handleResult;
18
- recognitionRef.current.start();
19
- return function () {
20
- if (recognitionRef.current) {
21
- recognitionRef.current.stop();
22
- delete recognitionRef.current;
23
- }
24
- };
25
- }, []);
26
- var handleResult = function (ev) {
27
- var transcript = ev.results[ev.results.length - 1][0].transcript;
28
- console.log("Transcript", transcript);
29
- props.onTranscript(transcript);
30
- };
31
- return null;
32
- };
33
- SpeechRecognizer.isAvailable = function () {
34
- // Cancel if SpeechRecognition not supported.
35
- if (!SpeechRecognition)
36
- return false;
37
- return true;
38
- };
39
- export { SpeechRecognizer };
@@ -1,9 +0,0 @@
1
- import * as React from 'react';
2
- import { Editor } from '@tiptap/react';
3
- interface IProps {
4
- editor: Editor;
5
- recording: boolean;
6
- onRecord: () => void;
7
- }
8
- declare const RecordButton: (props: IProps) => React.JSX.Element;
9
- export { RecordButton };
@@ -1,8 +0,0 @@
1
- import * as React from 'react';
2
- import { MenuButton } from '../menu/MenuButton';
3
- import { SVG } from '../../../svg';
4
- var RecordButton = function (props) {
5
- return (React.createElement(React.Fragment, null,
6
- React.createElement(MenuButton, { editor: props.editor, hint: "Record audio", onClick: function (e) { e.stopPropagation(); props.onRecord(); }, active: props.recording, icon: SVG.Editor.Microphone })));
7
- };
8
- export { RecordButton };