@douyinfe/semi-foundation 2.79.0 → 2.80.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/cascader/foundation.ts +2 -2
- package/lib/cjs/cascader/foundation.js +1 -1
- package/lib/cjs/videoPlayer/animation.scss +7 -0
- package/lib/cjs/videoPlayer/constants.d.ts +30 -0
- package/lib/cjs/videoPlayer/constants.js +48 -0
- package/lib/cjs/videoPlayer/foundation.d.ts +75 -0
- package/lib/cjs/videoPlayer/foundation.js +291 -0
- package/lib/cjs/videoPlayer/progressFoundation.d.ts +38 -0
- package/lib/cjs/videoPlayer/progressFoundation.js +131 -0
- package/lib/cjs/videoPlayer/variables.scss +75 -0
- package/lib/cjs/videoPlayer/videoPlayer.css +279 -0
- package/lib/cjs/videoPlayer/videoPlayer.scss +323 -0
- package/lib/es/cascader/foundation.js +1 -1
- package/lib/es/videoPlayer/animation.scss +7 -0
- package/lib/es/videoPlayer/constants.d.ts +30 -0
- package/lib/es/videoPlayer/constants.js +43 -0
- package/lib/es/videoPlayer/foundation.d.ts +75 -0
- package/lib/es/videoPlayer/foundation.js +283 -0
- package/lib/es/videoPlayer/progressFoundation.d.ts +38 -0
- package/lib/es/videoPlayer/progressFoundation.js +123 -0
- package/lib/es/videoPlayer/variables.scss +75 -0
- package/lib/es/videoPlayer/videoPlayer.css +279 -0
- package/lib/es/videoPlayer/videoPlayer.scss +323 -0
- package/package.json +4 -4
- package/videoPlayer/animation.scss +7 -0
- package/videoPlayer/constants.ts +39 -0
- package/videoPlayer/foundation.ts +332 -0
- package/videoPlayer/progressFoundation.ts +136 -0
- package/videoPlayer/variables.scss +75 -0
- package/videoPlayer/videoPlayer.scss +323 -0
package/cascader/foundation.ts
CHANGED
|
@@ -242,7 +242,7 @@ export interface CascaderAdapter extends DefaultAdapter<BasicCascaderProps, Basi
|
|
|
242
242
|
updateLoadedKeyRefValue: (keys: Set<string>) => void;
|
|
243
243
|
getLoadedKeyRefValue: () => Set<string>;
|
|
244
244
|
setEmptyContentMinWidth: (minWidth: number) => void;
|
|
245
|
-
getTriggerWidth: () => number
|
|
245
|
+
getTriggerWidth: () => number
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
export default class CascaderFoundation extends BaseFoundation<CascaderAdapter, BasicCascaderProps, BasicCascaderInnerData> {
|
|
@@ -521,7 +521,7 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
521
521
|
}
|
|
522
522
|
keyEntities[key] = optionNotExist as BasicEntity;
|
|
523
523
|
// Fix: 1155, if the data is loaded asynchronously to update treeData, the emptying operation should not be done when entering the updateSelectedKey method
|
|
524
|
-
} else if (loading) {
|
|
524
|
+
} else if (loading || loadingKeys?.size) {
|
|
525
525
|
// Use assign to avoid overwriting the'not-exist- * 'property of keyEntities after asynchronous loading
|
|
526
526
|
// Overwriting'not-exist- * 'will cause selectionContent to be emptied unexpectedly when clicking on a dropDown item
|
|
527
527
|
updateStates.keyEntities = assign(keyEntityState, keyEntities);
|
|
@@ -323,7 +323,7 @@ class CascaderFoundation extends _foundation.default {
|
|
|
323
323
|
}
|
|
324
324
|
keyEntities[key] = optionNotExist;
|
|
325
325
|
// Fix: 1155, if the data is loaded asynchronously to update treeData, the emptying operation should not be done when entering the updateSelectedKey method
|
|
326
|
-
} else if (loading) {
|
|
326
|
+
} else if (loading || (loadingKeys === null || loadingKeys === void 0 ? void 0 : loadingKeys.size)) {
|
|
327
327
|
// Use assign to avoid overwriting the'not-exist- * 'property of keyEntities after asynchronous loading
|
|
328
328
|
// Overwriting'not-exist- * 'will cause selectionContent to be emptied unexpectedly when clicking on a dropDown item
|
|
329
329
|
updateStates.keyEntities = (0, _assign2.default)(keyEntityState, keyEntities);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
$animation_duration-videoPlayer_controls-show: 500ms; // videoPlayer菜单栏-弹出动画-动画持续时间
|
|
2
|
+
$animation_duration-videoPlayer_slider-in: 300ms; // videoPlayer进度条-弹出动画-动画持续时间
|
|
3
|
+
$animation_duration-videoPlayer_slider-out: 300ms; // videoPlayer进度条-收起动画-动画持续时间
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
$animation_function-videoPlayer_slider-in: cubic-bezier(0.62, 0.05, 0.36, 0.95); // videoPlayer进度条-弹出动画-动画插值函数
|
|
7
|
+
$animation_function-videoPlayer_slider-out: cubic-bezier(0.62, 0.05, 0.36, 0.95); // videoPlayer进度条-收起动画-动画插值函数
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
declare const cssClasses: {
|
|
2
|
+
readonly PREFIX: "semi-videoPlayer";
|
|
3
|
+
readonly PREFIX_CONTROLS: "semi-videoPlayer-controls";
|
|
4
|
+
readonly PREFIX_PROGRESS: "semi-videoPlayer-progress";
|
|
5
|
+
};
|
|
6
|
+
declare const strings: {
|
|
7
|
+
readonly DARK: "dark";
|
|
8
|
+
readonly LIGHT: "light";
|
|
9
|
+
readonly PLAY: "play";
|
|
10
|
+
readonly NEXT: "next";
|
|
11
|
+
readonly TIME: "time";
|
|
12
|
+
readonly VOLUME: "volume";
|
|
13
|
+
readonly PLAYBACK_RATE: "playbackRate";
|
|
14
|
+
readonly QUALITY: "quality";
|
|
15
|
+
readonly ROUTE: "route";
|
|
16
|
+
readonly MIRROR: "mirror";
|
|
17
|
+
readonly FULLSCREEN: "fullscreen";
|
|
18
|
+
readonly PICTURE_IN_PICTURE: "pictureInPicture";
|
|
19
|
+
};
|
|
20
|
+
declare const numbers: {
|
|
21
|
+
readonly DEFAULT_VOLUME: 100;
|
|
22
|
+
readonly DEFAULT_SEEK_TIME: 10;
|
|
23
|
+
readonly DEFAULT_VOLUME_STEP: 10;
|
|
24
|
+
readonly DEFAULT_PLAYBACK_RATE: 1;
|
|
25
|
+
};
|
|
26
|
+
declare const DEFAULT_PLAYBACK_RATE: {
|
|
27
|
+
label: string;
|
|
28
|
+
value: number;
|
|
29
|
+
}[];
|
|
30
|
+
export { cssClasses, strings, numbers, DEFAULT_PLAYBACK_RATE };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.strings = exports.numbers = exports.cssClasses = exports.DEFAULT_PLAYBACK_RATE = void 0;
|
|
7
|
+
var _constants = require("../base/constants");
|
|
8
|
+
const cssClasses = exports.cssClasses = {
|
|
9
|
+
PREFIX: `${_constants.BASE_CLASS_PREFIX}-videoPlayer`,
|
|
10
|
+
PREFIX_CONTROLS: `${_constants.BASE_CLASS_PREFIX}-videoPlayer-controls`,
|
|
11
|
+
PREFIX_PROGRESS: `${_constants.BASE_CLASS_PREFIX}-videoPlayer-progress`
|
|
12
|
+
};
|
|
13
|
+
const strings = exports.strings = {
|
|
14
|
+
DARK: 'dark',
|
|
15
|
+
LIGHT: 'light',
|
|
16
|
+
PLAY: 'play',
|
|
17
|
+
NEXT: 'next',
|
|
18
|
+
TIME: 'time',
|
|
19
|
+
VOLUME: 'volume',
|
|
20
|
+
PLAYBACK_RATE: 'playbackRate',
|
|
21
|
+
QUALITY: 'quality',
|
|
22
|
+
ROUTE: 'route',
|
|
23
|
+
MIRROR: 'mirror',
|
|
24
|
+
FULLSCREEN: 'fullscreen',
|
|
25
|
+
PICTURE_IN_PICTURE: 'pictureInPicture'
|
|
26
|
+
};
|
|
27
|
+
const numbers = exports.numbers = {
|
|
28
|
+
DEFAULT_VOLUME: 100,
|
|
29
|
+
DEFAULT_SEEK_TIME: 10,
|
|
30
|
+
DEFAULT_VOLUME_STEP: 10,
|
|
31
|
+
DEFAULT_PLAYBACK_RATE: 1
|
|
32
|
+
};
|
|
33
|
+
const DEFAULT_PLAYBACK_RATE = exports.DEFAULT_PLAYBACK_RATE = [{
|
|
34
|
+
label: '2.0x',
|
|
35
|
+
value: 2
|
|
36
|
+
}, {
|
|
37
|
+
label: '1.5x',
|
|
38
|
+
value: 1.5
|
|
39
|
+
}, {
|
|
40
|
+
label: '1.25x',
|
|
41
|
+
value: 1.25
|
|
42
|
+
}, {
|
|
43
|
+
label: '1.0x',
|
|
44
|
+
value: 1
|
|
45
|
+
}, {
|
|
46
|
+
label: '0.75x',
|
|
47
|
+
value: 0.75
|
|
48
|
+
}];
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/// <reference types="lodash" />
|
|
2
|
+
import BaseFoundation, { DefaultAdapter } from '../base/foundation';
|
|
3
|
+
export interface VideoPlayerAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
|
|
4
|
+
getVideo: () => HTMLVideoElement | null;
|
|
5
|
+
getVideoWrapper: () => HTMLDivElement | null;
|
|
6
|
+
notifyPause: () => void;
|
|
7
|
+
notifyPlay: () => void;
|
|
8
|
+
notifyQualityChange: (quality: string) => void;
|
|
9
|
+
notifyRateChange: (rate: number) => void;
|
|
10
|
+
notifyRouteChange: (route: string) => void;
|
|
11
|
+
notifyVolumeChange: (volume: number) => void;
|
|
12
|
+
setBufferedValue: (bufferedValue: number) => void;
|
|
13
|
+
setCurrentTime: (currentTime: number) => void;
|
|
14
|
+
setIsError: (isError: boolean) => void;
|
|
15
|
+
setIsMirror: (isMirror: boolean) => void;
|
|
16
|
+
setIsPlaying: (isPlaying: boolean) => void;
|
|
17
|
+
setMuted: (muted: boolean) => void;
|
|
18
|
+
setNotificationContent: (content: string) => void;
|
|
19
|
+
setPlaybackRate: (rate: number) => void;
|
|
20
|
+
setQuality: (quality: string) => void;
|
|
21
|
+
setRoute: (route: string) => void;
|
|
22
|
+
setShowControls: (showControls: boolean) => void;
|
|
23
|
+
setShowNotification: (showNotification: boolean) => void;
|
|
24
|
+
setTotalTime: (totalTime: number) => void;
|
|
25
|
+
setVolume: (volume: number) => void;
|
|
26
|
+
}
|
|
27
|
+
export default class VideoPlayerFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<VideoPlayerAdapter<P, S>, P, S> {
|
|
28
|
+
constructor(adapter: VideoPlayerAdapter<P, S>);
|
|
29
|
+
private controlsTimer;
|
|
30
|
+
private scrollPosition;
|
|
31
|
+
init(): void;
|
|
32
|
+
destroy(): void;
|
|
33
|
+
shouldShowControlItem(name: string): boolean;
|
|
34
|
+
clearTimer(): void;
|
|
35
|
+
handleMouseMove: import("lodash").DebouncedFuncLeading<() => void>;
|
|
36
|
+
handleTimeChange(value: number): void;
|
|
37
|
+
handleTimeUpdate(): void;
|
|
38
|
+
handleDurationChange(): void;
|
|
39
|
+
handleError(): void;
|
|
40
|
+
handlePlayOrPause(): void;
|
|
41
|
+
handlePlay(): void;
|
|
42
|
+
handlePause(): void;
|
|
43
|
+
handleCanPlay: () => void;
|
|
44
|
+
handleWaiting: (locale: any) => void;
|
|
45
|
+
handleStalled: (locale: any) => void;
|
|
46
|
+
handleProgress: () => void;
|
|
47
|
+
handleEnded: () => void;
|
|
48
|
+
handleVolumeChange(value: number): void;
|
|
49
|
+
handleVolumeSilent: () => void;
|
|
50
|
+
checkFullScreen(): boolean;
|
|
51
|
+
handleFullscreen: () => void;
|
|
52
|
+
handleRateChange(rate: {
|
|
53
|
+
label: string;
|
|
54
|
+
value: number;
|
|
55
|
+
}, locale: any): void;
|
|
56
|
+
handleQualityChange(quality: {
|
|
57
|
+
label: string;
|
|
58
|
+
value: string;
|
|
59
|
+
}, locale: any): void;
|
|
60
|
+
handleRouteChange(route: {
|
|
61
|
+
label: string;
|
|
62
|
+
value: string;
|
|
63
|
+
}, locale: any): void;
|
|
64
|
+
handleMirror: (locale: any) => void;
|
|
65
|
+
handlePictureInPicture: () => void;
|
|
66
|
+
handleLeavePictureInPicture: () => void;
|
|
67
|
+
handleTemporaryNotification: (content: string) => void;
|
|
68
|
+
restorePlayPosition(): void;
|
|
69
|
+
handleMouseEnterWrapper: () => void;
|
|
70
|
+
handleMouseLeaveWrapper: () => void;
|
|
71
|
+
handleFullscreenChange: () => void;
|
|
72
|
+
registerEvent: () => void;
|
|
73
|
+
unregisterEvent: () => void;
|
|
74
|
+
handleBodyKeyDown(e: KeyboardEvent): void;
|
|
75
|
+
}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _throttle2 = _interopRequireDefault(require("lodash/throttle"));
|
|
8
|
+
var _foundation = _interopRequireDefault(require("../base/foundation"));
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
class VideoPlayerFoundation extends _foundation.default {
|
|
11
|
+
constructor(adapter) {
|
|
12
|
+
super(Object.assign({}, adapter));
|
|
13
|
+
this.scrollPosition = null;
|
|
14
|
+
this.handleMouseMove = (0, _throttle2.default)(() => {
|
|
15
|
+
this._adapter.setShowControls(true);
|
|
16
|
+
this.clearTimer();
|
|
17
|
+
this.controlsTimer = setTimeout(() => {
|
|
18
|
+
this._adapter.setShowControls(false);
|
|
19
|
+
}, 3000);
|
|
20
|
+
}, 200);
|
|
21
|
+
this.handleCanPlay = () => {
|
|
22
|
+
this._adapter.setShowNotification(false);
|
|
23
|
+
};
|
|
24
|
+
this.handleWaiting = locale => {
|
|
25
|
+
this._adapter.setNotificationContent(locale.loading);
|
|
26
|
+
this._adapter.setShowNotification(true);
|
|
27
|
+
};
|
|
28
|
+
this.handleStalled = locale => {
|
|
29
|
+
this._adapter.setNotificationContent(locale.stall);
|
|
30
|
+
this._adapter.setShowNotification(true);
|
|
31
|
+
};
|
|
32
|
+
this.handleProgress = () => {
|
|
33
|
+
const video = this._adapter.getVideo();
|
|
34
|
+
if (video && video.buffered.length > 0) {
|
|
35
|
+
const bufferedEnd = video.buffered.end(video.buffered.length - 1);
|
|
36
|
+
this._adapter.setBufferedValue(bufferedEnd);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
this.handleEnded = () => {
|
|
40
|
+
this._adapter.setIsPlaying(false);
|
|
41
|
+
this._adapter.setShowControls(true);
|
|
42
|
+
};
|
|
43
|
+
this.handleVolumeSilent = () => {
|
|
44
|
+
const video = this._adapter.getVideo();
|
|
45
|
+
const {
|
|
46
|
+
volume,
|
|
47
|
+
muted
|
|
48
|
+
} = this.getStates();
|
|
49
|
+
if (!video) return;
|
|
50
|
+
if (muted) {
|
|
51
|
+
video.volume = volume / 100;
|
|
52
|
+
this._adapter.setVolume(volume);
|
|
53
|
+
this._adapter.setMuted(false);
|
|
54
|
+
} else {
|
|
55
|
+
video.volume = 0;
|
|
56
|
+
this._adapter.setMuted(true);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
this.handleFullscreen = () => {
|
|
60
|
+
const videoWrapper = this._adapter.getVideoWrapper();
|
|
61
|
+
const isFullScreen = this.checkFullScreen();
|
|
62
|
+
if (videoWrapper) {
|
|
63
|
+
if (isFullScreen) {
|
|
64
|
+
document.exitFullscreen();
|
|
65
|
+
} else {
|
|
66
|
+
// record scroll position before entering fullscreen
|
|
67
|
+
this.scrollPosition = {
|
|
68
|
+
x: window.scrollX,
|
|
69
|
+
y: window.scrollY
|
|
70
|
+
};
|
|
71
|
+
videoWrapper.requestFullscreen();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
this.handleMirror = locale => {
|
|
76
|
+
const {
|
|
77
|
+
isMirror
|
|
78
|
+
} = this.getStates();
|
|
79
|
+
this._adapter.setIsMirror(!isMirror);
|
|
80
|
+
this.handleTemporaryNotification(!isMirror ? locale.mirror : locale.cancelMirror);
|
|
81
|
+
};
|
|
82
|
+
this.handlePictureInPicture = () => {
|
|
83
|
+
const video = this._adapter.getVideo();
|
|
84
|
+
if (!video) return;
|
|
85
|
+
video.requestPictureInPicture();
|
|
86
|
+
};
|
|
87
|
+
this.handleLeavePictureInPicture = () => {
|
|
88
|
+
const video = this._adapter.getVideo();
|
|
89
|
+
if (!video) return;
|
|
90
|
+
this._adapter.setIsPlaying(!video.paused);
|
|
91
|
+
};
|
|
92
|
+
this.handleTemporaryNotification = content => {
|
|
93
|
+
this._adapter.setNotificationContent(content);
|
|
94
|
+
this._adapter.setShowNotification(true);
|
|
95
|
+
setTimeout(() => {
|
|
96
|
+
this._adapter.setShowNotification(false);
|
|
97
|
+
}, 1000);
|
|
98
|
+
};
|
|
99
|
+
this.handleMouseEnterWrapper = () => {
|
|
100
|
+
this._adapter.setShowControls(true);
|
|
101
|
+
};
|
|
102
|
+
this.handleMouseLeaveWrapper = () => {
|
|
103
|
+
const {
|
|
104
|
+
isPlaying
|
|
105
|
+
} = this.getStates();
|
|
106
|
+
if (isPlaying) {
|
|
107
|
+
this._adapter.setShowControls(false);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
this.handleFullscreenChange = () => {
|
|
111
|
+
const isFullScreen = this.checkFullScreen();
|
|
112
|
+
if (isFullScreen) {
|
|
113
|
+
document.addEventListener('mousemove', this.handleMouseMove);
|
|
114
|
+
} else {
|
|
115
|
+
// according to the exit fullScreen has two way, Esc && click the button
|
|
116
|
+
// so we need to restore scroll position after exiting fullscreen
|
|
117
|
+
if (this.scrollPosition) {
|
|
118
|
+
setTimeout(() => {
|
|
119
|
+
window.scrollTo(this.scrollPosition.x, this.scrollPosition.y);
|
|
120
|
+
this.scrollPosition = null;
|
|
121
|
+
}, 0);
|
|
122
|
+
}
|
|
123
|
+
document.removeEventListener('mousemove', this.handleMouseMove);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
this.registerEvent = () => {
|
|
127
|
+
const video = this._adapter.getVideo();
|
|
128
|
+
if (!video) return;
|
|
129
|
+
document.addEventListener('keydown', e => this.handleBodyKeyDown(e));
|
|
130
|
+
document.addEventListener('fullscreenchange', this.handleFullscreenChange);
|
|
131
|
+
video.addEventListener('leavepictureinpicture', this.handleLeavePictureInPicture);
|
|
132
|
+
};
|
|
133
|
+
this.unregisterEvent = () => {
|
|
134
|
+
const video = this._adapter.getVideo();
|
|
135
|
+
if (!video) return;
|
|
136
|
+
document.removeEventListener('keydown', e => this.handleBodyKeyDown(e));
|
|
137
|
+
document.removeEventListener('fullscreenchange', this.handleFullscreenChange);
|
|
138
|
+
video.removeEventListener('leavepictureinpicture', this.handleLeavePictureInPicture);
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
init() {
|
|
142
|
+
const {
|
|
143
|
+
volume,
|
|
144
|
+
muted
|
|
145
|
+
} = this.getProps();
|
|
146
|
+
const video = this._adapter.getVideo();
|
|
147
|
+
if (video) {
|
|
148
|
+
this._adapter.setTotalTime(video.duration);
|
|
149
|
+
this.handleVolumeChange(muted ? 0 : volume);
|
|
150
|
+
}
|
|
151
|
+
this.registerEvent();
|
|
152
|
+
}
|
|
153
|
+
destroy() {
|
|
154
|
+
this.unregisterEvent();
|
|
155
|
+
this.clearTimer();
|
|
156
|
+
}
|
|
157
|
+
shouldShowControlItem(name) {
|
|
158
|
+
const {
|
|
159
|
+
controlsList
|
|
160
|
+
} = this.getProps();
|
|
161
|
+
if (controlsList.includes(name)) {
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
clearTimer() {
|
|
167
|
+
if (this.controlsTimer) {
|
|
168
|
+
clearTimeout(this.controlsTimer);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
handleTimeChange(value) {
|
|
172
|
+
const video = this._adapter.getVideo();
|
|
173
|
+
if (!video) return;
|
|
174
|
+
if (!Number.isNaN(value)) {
|
|
175
|
+
video.currentTime = value;
|
|
176
|
+
this._adapter.setCurrentTime(value);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
handleTimeUpdate() {
|
|
180
|
+
const video = this._adapter.getVideo();
|
|
181
|
+
if (!video) return;
|
|
182
|
+
this._adapter.setCurrentTime(video.currentTime);
|
|
183
|
+
}
|
|
184
|
+
handleDurationChange() {
|
|
185
|
+
const video = this._adapter.getVideo();
|
|
186
|
+
if (!video) return;
|
|
187
|
+
this._adapter.setTotalTime(video.duration);
|
|
188
|
+
}
|
|
189
|
+
handleError() {
|
|
190
|
+
this._adapter.setIsError(true);
|
|
191
|
+
}
|
|
192
|
+
handlePlayOrPause() {
|
|
193
|
+
const video = this._adapter.getVideo();
|
|
194
|
+
if (!video) return;
|
|
195
|
+
video.paused ? this.handlePlay() : this.handlePause();
|
|
196
|
+
}
|
|
197
|
+
handlePlay() {
|
|
198
|
+
const video = this._adapter.getVideo();
|
|
199
|
+
if (video) {
|
|
200
|
+
video.play();
|
|
201
|
+
this._adapter.setIsPlaying(true);
|
|
202
|
+
this._adapter.notifyPlay();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
handlePause() {
|
|
206
|
+
const video = this._adapter.getVideo();
|
|
207
|
+
if (video) {
|
|
208
|
+
video.pause();
|
|
209
|
+
this._adapter.setIsPlaying(false);
|
|
210
|
+
this._adapter.notifyPause();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
handleVolumeChange(value) {
|
|
214
|
+
const video = this._adapter.getVideo();
|
|
215
|
+
if (!video) return;
|
|
216
|
+
const volume = Math.floor(value > 0 ? value : 0);
|
|
217
|
+
video.volume = volume / 100;
|
|
218
|
+
this._adapter.setVolume(volume);
|
|
219
|
+
this._adapter.setMuted(volume === 0 ? true : false);
|
|
220
|
+
}
|
|
221
|
+
checkFullScreen() {
|
|
222
|
+
const videoWrapper = this._adapter.getVideoWrapper();
|
|
223
|
+
if (!videoWrapper) return false;
|
|
224
|
+
return !!(document.fullscreenElement === videoWrapper ||
|
|
225
|
+
// @ts-ignore
|
|
226
|
+
(document === null || document === void 0 ? void 0 : document.webkitFullscreenElement) === videoWrapper ||
|
|
227
|
+
// @ts-ignore
|
|
228
|
+
(document === null || document === void 0 ? void 0 : document.mozFullScreenElement) === videoWrapper ||
|
|
229
|
+
// @ts-ignore
|
|
230
|
+
(document === null || document === void 0 ? void 0 : document.msFullscreenElement) === videoWrapper || (
|
|
231
|
+
// @ts-ignore
|
|
232
|
+
videoWrapper === null || videoWrapper === void 0 ? void 0 : videoWrapper.webkitDisplayingFullscreen) // iOS Safari 特殊处理
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
handleRateChange(rate, locale) {
|
|
236
|
+
const video = this._adapter.getVideo();
|
|
237
|
+
if (!video) return;
|
|
238
|
+
video.playbackRate = rate.value;
|
|
239
|
+
this._adapter.setPlaybackRate(rate.value);
|
|
240
|
+
this._adapter.notifyRateChange(rate.value);
|
|
241
|
+
this.handleTemporaryNotification(locale.rateChange.replace('${rate}', rate.label));
|
|
242
|
+
}
|
|
243
|
+
handleQualityChange(quality, locale) {
|
|
244
|
+
this._adapter.setQuality(quality.value);
|
|
245
|
+
this._adapter.notifyQualityChange(quality.value);
|
|
246
|
+
this.handleTemporaryNotification(locale.qualityChange.replace('${quality}', quality.label));
|
|
247
|
+
this.restorePlayPosition();
|
|
248
|
+
}
|
|
249
|
+
handleRouteChange(route, locale) {
|
|
250
|
+
var _a, _b;
|
|
251
|
+
this._adapter.setRoute(route.value);
|
|
252
|
+
(_b = (_a = this._adapter).notifyRouteChange) === null || _b === void 0 ? void 0 : _b.call(_a, route.value);
|
|
253
|
+
this.handleTemporaryNotification(locale.routeChange.replace('${route}', route.label));
|
|
254
|
+
this.restorePlayPosition();
|
|
255
|
+
}
|
|
256
|
+
restorePlayPosition() {
|
|
257
|
+
const video = this._adapter.getVideo();
|
|
258
|
+
if (!video) return;
|
|
259
|
+
const wasPlaying = !video.paused;
|
|
260
|
+
const currentTime = video.currentTime;
|
|
261
|
+
const handleLoaded = () => {
|
|
262
|
+
video.currentTime = currentTime;
|
|
263
|
+
if (wasPlaying) {
|
|
264
|
+
video.play();
|
|
265
|
+
}
|
|
266
|
+
video.removeEventListener('loadeddata', handleLoaded);
|
|
267
|
+
};
|
|
268
|
+
video.addEventListener('loadeddata', handleLoaded);
|
|
269
|
+
}
|
|
270
|
+
handleBodyKeyDown(e) {
|
|
271
|
+
const {
|
|
272
|
+
currentTime,
|
|
273
|
+
volume
|
|
274
|
+
} = this.getStates();
|
|
275
|
+
const {
|
|
276
|
+
seekTime
|
|
277
|
+
} = this.getProps();
|
|
278
|
+
if (e.key === ' ') {
|
|
279
|
+
this.handlePlayOrPause();
|
|
280
|
+
// } else if (e.key === 'ArrowUp') {
|
|
281
|
+
// this.handleVolumeChange(volume + numbers.DEFAULT_VOLUME_STEP);
|
|
282
|
+
// } else if (e.key === 'ArrowDown') {
|
|
283
|
+
// this.handleVolumeChange(volume - numbers.DEFAULT_VOLUME_STEP);
|
|
284
|
+
} else if (e.key === 'ArrowLeft') {
|
|
285
|
+
this.handleTimeChange(currentTime - seekTime);
|
|
286
|
+
} else if (e.key === 'ArrowRight') {
|
|
287
|
+
this.handleTimeChange(currentTime + seekTime);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
exports.default = VideoPlayerFoundation;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import BaseFoundation, { DefaultAdapter } from '../base/foundation';
|
|
2
|
+
export interface MarkerListItem {
|
|
3
|
+
start: number;
|
|
4
|
+
end: number;
|
|
5
|
+
title: string;
|
|
6
|
+
width: string;
|
|
7
|
+
left: string;
|
|
8
|
+
}
|
|
9
|
+
export interface Marker {
|
|
10
|
+
start: number;
|
|
11
|
+
title: string;
|
|
12
|
+
}
|
|
13
|
+
export interface VideoProgressAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
|
|
14
|
+
getSliderRef: () => HTMLDivElement | null;
|
|
15
|
+
getMarkersList: () => MarkerListItem[];
|
|
16
|
+
setIsDragging: (isDragging: boolean) => void;
|
|
17
|
+
setIsHandleHovering: (isHandleHovering: boolean) => void;
|
|
18
|
+
setActiveIndex: (activeIndex: number) => void;
|
|
19
|
+
setMovingInfo: (movingInfo: {
|
|
20
|
+
progress: number;
|
|
21
|
+
offset: number;
|
|
22
|
+
value: number;
|
|
23
|
+
} | null) => void;
|
|
24
|
+
}
|
|
25
|
+
export default class VideoProgressFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<VideoProgressAdapter<P, S>, P, S> {
|
|
26
|
+
constructor(adapter: VideoProgressAdapter<P, S>);
|
|
27
|
+
handleDocumentMouseMove: (e: MouseEvent) => void;
|
|
28
|
+
handleDocumentMouseUp: () => void;
|
|
29
|
+
handleMouseDown: (e: any) => void;
|
|
30
|
+
handleMouseUp: () => void;
|
|
31
|
+
handleMouseEvent: (e: any, shouldSetValue?: boolean) => void;
|
|
32
|
+
handleSliderMouseEnter: (index: number) => void;
|
|
33
|
+
handleSliderMouseLeave: (index: number) => void;
|
|
34
|
+
setActiveIndex: (currentValue: number) => void;
|
|
35
|
+
getValueWidth: (marker: MarkerListItem, value: number) => string;
|
|
36
|
+
getPlayedWidth: (marker: MarkerListItem) => string;
|
|
37
|
+
getLoadedWidth: (marker: MarkerListItem) => string;
|
|
38
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _foundation = _interopRequireDefault(require("../base/foundation"));
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
class VideoProgressFoundation extends _foundation.default {
|
|
10
|
+
constructor(adapter) {
|
|
11
|
+
var _this;
|
|
12
|
+
super(Object.assign({}, adapter));
|
|
13
|
+
_this = this;
|
|
14
|
+
this.handleDocumentMouseMove = e => {
|
|
15
|
+
const {
|
|
16
|
+
isDragging
|
|
17
|
+
} = this.getStates();
|
|
18
|
+
if (isDragging) {
|
|
19
|
+
this.handleMouseEvent(e, true);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
this.handleDocumentMouseUp = () => {
|
|
23
|
+
const {
|
|
24
|
+
isDragging
|
|
25
|
+
} = this.getStates();
|
|
26
|
+
if (isDragging) {
|
|
27
|
+
this._adapter.setIsDragging(false);
|
|
28
|
+
}
|
|
29
|
+
document.removeEventListener('mousemove', this.handleDocumentMouseMove);
|
|
30
|
+
document.removeEventListener('mouseup', this.handleDocumentMouseUp);
|
|
31
|
+
};
|
|
32
|
+
this.handleMouseDown = e => {
|
|
33
|
+
this._adapter.setIsDragging(true);
|
|
34
|
+
this.handleMouseEvent(e, true);
|
|
35
|
+
document.addEventListener('mousemove', this.handleDocumentMouseMove);
|
|
36
|
+
document.addEventListener('mouseup', this.handleDocumentMouseUp);
|
|
37
|
+
};
|
|
38
|
+
this.handleMouseUp = () => {
|
|
39
|
+
const {
|
|
40
|
+
isDragging
|
|
41
|
+
} = this.getStates();
|
|
42
|
+
if (isDragging) {
|
|
43
|
+
this._adapter.setIsDragging(false);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
this.handleMouseEvent = function (e) {
|
|
47
|
+
let shouldSetValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
48
|
+
const {
|
|
49
|
+
isDragging
|
|
50
|
+
} = _this.getStates();
|
|
51
|
+
const {
|
|
52
|
+
onChange,
|
|
53
|
+
max
|
|
54
|
+
} = _this.getProps();
|
|
55
|
+
const sliderRef = _this._adapter.getSliderRef();
|
|
56
|
+
if (!sliderRef) return;
|
|
57
|
+
const rect = sliderRef.getBoundingClientRect();
|
|
58
|
+
const offset = e.clientX - rect.left;
|
|
59
|
+
const total = rect.width;
|
|
60
|
+
const percentage = Math.min(Math.max(offset / total, 0), 1);
|
|
61
|
+
const value = percentage * max;
|
|
62
|
+
if (shouldSetValue && (isDragging || e.type === 'mousedown')) {
|
|
63
|
+
_this.setActiveIndex(value);
|
|
64
|
+
onChange(value);
|
|
65
|
+
}
|
|
66
|
+
_this._adapter.setMovingInfo({
|
|
67
|
+
progress: percentage,
|
|
68
|
+
offset: offset - rect.width / 2,
|
|
69
|
+
value
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
this.handleSliderMouseEnter = index => {
|
|
73
|
+
const {
|
|
74
|
+
value: currentValue
|
|
75
|
+
} = this.getProps();
|
|
76
|
+
const markersList = this._adapter.getMarkersList();
|
|
77
|
+
const currentSlider = markersList[index];
|
|
78
|
+
if (currentSlider.start < currentValue && currentSlider.end > currentValue) {
|
|
79
|
+
this._adapter.setIsHandleHovering(true);
|
|
80
|
+
} else {
|
|
81
|
+
this._adapter.setIsHandleHovering(false);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
this.handleSliderMouseLeave = index => {
|
|
85
|
+
const {
|
|
86
|
+
value: currentValue
|
|
87
|
+
} = this.getProps();
|
|
88
|
+
const markersList = this._adapter.getMarkersList();
|
|
89
|
+
const currentSlider = markersList[index];
|
|
90
|
+
if (currentSlider.start < currentValue && currentSlider.end > currentValue) {
|
|
91
|
+
this._adapter.setIsHandleHovering(false);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
this.setActiveIndex = currentValue => {
|
|
95
|
+
const markersList = this._adapter.getMarkersList();
|
|
96
|
+
markersList.map((marker, index) => {
|
|
97
|
+
if (currentValue < marker.end && currentValue > marker.start) {
|
|
98
|
+
this._adapter.setIsHandleHovering(true);
|
|
99
|
+
this._adapter.setActiveIndex(index);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
this.getValueWidth = (marker, value) => {
|
|
104
|
+
const {
|
|
105
|
+
start,
|
|
106
|
+
end
|
|
107
|
+
} = marker;
|
|
108
|
+
if (value > end) {
|
|
109
|
+
return 'calc(100% - 2px)';
|
|
110
|
+
} else if (value < start) {
|
|
111
|
+
return '0%';
|
|
112
|
+
} else {
|
|
113
|
+
return `${(value - start) / (end - start) * 100}%`;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
// Get the width of the video being played
|
|
117
|
+
this.getPlayedWidth = marker => {
|
|
118
|
+
const {
|
|
119
|
+
value: currentValue
|
|
120
|
+
} = this.getProps();
|
|
121
|
+
return this.getValueWidth(marker, currentValue);
|
|
122
|
+
};
|
|
123
|
+
this.getLoadedWidth = marker => {
|
|
124
|
+
const {
|
|
125
|
+
bufferedValue
|
|
126
|
+
} = this.getProps();
|
|
127
|
+
return this.getValueWidth(marker, bufferedValue);
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
exports.default = VideoProgressFoundation;
|