@automattic/jetpack-ai-client 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/package.json +2 -2
- package/src/components/audio-duration-display/index.tsx +37 -0
- package/src/components/audio-duration-display/lib/media.ts +73 -0
- package/src/components/index.ts +1 -0
- package/src/hooks/use-ai-suggestions/Readme.md +1 -0
- package/src/hooks/use-ai-suggestions/index.ts +18 -1
- package/src/hooks/use-media-recording/Readme.md +7 -5
- package/src/hooks/use-media-recording/index.ts +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.1.7] - 2023-09-11
|
|
9
|
+
### Added
|
|
10
|
+
- AI Client: add and expose reset() from useAiSuggestions() hook [#32886]
|
|
11
|
+
- AI Client: introduce audio duration display component [#32825]
|
|
12
|
+
|
|
8
13
|
## [0.1.6] - 2023-09-04
|
|
9
14
|
### Added
|
|
10
15
|
- AI Client: add play and pause icons [#32788]
|
|
@@ -110,6 +115,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
110
115
|
- Updated package dependencies. [#31659]
|
|
111
116
|
- Updated package dependencies. [#31785]
|
|
112
117
|
|
|
118
|
+
[0.1.7]: https://github.com/Automattic/jetpack-ai-client/compare/v0.1.6...v0.1.7
|
|
113
119
|
[0.1.6]: https://github.com/Automattic/jetpack-ai-client/compare/v0.1.5...v0.1.6
|
|
114
120
|
[0.1.5]: https://github.com/Automattic/jetpack-ai-client/compare/v0.1.4...v0.1.5
|
|
115
121
|
[0.1.4]: https://github.com/Automattic/jetpack-ai-client/compare/v0.1.3...v0.1.4
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"private": false,
|
|
3
3
|
"name": "@automattic/jetpack-ai-client",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.7",
|
|
5
5
|
"description": "A JS client for consuming Jetpack AI services",
|
|
6
6
|
"homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/ai-client/#readme",
|
|
7
7
|
"bugs": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
".": "./index.ts"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@automattic/jetpack-base-styles": "^0.6.
|
|
35
|
+
"@automattic/jetpack-base-styles": "^0.6.9",
|
|
36
36
|
"@automattic/jetpack-connection": "^0.29.9",
|
|
37
37
|
"@automattic/jetpack-shared-extension-utils": "^0.11.4",
|
|
38
38
|
"@microsoft/fetch-event-source": "2.0.1",
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useState, useEffect } from '@wordpress/element';
|
|
5
|
+
/*
|
|
6
|
+
* Internal dependencies
|
|
7
|
+
*/
|
|
8
|
+
import { formatTime, getDuration } from './lib/media';
|
|
9
|
+
/*
|
|
10
|
+
* Types
|
|
11
|
+
*/
|
|
12
|
+
import type React from 'react';
|
|
13
|
+
|
|
14
|
+
type AudioDurationDisplayProps = {
|
|
15
|
+
url: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* AudioDurationDisplay component.
|
|
20
|
+
*
|
|
21
|
+
* @param {AudioDurationDisplayProps} props - Component props.
|
|
22
|
+
* @returns {React.ReactElement} Rendered component.
|
|
23
|
+
*/
|
|
24
|
+
export default function AudioDurationDisplay( {
|
|
25
|
+
url,
|
|
26
|
+
}: AudioDurationDisplayProps ): React.ReactElement {
|
|
27
|
+
const [ duration, setDuration ] = useState( 0 );
|
|
28
|
+
useEffect( () => {
|
|
29
|
+
if ( ! url ) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
getDuration( url ).then( setDuration );
|
|
34
|
+
}, [ url ] );
|
|
35
|
+
|
|
36
|
+
return <span>{ formatTime( duration, { addDecimalPart: false } ) }</span>;
|
|
37
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Function to get duration of audio file
|
|
3
|
+
*
|
|
4
|
+
* @param {string} url - The url of the audio file
|
|
5
|
+
* @returns {Promise<number>} The duration of the audio file
|
|
6
|
+
* @see https://stackoverflow.com/questions/21522036/html-audio-tag-duration-always-infinity
|
|
7
|
+
*/
|
|
8
|
+
export function getDuration( url: string ): Promise< number > {
|
|
9
|
+
return new Promise( next => {
|
|
10
|
+
const tmpAudioInstance = new Audio( url );
|
|
11
|
+
tmpAudioInstance.addEventListener(
|
|
12
|
+
'durationchange',
|
|
13
|
+
function () {
|
|
14
|
+
if ( this.duration === Infinity ) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const duration = this.duration;
|
|
19
|
+
tmpAudioInstance.remove(); // remove instance from memory
|
|
20
|
+
next( duration );
|
|
21
|
+
},
|
|
22
|
+
false
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
tmpAudioInstance.load();
|
|
26
|
+
tmpAudioInstance.currentTime = 24 * 60 * 60; // Fake big time
|
|
27
|
+
tmpAudioInstance.volume = 0;
|
|
28
|
+
tmpAudioInstance.play(); // This will call `durationchange` event
|
|
29
|
+
} );
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type FormatTimeOptions = {
|
|
33
|
+
/**
|
|
34
|
+
* Whether to add the decimal part to the formatted time.
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
addDecimalPart?: boolean;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Formats the given time in milliseconds into a string with the format HH:MM:SS.DD,
|
|
42
|
+
* adding hours and minutes only when needed.
|
|
43
|
+
*
|
|
44
|
+
* @param {number} time - The time in seconds to format.
|
|
45
|
+
* @param {FormatTimeOptions} options - The arguments.
|
|
46
|
+
* @returns {string} The formatted time string.
|
|
47
|
+
* @example
|
|
48
|
+
* const formattedTime1 = formatTime( 1234567 ); // Returns "20:34.56"
|
|
49
|
+
* const formattedTime2 = formatTime( 45123 ); // Returns "45.12"
|
|
50
|
+
* const formattedTime3 = formatTime( 64, { addDecimalPart: false } ); // Returns "01:04"
|
|
51
|
+
*/
|
|
52
|
+
export function formatTime(
|
|
53
|
+
time: number,
|
|
54
|
+
{ addDecimalPart = true }: FormatTimeOptions = {}
|
|
55
|
+
): string {
|
|
56
|
+
time = time * 1000;
|
|
57
|
+
const hours = Math.floor( time / 3600000 );
|
|
58
|
+
const minutes = Math.floor( time / 60000 ) % 60;
|
|
59
|
+
const seconds = Math.floor( time / 1000 ) % 60;
|
|
60
|
+
const deciseconds = Math.floor( time / 10 ) % 100;
|
|
61
|
+
|
|
62
|
+
const parts = [
|
|
63
|
+
hours > 0 ? hours.toString().padStart( 2, '0' ) + ':' : '',
|
|
64
|
+
hours > 0 || minutes > 0 ? minutes.toString().padStart( 2, '0' ) + ':' : '',
|
|
65
|
+
seconds.toString().padStart( 2, '0' ),
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
if ( addDecimalPart ) {
|
|
69
|
+
parts.push( '.' + deciseconds.toString().padStart( 2, '0' ) );
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return parts.join( '' );
|
|
73
|
+
}
|
package/src/components/index.ts
CHANGED
|
@@ -36,6 +36,7 @@ An object with the following properties:
|
|
|
36
36
|
- `requestingState: RequestingStateProp`: The state of the request.
|
|
37
37
|
- `eventSource: SuggestionsEventSource | undefined`: The event source of the request.
|
|
38
38
|
- `request: ( prompt: Array< PromptItemProps >, options: AskQuestionOptionsArgProps ) => Promise< void >`: The request handler.
|
|
39
|
+
- `reset`: `() => void`: Reset the request state.
|
|
39
40
|
|
|
40
41
|
### `PromptItemProps`
|
|
41
42
|
|
|
@@ -98,6 +98,11 @@ type useAiSuggestionsProps = {
|
|
|
98
98
|
*/
|
|
99
99
|
request: ( prompt: PromptProp, options?: AskQuestionOptionsArgProps ) => Promise< void >;
|
|
100
100
|
|
|
101
|
+
/*
|
|
102
|
+
* Reset the request state.
|
|
103
|
+
*/
|
|
104
|
+
reset: () => void;
|
|
105
|
+
|
|
101
106
|
/*
|
|
102
107
|
* The handler to stop a suggestion.
|
|
103
108
|
*/
|
|
@@ -294,6 +299,17 @@ export default function useAiSuggestions( {
|
|
|
294
299
|
]
|
|
295
300
|
);
|
|
296
301
|
|
|
302
|
+
/**
|
|
303
|
+
* Reset the request state.
|
|
304
|
+
*
|
|
305
|
+
* @returns {void}
|
|
306
|
+
*/
|
|
307
|
+
const reset = useCallback( () => {
|
|
308
|
+
setRequestingState( 'init' );
|
|
309
|
+
setSuggestion( '' );
|
|
310
|
+
setError( undefined );
|
|
311
|
+
}, [] );
|
|
312
|
+
|
|
297
313
|
/**
|
|
298
314
|
* Stop suggestion handler.
|
|
299
315
|
*
|
|
@@ -358,9 +374,10 @@ export default function useAiSuggestions( {
|
|
|
358
374
|
error,
|
|
359
375
|
requestingState,
|
|
360
376
|
|
|
361
|
-
//
|
|
377
|
+
// Requests handlers
|
|
362
378
|
request,
|
|
363
379
|
stopSuggestion,
|
|
380
|
+
reset,
|
|
364
381
|
|
|
365
382
|
// SuggestionsEventSource
|
|
366
383
|
eventSource: eventSourceRef.current,
|
|
@@ -10,11 +10,13 @@ Based on [MediaRecorder](https://developer.mozilla.org/en-US/docs/Web/API/MediaR
|
|
|
10
10
|
|
|
11
11
|
The hook returns an object with the following properties and methods:
|
|
12
12
|
|
|
13
|
-
- `
|
|
14
|
-
- `
|
|
15
|
-
- `
|
|
16
|
-
- `
|
|
17
|
-
- `
|
|
13
|
+
- `state: 'inactive' | 'recording' | 'paused'` - Current recording state
|
|
14
|
+
- `blob`: `blob` - The recorded blob
|
|
15
|
+
- `url`: `string` - The recorded blob url
|
|
16
|
+
- `start: ( timeslice ) => void` - Start the media recording
|
|
17
|
+
- `pause: () => void` - Pause the current media recording
|
|
18
|
+
- `resume: () => void` - Resume a paused recording
|
|
19
|
+
- `stop: () => void` - Stop the current recording
|
|
18
20
|
|
|
19
21
|
## Example
|
|
20
22
|
|
|
@@ -22,6 +22,11 @@ type UseMediaRecordingReturn = {
|
|
|
22
22
|
*/
|
|
23
23
|
blob: Blob | null;
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* The recorded blob url
|
|
27
|
+
*/
|
|
28
|
+
url: string | null;
|
|
29
|
+
|
|
25
30
|
/**
|
|
26
31
|
* `start` recording handler
|
|
27
32
|
*/
|
|
@@ -195,6 +200,7 @@ export default function useMediaRecording( {
|
|
|
195
200
|
return {
|
|
196
201
|
state,
|
|
197
202
|
blob,
|
|
203
|
+
url: blob ? URL.createObjectURL( blob ) : null,
|
|
198
204
|
|
|
199
205
|
start,
|
|
200
206
|
pause,
|