@ldelia/react-media 0.8.8 → 0.9.0
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/dist/components/reproduction-widget/models/Player/YouTubePlayer.d.ts +0 -1
- package/dist/components/reproduction-widget/models/Reproduction.d.ts +3 -0
- package/dist/components/reproduction-widget/models/Reproduction.js +35 -0
- package/dist/stories/reproduction-widget.stories.d.ts +6 -5
- package/dist/stories/reproduction-widget.stories.js +21 -7
- package/dist/stories/timeline.stories.d.ts +8 -7
- package/dist/stories/timeline.stories.js +1 -1
- package/package.json +10 -10
|
@@ -17,6 +17,8 @@ export declare class Reproduction {
|
|
|
17
17
|
private songTempo;
|
|
18
18
|
private state;
|
|
19
19
|
private interval;
|
|
20
|
+
private loopInterval;
|
|
21
|
+
private loopRange;
|
|
20
22
|
private countingInCounter;
|
|
21
23
|
private [dispatchOnReadyHandlers];
|
|
22
24
|
private [dispatchOnSongStartHandlers];
|
|
@@ -47,6 +49,7 @@ export declare class Reproduction {
|
|
|
47
49
|
dispatch(eventName: keyof typeof Reproduction.EVENTS, args?: {}): void;
|
|
48
50
|
start(): void;
|
|
49
51
|
play(): void;
|
|
52
|
+
playLoop(from: number, to: number): void;
|
|
50
53
|
pause(): void;
|
|
51
54
|
stop(): void;
|
|
52
55
|
isPlaying(): boolean;
|
|
@@ -37,6 +37,8 @@ export class Reproduction {
|
|
|
37
37
|
this.player = player;
|
|
38
38
|
this.state = Reproduction.STATES.STOPPED;
|
|
39
39
|
this.interval = null;
|
|
40
|
+
this.loopInterval = null;
|
|
41
|
+
this.loopRange = null;
|
|
40
42
|
this.requiresCountingIn = requiresCountingIn;
|
|
41
43
|
this.countingInCounter = 0;
|
|
42
44
|
this.player.setVolume(volume);
|
|
@@ -47,6 +49,9 @@ export class Reproduction {
|
|
|
47
49
|
this.player.on(PLAYER_EVENTS.FINISH, () => {
|
|
48
50
|
this.state = Reproduction.STATES.STOPPED;
|
|
49
51
|
clearInterval(this.interval);
|
|
52
|
+
clearInterval(this.loopInterval);
|
|
53
|
+
this.loopInterval = null;
|
|
54
|
+
this.loopRange = null;
|
|
50
55
|
this.dispatch(Reproduction.EVENTS.FINISH);
|
|
51
56
|
});
|
|
52
57
|
this.player.on(PLAYER_EVENTS.ERROR, (error) => {
|
|
@@ -129,6 +134,7 @@ export class Reproduction {
|
|
|
129
134
|
}
|
|
130
135
|
}
|
|
131
136
|
play() {
|
|
137
|
+
clearInterval(this.interval);
|
|
132
138
|
this.player.play();
|
|
133
139
|
const intervalTimeout = 200;
|
|
134
140
|
this.interval = setInterval(() => {
|
|
@@ -137,16 +143,45 @@ export class Reproduction {
|
|
|
137
143
|
}
|
|
138
144
|
}, intervalTimeout);
|
|
139
145
|
}
|
|
146
|
+
playLoop(from, to) {
|
|
147
|
+
if (!Number.isFinite(from) || !Number.isFinite(to)) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (to <= from) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
clearInterval(this.loopInterval);
|
|
154
|
+
this.loopInterval = null;
|
|
155
|
+
this.loopRange = { from, to };
|
|
156
|
+
this.seekTo(from);
|
|
157
|
+
this.play();
|
|
158
|
+
const loopCheckInterval = 100;
|
|
159
|
+
this.loopInterval = setInterval(() => {
|
|
160
|
+
if (!this.isPlaying() || !this.loopRange) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const currentTime = this.getCurrentTime();
|
|
164
|
+
if (currentTime >= this.loopRange.to) {
|
|
165
|
+
this.seekTo(this.loopRange.from);
|
|
166
|
+
}
|
|
167
|
+
}, loopCheckInterval);
|
|
168
|
+
}
|
|
140
169
|
pause() {
|
|
141
170
|
this.state = Reproduction.STATES.PAUSED;
|
|
142
171
|
this.player.pause();
|
|
143
172
|
clearInterval(this.interval);
|
|
173
|
+
clearInterval(this.loopInterval);
|
|
174
|
+
this.loopInterval = null;
|
|
175
|
+
this.loopRange = null;
|
|
144
176
|
this.dispatch(Reproduction.EVENTS.PAUSED);
|
|
145
177
|
}
|
|
146
178
|
stop() {
|
|
147
179
|
this.state = Reproduction.STATES.STOPPED;
|
|
148
180
|
this.player.stop();
|
|
149
181
|
clearInterval(this.interval);
|
|
182
|
+
clearInterval(this.loopInterval);
|
|
183
|
+
this.loopInterval = null;
|
|
184
|
+
this.loopRange = null;
|
|
150
185
|
this.dispatch(Reproduction.EVENTS.FINISH);
|
|
151
186
|
}
|
|
152
187
|
isPlaying() {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { Meta } from '@storybook/react';
|
|
1
2
|
import { ReproductionWidgetProps } from '../components/reproduction-widget';
|
|
2
|
-
declare const _default:
|
|
3
|
+
declare const _default: Meta;
|
|
3
4
|
export default _default;
|
|
4
|
-
export declare const Default: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
5
|
-
export declare const WhisperingVideo: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
6
|
-
export declare const PlayAlong: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
7
|
-
export declare const InvalidVideo: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
5
|
+
export declare const Default: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, ReproductionWidgetProps>;
|
|
6
|
+
export declare const WhisperingVideo: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, ReproductionWidgetProps>;
|
|
7
|
+
export declare const PlayAlong: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, ReproductionWidgetProps>;
|
|
8
|
+
export declare const InvalidVideo: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, ReproductionWidgetProps>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useCallback, useState } from 'react';
|
|
2
|
-
import { ReproductionWidget } from '../components/reproduction-widget';
|
|
2
|
+
import { ReproductionWidget, } from '../components/reproduction-widget';
|
|
3
3
|
export default {
|
|
4
4
|
title: 'ReproductionWidget',
|
|
5
5
|
component: ReproductionWidget,
|
|
@@ -12,13 +12,19 @@ const Template = (args) => {
|
|
|
12
12
|
const [reproductionTimestamp, setReproductionTimestamp] = useState(0);
|
|
13
13
|
// Handle initialization of reproduction
|
|
14
14
|
const handleInit = useCallback((reproductionInstance) => {
|
|
15
|
-
const refreshEvent = (args) => {
|
|
15
|
+
const refreshEvent = (args) => {
|
|
16
|
+
setReproductionTimestamp(new Date().getTime());
|
|
17
|
+
};
|
|
16
18
|
setReproduction(reproductionInstance);
|
|
17
|
-
reproductionInstance.on('COUNTING_IN', (args) => {
|
|
19
|
+
reproductionInstance.on('COUNTING_IN', (args) => {
|
|
20
|
+
console.log('counting in', args);
|
|
21
|
+
});
|
|
18
22
|
reproductionInstance.on('PLAYING', refreshEvent);
|
|
19
23
|
reproductionInstance.on('PAUSED', refreshEvent);
|
|
20
24
|
reproductionInstance.on('FINISH', refreshEvent);
|
|
21
|
-
reproductionInstance.on('ERROR', (args) => {
|
|
25
|
+
reproductionInstance.on('ERROR', (args) => {
|
|
26
|
+
console.error('Reproduction error', args);
|
|
27
|
+
});
|
|
22
28
|
}, []);
|
|
23
29
|
const handleStop = () => {
|
|
24
30
|
if (reproduction) {
|
|
@@ -40,19 +46,27 @@ const Template = (args) => {
|
|
|
40
46
|
reproduction.start();
|
|
41
47
|
}
|
|
42
48
|
};
|
|
49
|
+
const handleLoop = () => {
|
|
50
|
+
if (reproduction) {
|
|
51
|
+
reproduction.playLoop(10, 20);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
43
54
|
return (React.createElement("div", null,
|
|
44
55
|
React.createElement(ReproductionWidget, Object.assign({}, args, { onInit: handleInit })),
|
|
45
56
|
React.createElement("div", null,
|
|
46
57
|
React.createElement("button", { onClick: handleStop, disabled: !reproduction || reproduction.isStopped() }, "Stop"),
|
|
47
58
|
React.createElement("button", { onClick: handlePause, disabled: !reproduction || !reproduction.isPlaying() }, "Pause"),
|
|
48
|
-
React.createElement("button", { onClick: handleResume, disabled: !reproduction ||
|
|
59
|
+
React.createElement("button", { onClick: handleResume, disabled: !reproduction ||
|
|
60
|
+
reproduction.isPlaying() ||
|
|
61
|
+
reproduction.getCurrentTime() === 0 }, "Resume"),
|
|
49
62
|
React.createElement("button", { onClick: handleStart, disabled: !reproduction || reproduction.isPlaying() }, "Start"),
|
|
63
|
+
React.createElement("button", { onClick: handleLoop, disabled: !reproduction }, "Loop 10-20"),
|
|
50
64
|
reproduction && (React.createElement("div", null,
|
|
51
65
|
"Current time: ", reproduction === null || reproduction === void 0 ? void 0 :
|
|
52
66
|
reproduction.getCurrentTime())),
|
|
53
|
-
reproduction &&
|
|
67
|
+
reproduction && React.createElement("div", null,
|
|
54
68
|
"Volume: ", reproduction === null || reproduction === void 0 ? void 0 :
|
|
55
|
-
reproduction.getVolume())
|
|
69
|
+
reproduction.getVolume()),
|
|
56
70
|
React.createElement("button", { onClick: () => reproduction === null || reproduction === void 0 ? void 0 : reproduction.setVolume(reproduction.getVolume() - 10), disabled: !reproduction || reproduction.getVolume() <= 10 }, "Volume -10"),
|
|
57
71
|
React.createElement("button", { onClick: () => reproduction === null || reproduction === void 0 ? void 0 : reproduction.setVolume(reproduction.getVolume() + 10), disabled: !reproduction || reproduction.getVolume() >= 100 }, "Volume +10"))));
|
|
58
72
|
};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import type { Meta } from '@storybook/react';
|
|
1
2
|
import { TimelineProps } from '../components/timeline';
|
|
2
3
|
import './timeline.stories.custom.css';
|
|
3
|
-
declare const _default:
|
|
4
|
+
declare const _default: Meta;
|
|
4
5
|
export default _default;
|
|
5
|
-
export declare const Default: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
6
|
-
export declare const WithSelectedRange: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
7
|
-
export declare const WithCustomClassName: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
8
|
-
export declare const WithoutTimeBlocks: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
9
|
-
export declare const Minimalist: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
10
|
-
export declare const WithSelectedRangeAndMarkers: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
6
|
+
export declare const Default: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, TimelineProps>;
|
|
7
|
+
export declare const WithSelectedRange: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, TimelineProps>;
|
|
8
|
+
export declare const WithCustomClassName: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, TimelineProps>;
|
|
9
|
+
export declare const WithoutTimeBlocks: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, TimelineProps>;
|
|
10
|
+
export declare const Minimalist: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, TimelineProps>;
|
|
11
|
+
export declare const WithSelectedRangeAndMarkers: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, TimelineProps>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Timeline } from '../components/timeline';
|
|
3
2
|
import styled from 'styled-components';
|
|
3
|
+
import { Timeline } from '../components/timeline';
|
|
4
4
|
import './timeline.stories.custom.css';
|
|
5
5
|
const StyledTimeline = styled(Timeline) `
|
|
6
6
|
.media-timeline-value-line {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ldelia/react-media",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "A React components collection for media-related features.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"keywords": [
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"styled-components": "^6.1.11",
|
|
102
102
|
"tailwindcss": "^3.0.2",
|
|
103
103
|
"terser-webpack-plugin": "^5.2.5",
|
|
104
|
-
"typescript": "^
|
|
104
|
+
"typescript": "^5.3.3",
|
|
105
105
|
"webpack": "^5.102.1",
|
|
106
106
|
"webpack-dev-server": "^5.2.2",
|
|
107
107
|
"webpack-manifest-plugin": "^5.0.1",
|
|
@@ -113,12 +113,12 @@
|
|
|
113
113
|
"@babel/preset-env": "^7.24.8",
|
|
114
114
|
"@babel/preset-react": "^7.24.7",
|
|
115
115
|
"@babel/preset-typescript": "^7.24.7",
|
|
116
|
-
"@chromatic-com/storybook": "^
|
|
117
|
-
"@storybook/addon-docs": "^
|
|
118
|
-
"@storybook/addon-links": "^
|
|
119
|
-
"@storybook/addon-onboarding": "^
|
|
116
|
+
"@chromatic-com/storybook": "^5.0.1",
|
|
117
|
+
"@storybook/addon-docs": "^10.2.8",
|
|
118
|
+
"@storybook/addon-links": "^10.2.8",
|
|
119
|
+
"@storybook/addon-onboarding": "^10.2.8",
|
|
120
120
|
"@storybook/react-docgen-typescript-plugin": "^1.0.6--canary.9.0c3f3b7.0",
|
|
121
|
-
"@storybook/react-webpack5": "^
|
|
121
|
+
"@storybook/react-webpack5": "^10.2.8",
|
|
122
122
|
"@testing-library/jest-dom": "^6.4.6",
|
|
123
123
|
"@testing-library/react": "^16.0.0",
|
|
124
124
|
"@testing-library/user-event": "^14.5.2",
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
"babel-loader": "^9.1.3",
|
|
132
132
|
"eslint-config-prettier": "^9.1.0",
|
|
133
133
|
"eslint-plugin-prettier": "^5.1.3",
|
|
134
|
-
"eslint-plugin-storybook": "^
|
|
134
|
+
"eslint-plugin-storybook": "^10.2.8",
|
|
135
135
|
"jest-environment-jsdom": "^30.2.0",
|
|
136
136
|
"postcss-flexbugs-fixes": "^5.0.2",
|
|
137
137
|
"postcss-normalize": "^10.0.1",
|
|
@@ -139,10 +139,10 @@
|
|
|
139
139
|
"prettier": "^3.3.2",
|
|
140
140
|
"prop-types": "^15.8.1",
|
|
141
141
|
"react-docgen-typescript-plugin": "^1.0.8",
|
|
142
|
-
"storybook": "^
|
|
142
|
+
"storybook": "^10.2.8",
|
|
143
143
|
"ts-loader": "^9.5.1",
|
|
144
144
|
"tsconfig-paths-webpack-plugin": "^4.1.0",
|
|
145
|
-
"webpack": "^5.
|
|
145
|
+
"webpack": "^5.105.2"
|
|
146
146
|
},
|
|
147
147
|
"jest": {
|
|
148
148
|
"roots": [
|