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.
Files changed (48) hide show
  1. package/dist/components/ChatSetting/GroupChatSetting/GroupActions/GroupActions.js +1 -4
  2. package/dist/components/ChatSetting/GroupChatSetting/GroupChatSetting.js +1 -2
  3. package/dist/components/ChatSetting/GroupChatSetting/GroupManagement/GroupManagement.js +1 -2
  4. package/dist/components/CoGuestPanel/CoGuestPanel.js +6 -6
  5. package/dist/components/ContactList/ContactInfo/GroupInfo/GroupInfo.js +1 -2
  6. package/dist/components/ConversationList/ConversationCreate/ConversationCreate.js +1 -2
  7. package/dist/components/ConversationList/ConversationSearch/ConversationSearch.js +0 -1
  8. package/dist/components/LiveCoreView/PlayerControl/AudioControl.js +252 -0
  9. package/dist/components/LiveCoreView/PlayerControl/AudioControl.vue.d.ts +38 -0
  10. package/dist/components/LiveCoreView/PlayerControl/PlayerControl.js +279 -0
  11. package/dist/components/LiveCoreView/PlayerControl/PlayerControl.vue.d.ts +15 -0
  12. package/dist/components/LiveCoreView/PlayerControl/PlayerControlState.d.ts +29 -0
  13. package/dist/components/LiveCoreView/PlayerControl/PlayerControlState.js +412 -0
  14. package/dist/components/LiveCoreView/PlayerControl/index.d.ts +3 -0
  15. package/dist/components/LiveCoreView/PlayerControl/index.js +8 -0
  16. package/dist/components/LiveCoreView/PlayerControl/utils/deviceDetection.d.ts +85 -0
  17. package/dist/components/LiveCoreView/PlayerControl/utils/deviceDetection.js +129 -0
  18. package/dist/components/LiveCoreView/PlayerControl/utils/domHelpers.d.ts +75 -0
  19. package/dist/components/LiveCoreView/PlayerControl/utils/domHelpers.js +120 -0
  20. package/dist/components/LiveCoreView/PlayerControl/utils/fullscreenManager.d.ts +120 -0
  21. package/dist/components/LiveCoreView/PlayerControl/utils/fullscreenManager.js +311 -0
  22. package/dist/components/LiveCoreView/i18n/en-US/index.d.ts +9 -0
  23. package/dist/components/LiveCoreView/i18n/en-US/index.js +10 -1
  24. package/dist/components/LiveCoreView/i18n/zh-CN/index.d.ts +9 -0
  25. package/dist/components/LiveCoreView/i18n/zh-CN/index.js +10 -1
  26. package/dist/components/LiveCoreView/index.js +30 -4
  27. package/dist/components/StreamView/Layout/CustomLayout.js +2 -2
  28. package/dist/components/StreamView/Layout/GridLayout.js +2 -2
  29. package/dist/components/StreamView/common/StreamList/index.js +2 -2
  30. package/dist/styles/index.css +336 -31
  31. package/package.json +3 -3
  32. package/src/components/ChatSetting/GroupChatSetting/GroupActions/GroupActions.vue +0 -3
  33. package/src/components/ChatSetting/GroupChatSetting/GroupChatSetting.vue +0 -1
  34. package/src/components/ChatSetting/GroupChatSetting/GroupManagement/GroupManagement.vue +0 -1
  35. package/src/components/ContactList/ContactInfo/GroupInfo/GroupInfo.vue +0 -1
  36. package/src/components/ConversationList/ConversationCreate/ConversationCreate.vue +0 -1
  37. package/src/components/ConversationList/ConversationSearch/ConversationSearch.vue +0 -1
  38. package/src/components/LiveCoreView/PlayerControl/AudioControl.vue +434 -0
  39. package/src/components/LiveCoreView/PlayerControl/PlayerControl.module.scss +52 -0
  40. package/src/components/LiveCoreView/PlayerControl/PlayerControl.vue +484 -0
  41. package/src/components/LiveCoreView/PlayerControl/PlayerControlState.ts +602 -0
  42. package/src/components/LiveCoreView/PlayerControl/index.ts +3 -0
  43. package/src/components/LiveCoreView/PlayerControl/utils/deviceDetection.ts +234 -0
  44. package/src/components/LiveCoreView/PlayerControl/utils/domHelpers.ts +145 -0
  45. package/src/components/LiveCoreView/PlayerControl/utils/fullscreenManager.ts +417 -0
  46. package/src/components/LiveCoreView/i18n/en-US/index.ts +9 -0
  47. package/src/components/LiveCoreView/i18n/zh-CN/index.ts +9 -0
  48. package/src/components/LiveCoreView/index.vue +14 -3
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Device detection utility module
3
+ */
4
+
5
+ // Device type enum
6
+ export enum DeviceType {
7
+ DESKTOP = 'desktop',
8
+ MOBILE = 'mobile',
9
+ IOS = 'ios',
10
+ ANDROID = 'android',
11
+ }
12
+
13
+ // Device capabilities interface
14
+ export interface DeviceCapabilities {
15
+ supportsFullscreen: boolean;
16
+ supportsOrientation: boolean;
17
+ supportsPictureInPicture: boolean;
18
+ deviceType: DeviceType;
19
+ }
20
+
21
+ /**
22
+ * Detect if it's a mobile device
23
+ */
24
+ export const isMobileDevice = (): boolean => {
25
+ return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
26
+ };
27
+
28
+ /**
29
+ * Detect if it's an iOS device
30
+ */
31
+ export const isIOSDevice = (): boolean => {
32
+ return /iPad|iPhone|iPod/.test(navigator.userAgent);
33
+ };
34
+
35
+ /**
36
+ * Detect if it's an Android device
37
+ */
38
+ export const isAndroidDevice = (): boolean => {
39
+ return /Android/i.test(navigator.userAgent);
40
+ };
41
+
42
+ /**
43
+ * Detect if it's a Safari browser
44
+ */
45
+ export const isSafariBrowser = (): boolean => {
46
+ // Safari has several unique features
47
+ const isSafari =
48
+ // Check the vendor feature
49
+ navigator.vendor && navigator.vendor.includes('Apple') &&
50
+ // Check specific apis or behaviors unique to Safari
51
+ !navigator.userAgent.includes('CriOS') && // Exclude Chrome iOS
52
+ !navigator.userAgent.includes('FxiOS') && // Exclude Firefox iOS
53
+ // Additional feature checks
54
+ (typeof safari !== 'undefined' ||
55
+ !('netscape' in window) || // Firefox has netscape objects
56
+ document.documentMode === undefined); // Exclude IE
57
+
58
+ return !!isSafari;
59
+ }
60
+
61
+ /**
62
+ * Detect if it's a Firefox browser
63
+ */
64
+ export const isFirefoxBrowser = (): boolean => {
65
+ // The unique features of Firefox
66
+ return typeof InstallTrigger !== 'undefined' ||
67
+ navigator.userAgent.includes('Firefox') ||
68
+ navigator.userAgent.includes('Gecko/');
69
+ }
70
+
71
+ /**
72
+ * Get device type
73
+ */
74
+ export const getDeviceType = (): DeviceType => {
75
+ if (isIOSDevice()) return DeviceType.IOS;
76
+ if (isAndroidDevice()) return DeviceType.ANDROID;
77
+ if (isMobileDevice()) return DeviceType.MOBILE;
78
+ return DeviceType.DESKTOP;
79
+ };
80
+
81
+ /**
82
+ * Detect if device supports screen orientation control
83
+ */
84
+ export const isOrientationSupported = (): boolean => {
85
+ return !!(screen.orientation && (screen.orientation as any).lock);
86
+ };
87
+
88
+ /**
89
+ * Get current screen orientation
90
+ */
91
+ export const getCurrentOrientation = (): 'portrait' | 'landscape' | 'unknown' => {
92
+ // First try the standard Screen Orientation API
93
+ if (screen.orientation) {
94
+ const angle = screen.orientation.angle;
95
+ const type = screen.orientation.type;
96
+
97
+ // Check orientation type first (more reliable)
98
+ if (type.includes('portrait')) {
99
+ return 'portrait';
100
+ } else if (type.includes('landscape')) {
101
+ return 'landscape';
102
+ }
103
+
104
+ // Fallback to angle-based detection
105
+ if (angle === 0 || angle === 180) {
106
+ return 'portrait';
107
+ } else if (angle === 90 || angle === 270) {
108
+ return 'landscape';
109
+ }
110
+ }
111
+
112
+ // Fallback to window dimensions
113
+ if (window.innerHeight > window.innerWidth) {
114
+ return 'portrait';
115
+ } else if (window.innerWidth > window.innerHeight) {
116
+ return 'landscape';
117
+ }
118
+
119
+ return 'unknown';
120
+ };
121
+
122
+ /**
123
+ * Check if device is currently in portrait orientation
124
+ */
125
+ export const isCurrentlyPortrait = (): boolean => {
126
+ return getCurrentOrientation() === 'portrait';
127
+ };
128
+
129
+ /**
130
+ * Check if device is currently in landscape orientation
131
+ */
132
+ export const isCurrentlyLandscape = (): boolean => {
133
+ return getCurrentOrientation() === 'landscape';
134
+ };
135
+
136
+ /**
137
+ * Determine if device should rotate to landscape for fullscreen
138
+ * @param deviceType - The type of device
139
+ * @param isLandscapeStream - Whether the stream is landscape oriented
140
+ * @returns Whether the device should rotate to landscape
141
+ */
142
+ export const shouldRotateToLandscapeForFullscreen = (
143
+ deviceType: DeviceType,
144
+ isLandscapeStream: boolean
145
+ ): boolean => {
146
+ // Only mobile devices can/should rotate
147
+ if (deviceType === DeviceType.DESKTOP) {
148
+ return false;
149
+ }
150
+
151
+ // Only rotate for landscape streams
152
+ if (!isLandscapeStream) {
153
+ return false;
154
+ }
155
+
156
+ // Only rotate if currently in portrait
157
+ if (!isCurrentlyPortrait()) {
158
+ return false;
159
+ }
160
+
161
+ return true;
162
+ };
163
+
164
+ /**
165
+ * Determine if device had landscape rotation that should be undone
166
+ * @param deviceType - The type of device
167
+ * @param isLandscapeStream - Whether the stream is landscape oriented
168
+ * @returns Whether the device had landscape rotation that should be undone
169
+ */
170
+ export const hadLandscapeRotationToUndo = (
171
+ deviceType: DeviceType,
172
+ isLandscapeStream: boolean
173
+ ): boolean => {
174
+ // Only mobile devices can have had rotation
175
+ if (deviceType === DeviceType.DESKTOP) {
176
+ return false;
177
+ }
178
+
179
+ // Only relevant for landscape streams
180
+ if (!isLandscapeStream) {
181
+ return false;
182
+ }
183
+
184
+ // Only if currently in landscape (meaning we probably rotated from portrait)
185
+ if (!isCurrentlyLandscape()) {
186
+ return false;
187
+ }
188
+
189
+ return true;
190
+ };
191
+
192
+ /**
193
+ * Detect if fullscreen API is supported
194
+ */
195
+ export const isFullscreenSupported = (element: HTMLElement): boolean => {
196
+ return !!(
197
+ element.requestFullscreen ||
198
+ (element as any).webkitRequestFullscreen ||
199
+ (element as any).mozRequestFullScreen ||
200
+ (element as any).msRequestFullscreen
201
+ );
202
+ };
203
+
204
+ /**
205
+ * Detect if exit fullscreen API is supported
206
+ */
207
+ export const isExitFullscreenSupported = (): boolean => {
208
+ return !!(
209
+ document.exitFullscreen ||
210
+ (document as any).webkitExitFullscreen ||
211
+ (document as any).mozCancelFullScreen ||
212
+ (document as any).msExitFullscreen
213
+ );
214
+ };
215
+
216
+ /**
217
+ * Detect if picture-in-picture is supported
218
+ */
219
+ export const isPictureInPictureSupported = (video?: HTMLVideoElement): boolean => {
220
+ if (!video) return false;
221
+ return typeof video.requestPictureInPicture === 'function' && typeof document.exitPictureInPicture === 'function';
222
+ };
223
+
224
+ /**
225
+ * Get complete device capabilities information
226
+ */
227
+ export const getDeviceCapabilities = (element?: HTMLElement): DeviceCapabilities => {
228
+ return {
229
+ supportsFullscreen: element ? isFullscreenSupported(element) : false,
230
+ supportsOrientation: isOrientationSupported(),
231
+ supportsPictureInPicture: isPictureInPictureSupported(),
232
+ deviceType: getDeviceType(),
233
+ };
234
+ };
@@ -0,0 +1,145 @@
1
+ /**
2
+ * DOM operation helper utility module
3
+ */
4
+
5
+ // DOM selector constants
6
+ export const DOM_SELECTORS = {
7
+ LIVE_CORE_VIEW_CONTAINER: '.live-core-view-container',
8
+ LIVE_CORE_VIEW: '.live-core-view',
9
+ VIDEO_ELEMENT: '#atomicx-live-stream-content video',
10
+ TCPLAYER_ELEMENT: '.tcplayer',
11
+ };
12
+
13
+ /**
14
+ * DOM element getter
15
+ */
16
+ export class DOMElementGetter {
17
+ /**
18
+ * Get live-core-view-container element
19
+ */
20
+ static getLiveCoreViewContainer(): HTMLElement | null {
21
+ return document.querySelector(DOM_SELECTORS.LIVE_CORE_VIEW_CONTAINER);
22
+ }
23
+
24
+ /**
25
+ * Get live-core-view element
26
+ */
27
+ static getLiveCoreView(): HTMLElement | null {
28
+ return document.querySelector(DOM_SELECTORS.LIVE_CORE_VIEW);
29
+ }
30
+
31
+ /**
32
+ * Get video element
33
+ */
34
+ static getVideoElement(): HTMLVideoElement | null {
35
+ return document.querySelector(DOM_SELECTORS.VIDEO_ELEMENT);
36
+ }
37
+
38
+ /**
39
+ * Get all required DOM elements
40
+ */
41
+ static getAllElements(): {
42
+ container: HTMLElement | null;
43
+ view: HTMLElement | null;
44
+ video: HTMLVideoElement | null;
45
+ } {
46
+ return {
47
+ container: DOMElementGetter.getLiveCoreViewContainer(),
48
+ view: DOMElementGetter.getLiveCoreView(),
49
+ video: DOMElementGetter.getVideoElement(),
50
+ };
51
+ }
52
+
53
+ /**
54
+ * Check if tcplayer element exists in live-core-view-container
55
+ */
56
+ static hasTcPlayerElement(): boolean {
57
+ const container = DOMElementGetter.getLiveCoreViewContainer();
58
+ if (!container) {
59
+ return false;
60
+ }
61
+ return container.querySelector(DOM_SELECTORS.TCPLAYER_ELEMENT) !== null;
62
+ }
63
+
64
+ /**
65
+ * Get tcplayer element from live-core-view-container
66
+ */
67
+ static getTcPlayerElement(): HTMLElement | null {
68
+ const container = DOMElementGetter.getLiveCoreViewContainer();
69
+ if (!container) {
70
+ return null;
71
+ }
72
+ return container.querySelector(DOM_SELECTORS.TCPLAYER_ELEMENT);
73
+ }
74
+
75
+ /**
76
+ * Validate if elements exist
77
+ */
78
+ static validateElements(elements: { container?: HTMLElement | null; view?: HTMLElement | null; video?: HTMLVideoElement | null }): {
79
+ isValid: boolean;
80
+ missingElements: string[];
81
+ } {
82
+ const missingElements: string[] = [];
83
+
84
+ if (elements.container === null) {
85
+ missingElements.push('live-core-view-container');
86
+ }
87
+ if (elements.view === null) {
88
+ missingElements.push('live-core-view');
89
+ }
90
+ if (elements.video === null) {
91
+ missingElements.push('video');
92
+ }
93
+
94
+ return {
95
+ isValid: missingElements.length === 0,
96
+ missingElements,
97
+ };
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Event listener manager
103
+ */
104
+ export class EventListenerManager {
105
+ private listeners: Map<string, { element: EventTarget; event: string; handler: EventListener }> = new Map();
106
+
107
+ /**
108
+ * Add event listener
109
+ */
110
+ addListener(id: string, element: EventTarget, event: string, handler: EventListener): void {
111
+ // Remove possible existing old listener
112
+ this.removeListener(id);
113
+
114
+ // Add new listener
115
+ element.addEventListener(event, handler);
116
+ this.listeners.set(id, { element, event, handler });
117
+ }
118
+
119
+ /**
120
+ * Remove specified event listener
121
+ */
122
+ removeListener(id: string): void {
123
+ const listener = this.listeners.get(id);
124
+ if (listener) {
125
+ listener.element.removeEventListener(listener.event, listener.handler);
126
+ this.listeners.delete(id);
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Remove all event listeners
132
+ */
133
+ removeAllListeners(): void {
134
+ for (const [id] of this.listeners) {
135
+ this.removeListener(id);
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Get current listener count
141
+ */
142
+ getListenerCount(): number {
143
+ return this.listeners.size;
144
+ }
145
+ }