@ldelia/react-media 0.7.0 → 0.8.1

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.
@@ -13,6 +13,7 @@ export declare class PlayAlongPlayer {
13
13
  static get EVENTS(): {
14
14
  readonly READY: "READY";
15
15
  readonly FINISH: "FINISH";
16
+ readonly ERROR: "ERROR";
16
17
  };
17
18
  play(): void;
18
19
  pause(): void;
@@ -1,4 +1,5 @@
1
1
  export declare const PLAYER_EVENTS: {
2
2
  readonly READY: "READY";
3
3
  readonly FINISH: "FINISH";
4
+ readonly ERROR: "ERROR";
4
5
  };
@@ -1,4 +1,5 @@
1
1
  export const PLAYER_EVENTS = {
2
2
  READY: 'READY',
3
3
  FINISH: 'FINISH',
4
+ ERROR: 'ERROR',
4
5
  };
@@ -3,16 +3,19 @@ import { PlayAlongPlayer } from './PlayAlongPlayer';
3
3
  export type InnerYouTubePlayerInterface = YT.Player;
4
4
  declare const dispatchOnReadyHandlers: unique symbol;
5
5
  declare const dispatchOnFinishHandlers: unique symbol;
6
+ declare const dispatchOnErrorHandlers: unique symbol;
6
7
  export declare class YouTubePlayer {
7
8
  private currentTime;
8
9
  private isRunning;
9
10
  private innerPlayer;
10
11
  private [dispatchOnReadyHandlers];
11
12
  private [dispatchOnFinishHandlers];
13
+ private [dispatchOnErrorHandlers];
12
14
  constructor(innerPlayer: InnerYouTubePlayerInterface);
13
15
  static get EVENTS(): {
14
16
  readonly READY: "READY";
15
17
  readonly FINISH: "FINISH";
18
+ readonly ERROR: "ERROR";
16
19
  };
17
20
  getInnerPlayer(): YT.Player;
18
21
  play(): void;
@@ -25,7 +28,8 @@ export declare class YouTubePlayer {
25
28
  getAvailablePlaybackRates(): number[];
26
29
  setPlaybackRate(playbackRate: number): void;
27
30
  isAvailable(): boolean;
28
- on(eventName: keyof typeof PlayAlongPlayer.EVENTS, handler: () => void): number | undefined;
29
- dispatch(eventName: keyof typeof PlayAlongPlayer.EVENTS): void;
31
+ on(eventName: keyof typeof PlayAlongPlayer.EVENTS, handler: (error?: any) => void): number | undefined;
32
+ dispatch(eventName: keyof typeof PlayAlongPlayer.EVENTS, error?: any): void;
33
+ private getErrorMessage;
30
34
  }
31
35
  export {};
@@ -2,19 +2,27 @@ import { PlayAlongPlayer } from './PlayAlongPlayer';
2
2
  import { PLAYER_EVENTS } from './PlayerEvents';
3
3
  const dispatchOnReadyHandlers = Symbol();
4
4
  const dispatchOnFinishHandlers = Symbol();
5
+ const dispatchOnErrorHandlers = Symbol();
5
6
  export class YouTubePlayer {
6
7
  constructor(innerPlayer) {
7
8
  this[dispatchOnFinishHandlers] = [];
8
9
  this[dispatchOnReadyHandlers] = [];
10
+ this[dispatchOnErrorHandlers] = [];
9
11
  this.currentTime = 0;
10
12
  this.isRunning = false;
11
13
  this.innerPlayer = innerPlayer;
12
- this.innerPlayer = innerPlayer;
13
14
  this.dispatch(YouTubePlayer.EVENTS.READY);
14
15
  // This is necessary for avoiding the state video cued.
15
16
  // When a video is in this state, when the user seeks to X, the song is played
16
17
  this.innerPlayer.playVideo();
17
18
  this.innerPlayer.pauseVideo();
19
+ this.innerPlayer.addEventListener('onError', (event) => {
20
+ this.isRunning = false;
21
+ this.dispatch(YouTubePlayer.EVENTS.ERROR, {
22
+ code: event.data,
23
+ message: this.getErrorMessage(event.data)
24
+ });
25
+ });
18
26
  this.innerPlayer.addEventListener('onStateChange', (videoState) => {
19
27
  switch (videoState.data) {
20
28
  case YT.PlayerState.ENDED:
@@ -92,12 +100,16 @@ export class YouTubePlayer {
92
100
  return this[dispatchOnReadyHandlers].push(handler);
93
101
  case PlayAlongPlayer.EVENTS.FINISH:
94
102
  return this[dispatchOnFinishHandlers].push(handler);
103
+ case PlayAlongPlayer.EVENTS.ERROR:
104
+ return this[dispatchOnErrorHandlers].push(handler);
95
105
  default:
96
106
  break;
97
107
  }
98
108
  }
99
- dispatch(eventName) {
100
- let handler, i, len;
109
+ dispatch(eventName, error) {
110
+ let handler;
111
+ let i;
112
+ let len;
101
113
  let ref = [];
102
114
  switch (eventName) {
103
115
  case YouTubePlayer.EVENTS.READY:
@@ -106,12 +118,30 @@ export class YouTubePlayer {
106
118
  case YouTubePlayer.EVENTS.FINISH:
107
119
  ref = this[dispatchOnFinishHandlers];
108
120
  break;
121
+ case YouTubePlayer.EVENTS.ERROR:
122
+ ref = this[dispatchOnErrorHandlers];
123
+ break;
109
124
  default:
110
125
  break;
111
126
  }
112
127
  for (i = 0, len = ref.length; i < len; i++) {
113
128
  handler = ref[i];
114
- setTimeout(handler, 0);
129
+ setTimeout(() => handler(error), 0);
130
+ }
131
+ }
132
+ getErrorMessage(errorCode) {
133
+ switch (errorCode) {
134
+ case YT.PlayerError.InvalidParam:
135
+ return 'Invalid parameter value';
136
+ case YT.PlayerError.Html5Error:
137
+ return 'HTML5 player error';
138
+ case YT.PlayerError.VideoNotFound:
139
+ return 'Video not found';
140
+ case YT.PlayerError.EmbeddingNotAllowed:
141
+ case YT.PlayerError.EmbeddingNotAllowed2:
142
+ return 'Video cannot be played in embedded players';
143
+ default:
144
+ return `Unknown error (code: ${errorCode})`;
115
145
  }
116
146
  }
117
147
  }
@@ -10,6 +10,7 @@ declare const dispatchOnPlayHandlers: unique symbol;
10
10
  declare const dispatchOnPlayingHandlers: unique symbol;
11
11
  declare const dispatchOnPausedHandlers: unique symbol;
12
12
  declare const dispatchOnFinishHandlers: unique symbol;
13
+ declare const dispatchOnErrorHandlers: unique symbol;
13
14
  export declare class Reproduction {
14
15
  private player;
15
16
  private requiresCountingIn;
@@ -26,6 +27,7 @@ export declare class Reproduction {
26
27
  private [dispatchOnPlayingHandlers];
27
28
  private [dispatchOnPausedHandlers];
28
29
  private [dispatchOnFinishHandlers];
30
+ private [dispatchOnErrorHandlers];
29
31
  constructor(player: Player, requiresCountingIn: boolean, songTempo: number, volume: number);
30
32
  static get EVENTS(): {
31
33
  readonly READY: "READY";
@@ -35,6 +37,7 @@ export declare class Reproduction {
35
37
  readonly PLAYING: "PLAYING";
36
38
  readonly PAUSED: "PAUSED";
37
39
  readonly FINISH: "FINISH";
40
+ readonly ERROR: "ERROR";
38
41
  };
39
42
  static get STATES(): {
40
43
  STOPPED: number;
@@ -14,6 +14,7 @@ const EVENTS = {
14
14
  PLAYING: 'PLAYING',
15
15
  PAUSED: 'PAUSED',
16
16
  FINISH: 'FINISH',
17
+ ERROR: 'ERROR',
17
18
  };
18
19
  const dispatchOnReadyHandlers = Symbol();
19
20
  const dispatchOnSongStartHandlers = Symbol();
@@ -22,6 +23,7 @@ const dispatchOnPlayHandlers = Symbol();
22
23
  const dispatchOnPlayingHandlers = Symbol();
23
24
  const dispatchOnPausedHandlers = Symbol();
24
25
  const dispatchOnFinishHandlers = Symbol();
26
+ const dispatchOnErrorHandlers = Symbol();
25
27
  export class Reproduction {
26
28
  constructor(player, requiresCountingIn, songTempo, volume) {
27
29
  this.volume = 50; // between 0 and 100
@@ -32,6 +34,7 @@ export class Reproduction {
32
34
  this[dispatchOnPlayingHandlers] = [];
33
35
  this[dispatchOnPausedHandlers] = [];
34
36
  this[dispatchOnFinishHandlers] = [];
37
+ this[dispatchOnErrorHandlers] = [];
35
38
  this.songTempo = songTempo;
36
39
  this.player = player;
37
40
  this.ready = false;
@@ -49,6 +52,9 @@ export class Reproduction {
49
52
  clearInterval(this.interval);
50
53
  this.dispatch(Reproduction.EVENTS.FINISH);
51
54
  });
55
+ this.player.on(PLAYER_EVENTS.ERROR, (error) => {
56
+ this.dispatch(Reproduction.EVENTS.ERROR, { error });
57
+ });
52
58
  }
53
59
  static get EVENTS() {
54
60
  return EVENTS;
@@ -75,6 +81,8 @@ export class Reproduction {
75
81
  return this[dispatchOnPausedHandlers].push(handler);
76
82
  case Reproduction.EVENTS.FINISH:
77
83
  return this[dispatchOnFinishHandlers].push(handler);
84
+ case Reproduction.EVENTS.ERROR:
85
+ return this[dispatchOnErrorHandlers].push(handler);
78
86
  default:
79
87
  break;
80
88
  }
@@ -104,13 +112,15 @@ export class Reproduction {
104
112
  case Reproduction.EVENTS.FINISH:
105
113
  ref = this[dispatchOnFinishHandlers];
106
114
  break;
115
+ case Reproduction.EVENTS.ERROR:
116
+ ref = this[dispatchOnErrorHandlers];
117
+ break;
107
118
  default:
108
119
  break;
109
120
  }
110
121
  for (i = 0, len = ref.length; i < len; i++) {
111
122
  handler = ref[i];
112
123
  handler(args);
113
- // setTimeout(handler, 0);
114
124
  }
115
125
  }
116
126
  start() {
@@ -122,6 +132,7 @@ export class Reproduction {
122
132
  this.countInAndPlay(this.getBPMInterval() * 2, 3);
123
133
  }
124
134
  else {
135
+ this.seekTo(0);
125
136
  this.play();
126
137
  }
127
138
  }
@@ -18,7 +18,7 @@ const Template = (args) => {
18
18
  reproductionInstance.on('PLAYING', refreshEvent);
19
19
  reproductionInstance.on('PAUSED', refreshEvent);
20
20
  reproductionInstance.on('FINISH', refreshEvent);
21
- reproductionInstance.start();
21
+ reproductionInstance.on('ERROR', (args) => { console.error("Reproduction error", args); });
22
22
  }, []);
23
23
  const handleStop = () => {
24
24
  if (reproduction) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ldelia/react-media",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
4
4
  "description": "A React components collection for media-related features.",
5
5
  "private": false,
6
6
  "keywords": [
@@ -85,7 +85,6 @@
85
85
  "postcss-flexbugs-fixes": "^5.0.2",
86
86
  "postcss-loader": "^6.2.1",
87
87
  "postcss-normalize": "^10.0.1",
88
- "postcss-preset-env": "^7.0.1",
89
88
  "prompts": "^2.4.2",
90
89
  "react": "^18.3.1",
91
90
  "react-app-polyfill": "^3.0.0",
@@ -103,10 +102,10 @@
103
102
  "tailwindcss": "^3.0.2",
104
103
  "terser-webpack-plugin": "^5.2.5",
105
104
  "typescript": "^4.9.5",
106
- "webpack": "^5.64.4",
107
- "webpack-dev-server": "^4.6.0",
108
- "webpack-manifest-plugin": "^4.0.2",
109
- "workbox-webpack-plugin": "^6.4.1"
105
+ "webpack": "^5.102.1",
106
+ "webpack-dev-server": "^5.2.2",
107
+ "webpack-manifest-plugin": "^5.0.1",
108
+ "workbox-webpack-plugin": "^7.3.0"
110
109
  },
111
110
  "devDependencies": {
112
111
  "@babel/core": "^7.24.9",
@@ -115,11 +114,11 @@
115
114
  "@babel/preset-react": "^7.24.7",
116
115
  "@babel/preset-typescript": "^7.24.7",
117
116
  "@chromatic-com/storybook": "^4.1.1",
118
- "@storybook/addon-docs": "^9.1.10",
119
- "@storybook/addon-links": "^9.1.10",
120
- "@storybook/addon-onboarding": "^9.1.10",
117
+ "@storybook/addon-docs": "^9.1.12",
118
+ "@storybook/addon-links": "^9.1.12",
119
+ "@storybook/addon-onboarding": "^9.1.12",
121
120
  "@storybook/react-docgen-typescript-plugin": "^1.0.6--canary.9.0c3f3b7.0",
122
- "@storybook/react-webpack5": "^9.1.10",
121
+ "@storybook/react-webpack5": "^9.1.12",
123
122
  "@testing-library/jest-dom": "^6.4.6",
124
123
  "@testing-library/react": "^16.0.0",
125
124
  "@testing-library/user-event": "^14.5.2",
@@ -128,19 +127,19 @@
128
127
  "@types/react": "^18.3.3",
129
128
  "@types/react-dom": "^18.3.0",
130
129
  "@types/styled-components": "^5.1.34",
131
- "@types/youtube": "^0.0.50",
130
+ "@types/youtube": "^0.1.2",
132
131
  "babel-loader": "^9.1.3",
133
132
  "eslint-config-prettier": "^9.1.0",
134
133
  "eslint-plugin-prettier": "^5.1.3",
135
- "eslint-plugin-storybook": "^9.1.10",
134
+ "eslint-plugin-storybook": "^9.1.12",
136
135
  "jest-environment-jsdom": "^30.2.0",
137
136
  "postcss-flexbugs-fixes": "^5.0.2",
138
137
  "postcss-normalize": "^10.0.1",
139
- "postcss-preset-env": "^9.5.14",
138
+ "postcss-preset-env": "^10.4.0",
140
139
  "prettier": "^3.3.2",
141
140
  "prop-types": "^15.8.1",
142
141
  "react-docgen-typescript-plugin": "^1.0.8",
143
- "storybook": "^9.1.10",
142
+ "storybook": "^9.1.12",
144
143
  "ts-loader": "^9.5.1",
145
144
  "tsconfig-paths-webpack-plugin": "^4.1.0",
146
145
  "webpack": "^5.92.0"