tuikit-atomicx-vue3 3.3.1 → 3.3.2
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/ChatSetting/GroupChatSetting/GroupActions/GroupActions.js +1 -4
- package/dist/components/ChatSetting/GroupChatSetting/GroupChatSetting.js +1 -2
- package/dist/components/ChatSetting/GroupChatSetting/GroupManagement/GroupManagement.js +1 -2
- package/dist/components/CoGuestPanel/CoGuestPanel.js +6 -6
- package/dist/components/ContactList/ContactInfo/GroupInfo/GroupInfo.js +1 -2
- package/dist/components/ConversationList/ConversationCreate/ConversationCreate.js +1 -2
- package/dist/components/ConversationList/ConversationSearch/ConversationSearch.js +0 -1
- package/dist/components/LiveCoreView/PlayerControl/AudioControl.js +252 -0
- package/dist/components/LiveCoreView/PlayerControl/AudioControl.vue.d.ts +38 -0
- package/dist/components/LiveCoreView/PlayerControl/PlayerControl.js +279 -0
- package/dist/components/LiveCoreView/PlayerControl/PlayerControl.vue.d.ts +15 -0
- package/dist/components/LiveCoreView/PlayerControl/PlayerControlState.d.ts +29 -0
- package/dist/components/LiveCoreView/PlayerControl/PlayerControlState.js +412 -0
- package/dist/components/LiveCoreView/PlayerControl/index.d.ts +3 -0
- package/dist/components/LiveCoreView/PlayerControl/index.js +8 -0
- package/dist/components/LiveCoreView/PlayerControl/utils/deviceDetection.d.ts +85 -0
- package/dist/components/LiveCoreView/PlayerControl/utils/deviceDetection.js +129 -0
- package/dist/components/LiveCoreView/PlayerControl/utils/domHelpers.d.ts +75 -0
- package/dist/components/LiveCoreView/PlayerControl/utils/domHelpers.js +120 -0
- package/dist/components/LiveCoreView/PlayerControl/utils/fullscreenManager.d.ts +120 -0
- package/dist/components/LiveCoreView/PlayerControl/utils/fullscreenManager.js +311 -0
- package/dist/components/LiveCoreView/i18n/en-US/index.d.ts +9 -0
- package/dist/components/LiveCoreView/i18n/en-US/index.js +10 -1
- package/dist/components/LiveCoreView/i18n/zh-CN/index.d.ts +9 -0
- package/dist/components/LiveCoreView/i18n/zh-CN/index.js +10 -1
- package/dist/components/LiveCoreView/index.js +30 -4
- package/dist/components/StreamView/Layout/CustomLayout.js +2 -2
- package/dist/components/StreamView/Layout/GridLayout.js +2 -2
- package/dist/components/StreamView/common/StreamList/index.js +2 -2
- package/dist/styles/index.css +336 -31
- package/package.json +3 -3
- package/src/components/ChatSetting/GroupChatSetting/GroupActions/GroupActions.vue +0 -3
- package/src/components/ChatSetting/GroupChatSetting/GroupChatSetting.vue +0 -1
- package/src/components/ChatSetting/GroupChatSetting/GroupManagement/GroupManagement.vue +0 -1
- package/src/components/ContactList/ContactInfo/GroupInfo/GroupInfo.vue +0 -1
- package/src/components/ConversationList/ConversationCreate/ConversationCreate.vue +0 -1
- package/src/components/ConversationList/ConversationSearch/ConversationSearch.vue +0 -1
- package/src/components/LiveCoreView/PlayerControl/AudioControl.vue +434 -0
- package/src/components/LiveCoreView/PlayerControl/PlayerControl.module.scss +52 -0
- package/src/components/LiveCoreView/PlayerControl/PlayerControl.vue +484 -0
- package/src/components/LiveCoreView/PlayerControl/PlayerControlState.ts +602 -0
- package/src/components/LiveCoreView/PlayerControl/index.ts +3 -0
- package/src/components/LiveCoreView/PlayerControl/utils/deviceDetection.ts +234 -0
- package/src/components/LiveCoreView/PlayerControl/utils/domHelpers.ts +145 -0
- package/src/components/LiveCoreView/PlayerControl/utils/fullscreenManager.ts +417 -0
- package/src/components/LiveCoreView/i18n/en-US/index.ts +9 -0
- package/src/components/LiveCoreView/i18n/zh-CN/index.ts +9 -0
- package/src/components/LiveCoreView/index.vue +14 -3
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import AudioControl from "./AudioControl.js";
|
|
2
|
+
import { defineComponent, ref, onMounted, onBeforeUnmount, createBlock, openBlock, Transition, withCtx, withDirectives, createElementVNode, normalizeClass, unref, createVNode, vShow } from "vue";
|
|
3
|
+
import { useUIKit, IconPause, IconPlay, IconPictureInPicture, IconFullScreen, TUIToast, TOAST_TYPE } from "@tencentcloud/uikit-base-component-vue3";
|
|
4
|
+
import { usePlayerControlState } from "./PlayerControlState.js";
|
|
5
|
+
import { isSafariBrowser, isFirefoxBrowser } from "./utils/deviceDetection.js";
|
|
6
|
+
import { isMobile } from "../../../utils/env.js";
|
|
7
|
+
import { _ as _export_sfc } from "../../../_plugin-vue_export-helper-1tPrXgE0.js";
|
|
8
|
+
const _hoisted_1 = { class: "control-buttons" };
|
|
9
|
+
const _hoisted_2 = ["title"];
|
|
10
|
+
const _hoisted_3 = { class: "right-controls" };
|
|
11
|
+
const _hoisted_4 = { class: "control-btn audio-control-btn" };
|
|
12
|
+
const _hoisted_5 = ["title"];
|
|
13
|
+
const _hoisted_6 = ["title"];
|
|
14
|
+
const AUTO_HIDE_DELAY = 3e3;
|
|
15
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
16
|
+
__name: "PlayerControl",
|
|
17
|
+
props: {
|
|
18
|
+
isLandscapeStyleMode: { type: Boolean }
|
|
19
|
+
},
|
|
20
|
+
setup(__props) {
|
|
21
|
+
const {
|
|
22
|
+
isPlaying,
|
|
23
|
+
isFullscreen,
|
|
24
|
+
isPictureInPicture,
|
|
25
|
+
pause,
|
|
26
|
+
resume,
|
|
27
|
+
requestPictureInPicture,
|
|
28
|
+
exitPictureInPicture,
|
|
29
|
+
requestFullscreen,
|
|
30
|
+
exitFullscreen,
|
|
31
|
+
setVolume,
|
|
32
|
+
cleanup
|
|
33
|
+
} = usePlayerControlState();
|
|
34
|
+
const props = __props;
|
|
35
|
+
const { t } = useUIKit();
|
|
36
|
+
const currentVolume = ref(1);
|
|
37
|
+
const isMuted = ref(false);
|
|
38
|
+
const playerControlRef = ref();
|
|
39
|
+
const showControls = ref(false);
|
|
40
|
+
const hideTimeout = ref(null);
|
|
41
|
+
const isEnableVolumeControl = () => {
|
|
42
|
+
if (!isMobile) return true;
|
|
43
|
+
if (isSafariBrowser()) return false;
|
|
44
|
+
if (isFirefoxBrowser()) return false;
|
|
45
|
+
return true;
|
|
46
|
+
};
|
|
47
|
+
const handlePlayPause = () => {
|
|
48
|
+
if (isPlaying.value) {
|
|
49
|
+
pause();
|
|
50
|
+
} else {
|
|
51
|
+
resume();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const handlePictureInPicture = async () => {
|
|
55
|
+
let flag = false;
|
|
56
|
+
if (isPictureInPicture.value) {
|
|
57
|
+
flag = await exitPictureInPicture();
|
|
58
|
+
} else {
|
|
59
|
+
flag = await requestPictureInPicture();
|
|
60
|
+
}
|
|
61
|
+
if (!flag) {
|
|
62
|
+
TUIToast({
|
|
63
|
+
type: TOAST_TYPE.ERROR,
|
|
64
|
+
message: t("The system does not support picture-in-picture mode")
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const handleFullscreen = () => {
|
|
69
|
+
console.log("handleFullscreen");
|
|
70
|
+
if (isFullscreen.value) {
|
|
71
|
+
exitFullscreen();
|
|
72
|
+
} else {
|
|
73
|
+
requestFullscreen();
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const handleVolumeChange = async (volume) => {
|
|
77
|
+
currentVolume.value = volume;
|
|
78
|
+
if (isMobile) {
|
|
79
|
+
startAutoHideControl();
|
|
80
|
+
}
|
|
81
|
+
await setVolume(volume);
|
|
82
|
+
};
|
|
83
|
+
const startAutoHideControl = () => {
|
|
84
|
+
stopAutoHideControl();
|
|
85
|
+
hideTimeout.value = window.setTimeout(() => {
|
|
86
|
+
showControls.value = false;
|
|
87
|
+
hideTimeout.value = null;
|
|
88
|
+
}, AUTO_HIDE_DELAY);
|
|
89
|
+
};
|
|
90
|
+
const stopAutoHideControl = () => {
|
|
91
|
+
if (hideTimeout.value) {
|
|
92
|
+
clearTimeout(hideTimeout.value);
|
|
93
|
+
hideTimeout.value = null;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const handleMouseEnter = () => {
|
|
97
|
+
stopAutoHideControl();
|
|
98
|
+
showControls.value = true;
|
|
99
|
+
};
|
|
100
|
+
const handleMouseLeave = () => {
|
|
101
|
+
startAutoHideControl();
|
|
102
|
+
};
|
|
103
|
+
const setupParentMouseListener = () => {
|
|
104
|
+
if (!isMobile && playerControlRef.value) {
|
|
105
|
+
const parentElement = playerControlRef.value.parentElement;
|
|
106
|
+
if (parentElement) {
|
|
107
|
+
parentElement.addEventListener("mouseenter", handleMouseEnter);
|
|
108
|
+
parentElement.addEventListener("mouseleave", handleMouseLeave);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
const removeParentMouseListener = () => {
|
|
113
|
+
if (!isMobile && playerControlRef.value) {
|
|
114
|
+
const parentElement = playerControlRef.value.parentElement;
|
|
115
|
+
if (parentElement) {
|
|
116
|
+
parentElement.removeEventListener("mouseenter", handleMouseEnter);
|
|
117
|
+
parentElement.removeEventListener("mouseleave", handleMouseLeave);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
const touchStartCoords = ref(null);
|
|
122
|
+
const calculateTouchDistance = (start, end) => {
|
|
123
|
+
return Math.sqrt(Math.pow(end.clientX - start.x, 2) + Math.pow(end.clientY - start.y, 2));
|
|
124
|
+
};
|
|
125
|
+
const isPlayerControlTarget = (target) => {
|
|
126
|
+
var _a;
|
|
127
|
+
return ((_a = playerControlRef.value) == null ? void 0 : _a.contains(target)) || false;
|
|
128
|
+
};
|
|
129
|
+
const isLiveCoreViewTarget = (target) => {
|
|
130
|
+
const container = document.getElementById("live-core-view-container");
|
|
131
|
+
return (container == null ? void 0 : container.contains(target)) || false;
|
|
132
|
+
};
|
|
133
|
+
const handlePlayerControlTouch = () => {
|
|
134
|
+
stopAutoHideControl();
|
|
135
|
+
startAutoHideControl();
|
|
136
|
+
};
|
|
137
|
+
const handleLiveCoreViewTouch = () => {
|
|
138
|
+
showControls.value = !showControls.value;
|
|
139
|
+
if (showControls.value) {
|
|
140
|
+
startAutoHideControl();
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
const handleScreenTouchStart = (event) => {
|
|
144
|
+
if (event.touches.length === 1) {
|
|
145
|
+
const touch = event.touches[0];
|
|
146
|
+
touchStartCoords.value = {
|
|
147
|
+
x: touch.clientX,
|
|
148
|
+
y: touch.clientY
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
const handleScreenTouchMove = (event) => {
|
|
153
|
+
if (playerControlRef.value && playerControlRef.value.contains(event.target)) {
|
|
154
|
+
stopAutoHideControl();
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
const handleScreenTouchEnd = (event) => {
|
|
159
|
+
if (!touchStartCoords.value) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const touchEnd = event.changedTouches[0];
|
|
163
|
+
const distance = calculateTouchDistance(touchStartCoords.value, touchEnd);
|
|
164
|
+
const MAX_CLICK_DISTANCE = 20;
|
|
165
|
+
if (distance > MAX_CLICK_DISTANCE) {
|
|
166
|
+
touchStartCoords.value = null;
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const target = event.target;
|
|
170
|
+
if (isPlayerControlTarget(target)) {
|
|
171
|
+
handlePlayerControlTouch();
|
|
172
|
+
} else if (isLiveCoreViewTarget(target)) {
|
|
173
|
+
handleLiveCoreViewTouch();
|
|
174
|
+
} else {
|
|
175
|
+
showControls.value = false;
|
|
176
|
+
}
|
|
177
|
+
touchStartCoords.value = null;
|
|
178
|
+
};
|
|
179
|
+
const setupTouchEventListeners = () => {
|
|
180
|
+
if (isMobile) {
|
|
181
|
+
document.addEventListener("touchstart", handleScreenTouchStart, true);
|
|
182
|
+
document.addEventListener("touchmove", handleScreenTouchMove, true);
|
|
183
|
+
document.addEventListener("touchend", handleScreenTouchEnd, true);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
const removeTouchEventListeners = () => {
|
|
187
|
+
if (isMobile) {
|
|
188
|
+
document.removeEventListener("touchstart", handleScreenTouchStart, true);
|
|
189
|
+
document.removeEventListener("touchmove", handleScreenTouchMove, true);
|
|
190
|
+
document.removeEventListener("touchend", handleScreenTouchEnd, true);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
const handleMutedChange = async (muted) => {
|
|
194
|
+
isMuted.value = muted;
|
|
195
|
+
if (muted) {
|
|
196
|
+
await setVolume(0);
|
|
197
|
+
} else {
|
|
198
|
+
await setVolume(currentVolume.value);
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
const cleanupEventListeners = () => {
|
|
202
|
+
removeTouchEventListeners();
|
|
203
|
+
removeParentMouseListener();
|
|
204
|
+
stopAutoHideControl();
|
|
205
|
+
};
|
|
206
|
+
onMounted(() => {
|
|
207
|
+
setupTouchEventListeners();
|
|
208
|
+
setupParentMouseListener();
|
|
209
|
+
});
|
|
210
|
+
onBeforeUnmount(() => {
|
|
211
|
+
cleanupEventListeners();
|
|
212
|
+
cleanup();
|
|
213
|
+
});
|
|
214
|
+
return (_ctx, _cache) => {
|
|
215
|
+
return openBlock(), createBlock(Transition, { name: "player-control" }, {
|
|
216
|
+
default: withCtx(() => [
|
|
217
|
+
withDirectives(createElementVNode("div", {
|
|
218
|
+
ref_key: "playerControlRef",
|
|
219
|
+
ref: playerControlRef,
|
|
220
|
+
class: normalizeClass([
|
|
221
|
+
"playback-controls",
|
|
222
|
+
unref(isMobile) ? "mobile-mode" : "pc-mode",
|
|
223
|
+
{ "mobile-landscape-mode": props.isLandscapeStyleMode }
|
|
224
|
+
])
|
|
225
|
+
}, [
|
|
226
|
+
createElementVNode("div", _hoisted_1, [
|
|
227
|
+
createElementVNode("span", {
|
|
228
|
+
class: "control-btn play-pause-btn",
|
|
229
|
+
title: unref(isPlaying) ? unref(t)("Pause") : unref(t)("Play"),
|
|
230
|
+
onClick: handlePlayPause
|
|
231
|
+
}, [
|
|
232
|
+
unref(isPlaying) ? (openBlock(), createBlock(unref(IconPause), {
|
|
233
|
+
key: 0,
|
|
234
|
+
size: "20"
|
|
235
|
+
})) : (openBlock(), createBlock(unref(IconPlay), {
|
|
236
|
+
key: 1,
|
|
237
|
+
size: "20"
|
|
238
|
+
}))
|
|
239
|
+
], 8, _hoisted_2),
|
|
240
|
+
_cache[0] || (_cache[0] = createElementVNode("div", { class: "center-controls" }, null, -1)),
|
|
241
|
+
createElementVNode("div", _hoisted_3, [
|
|
242
|
+
createElementVNode("span", _hoisted_4, [
|
|
243
|
+
createVNode(AudioControl, {
|
|
244
|
+
class: "audio-control-icon",
|
|
245
|
+
"icon-size": 20,
|
|
246
|
+
"enable-volume-control": isEnableVolumeControl(),
|
|
247
|
+
onVolumeChange: handleVolumeChange,
|
|
248
|
+
onMutedChange: handleMutedChange
|
|
249
|
+
}, null, 8, ["enable-volume-control"])
|
|
250
|
+
]),
|
|
251
|
+
createElementVNode("span", {
|
|
252
|
+
class: "control-btn",
|
|
253
|
+
title: unref(isPictureInPicture) ? unref(t)("Exit Picture in Picture") : unref(t)("Picture in Picture"),
|
|
254
|
+
onClick: handlePictureInPicture
|
|
255
|
+
}, [
|
|
256
|
+
createVNode(unref(IconPictureInPicture), { size: "20" })
|
|
257
|
+
], 8, _hoisted_5),
|
|
258
|
+
createElementVNode("span", {
|
|
259
|
+
class: "control-btn fullscreen-btn",
|
|
260
|
+
title: unref(isFullscreen) ? unref(t)("Exit Fullscreen") : unref(t)("Fullscreen"),
|
|
261
|
+
onClick: handleFullscreen
|
|
262
|
+
}, [
|
|
263
|
+
createVNode(unref(IconFullScreen), { size: "20" })
|
|
264
|
+
], 8, _hoisted_6)
|
|
265
|
+
])
|
|
266
|
+
])
|
|
267
|
+
], 2), [
|
|
268
|
+
[vShow, showControls.value]
|
|
269
|
+
])
|
|
270
|
+
]),
|
|
271
|
+
_: 1
|
|
272
|
+
});
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
const PlayerControl = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-28ed6eb9"]]);
|
|
277
|
+
export {
|
|
278
|
+
PlayerControl as default
|
|
279
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
declare const _default: import('vue').DefineComponent<import('vue').ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
|
|
2
|
+
isLandscapeStyleMode?: boolean;
|
|
3
|
+
}>>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
|
|
4
|
+
isLandscapeStyleMode?: boolean;
|
|
5
|
+
}>>> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
|
|
6
|
+
export default _default;
|
|
7
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
8
|
+
type __VLS_TypePropsToRuntimeProps<T> = {
|
|
9
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
10
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
11
|
+
} : {
|
|
12
|
+
type: import('vue').PropType<T[K]>;
|
|
13
|
+
required: true;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
import { FullscreenResult } from './utils/fullscreenManager';
|
|
3
|
+
|
|
4
|
+
export declare enum FillMode {
|
|
5
|
+
CONTAIN = "contain",
|
|
6
|
+
COVER = "cover",
|
|
7
|
+
FILL = "fill"
|
|
8
|
+
}
|
|
9
|
+
export interface PlayerControlState {
|
|
10
|
+
isPlaying: Ref<boolean>;
|
|
11
|
+
currentFillMode: Ref<FillMode>;
|
|
12
|
+
isFullscreen: Ref<boolean>;
|
|
13
|
+
isLandscapeStyleMode: Ref<boolean>;
|
|
14
|
+
isPictureInPicture: Ref<boolean>;
|
|
15
|
+
currentVolume: Ref<number>;
|
|
16
|
+
resume: () => Promise<boolean>;
|
|
17
|
+
pause: () => Promise<boolean>;
|
|
18
|
+
requestFullscreen: () => Promise<FullscreenResult>;
|
|
19
|
+
exitFullscreen: () => Promise<FullscreenResult>;
|
|
20
|
+
requestPictureInPicture: () => Promise<boolean>;
|
|
21
|
+
exitPictureInPicture: () => Promise<boolean>;
|
|
22
|
+
setVolume: (volume: number) => Promise<boolean>;
|
|
23
|
+
changeFillMode: (fillMode: FillMode) => Promise<boolean>;
|
|
24
|
+
cleanup: () => void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Player control state management hook
|
|
28
|
+
*/
|
|
29
|
+
export declare function usePlayerControlState(): PlayerControlState;
|