@ray-js/ipc-player-integration 0.0.29-beta.9 → 0.0.30
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/lib/ctx/ctx.composition.d.ts +9 -3
- package/lib/ctx/ctx.composition.js +42 -2
- package/lib/ctx/ctx.js +5 -0
- package/lib/ctx/multiCameraCtx.d.ts +31 -1
- package/lib/ctx/multiCameraCtx.js +60 -16
- package/lib/features/initPlayerWidgets/index.d.ts +7 -1
- package/lib/features/initPlayerWidgets/index.js +14 -11
- package/lib/i18n/index.d.ts +4 -0
- package/lib/i18n/strings.d.ts +2 -0
- package/lib/i18n/strings.js +4 -2
- package/lib/iconfont/iconfont.css +126 -6
- package/lib/iconfont/iconfont.js +13 -13
- package/lib/iconfont/iconfont.json +217 -7
- package/lib/iconfont/iconfont.ttf +0 -0
- package/lib/iconfont/iconfont.woff +0 -0
- package/lib/iconfont/iconfont.woff2 +0 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.js +2 -1
- package/lib/interface.d.ts +43 -2
- package/lib/ui/constant.d.ts +1 -0
- package/lib/ui/constant.js +1 -0
- package/lib/ui/ui.d.ts +1 -0
- package/lib/ui/ui.js +144 -34
- package/lib/ui/ui.less +2 -2
- package/lib/utils/index.d.ts +2 -0
- package/lib/utils/index.js +12 -1
- package/lib/utils/videoSplitHelper.d.ts +18 -0
- package/lib/utils/videoSplitHelper.js +48 -0
- package/lib/widgets/flowLowTip/flowLowTip.d.ts +8 -0
- package/lib/widgets/flowLowTip/flowLowTip.js +65 -0
- package/lib/widgets/flowLowTip/flowLowTip.less +73 -0
- package/lib/widgets/flowLowTip/index.d.ts +1 -0
- package/lib/widgets/flowLowTip/index.js +1 -0
- package/lib/widgets/fullScreen/fullScreen.js +2 -3
- package/lib/widgets/fullScreen/fullVoiceIntercom.js +1 -1
- package/lib/widgets/fullScreen/verticalScreen.js +1 -1
- package/lib/widgets/index.d.ts +2 -0
- package/lib/widgets/index.js +3 -1
- package/lib/widgets/multiCamera/index.less +23 -0
- package/lib/widgets/multiCamera/moveablePtzControl.js +16 -7
- package/lib/widgets/multiCamera/tileActions.js +2 -2
- package/lib/widgets/toggleVerticalFull/index.d.ts +1 -0
- package/lib/widgets/toggleVerticalFull/index.js +1 -0
- package/lib/widgets/toggleVerticalFull/toggleVerticalFull.d.ts +8 -0
- package/lib/widgets/toggleVerticalFull/toggleVerticalFull.js +32 -0
- package/lib/widgets/toggleVerticalFull/toggleVerticalFull.less +4 -0
- package/lib/widgets/voiceIntercom/voiceIntercom.js +12 -20
- package/lib/widgets/voiceIntercom/voiceIntercom.less +85 -0
- package/package.json +4 -4
- package/lib/features/initPlayerWidgets/multiCamera.d.ts +0 -8
- package/lib/features/initPlayerWidgets/multiCamera.js +0 -78
- package/lib/widgets/battery/battery.composition.d.ts +0 -159
- package/lib/widgets/voiceIntercom/voiceIntercom.d.ts +0 -95
package/lib/ui/ui.js
CHANGED
|
@@ -9,17 +9,19 @@ import IPCPlayer from '@ray-js/ray-ipc-player';
|
|
|
9
9
|
import { ipcTTTOperatorLog } from '@ray-js/ray-ipc-utils';
|
|
10
10
|
import { PlayState, PlayerStreamStatus, MultiCameraScreenMode } from '../interface';
|
|
11
11
|
import { useCtx } from '../ctx/ctx.composition';
|
|
12
|
-
import { useStore } from '../ctx/store';
|
|
12
|
+
import { useStore, updateAtom } from '../ctx/store';
|
|
13
13
|
import { UIEventContext } from './context';
|
|
14
|
-
import { showAllComponent, hideAllComponent, playerTap, startTimeToHideAllComponent, pauseTimeToHideAllComponent, decodeClarityDic, changeIgnoreHideStopPreview, moveablePtzControlId, tileActionsId, tileTipId, landscapeTipId, multiPtzId, ptzMoveableTipId } from './constant';
|
|
14
|
+
import { showAllComponent, hideAllComponent, playerTap, startTimeToHideAllComponent, pauseTimeToHideAllComponent, decodeClarityDic, changeIgnoreHideStopPreview, moveablePtzControlId, tileActionsId, tileTipId, landscapeTipId, multiPtzId, ptzMoveableTipId, showFlowLowTipId } from './constant';
|
|
15
15
|
import BottomLeftContent from './bottomLeftContent';
|
|
16
16
|
import BottomRightContent from './bottomRightContent';
|
|
17
17
|
import TopLeftContent from './topLeftContent';
|
|
18
18
|
import TopRightContent from './topRightContent';
|
|
19
|
+
import { FlowLowTip } from '../widgets';
|
|
19
20
|
import { useMemoizedFn } from '../hooks';
|
|
20
21
|
import { Storage } from '../utils/storage';
|
|
21
22
|
import './ui.less';
|
|
22
23
|
import { updatePlayerWidgetProps } from '../features';
|
|
24
|
+
import { isSmallScreen } from '../utils';
|
|
23
25
|
function getCtxInstance(instance, devId) {
|
|
24
26
|
if (instance) return instance;
|
|
25
27
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
@@ -63,6 +65,7 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
63
65
|
playerRoute = 'pages/home/index',
|
|
64
66
|
defaultAutoPlay = true,
|
|
65
67
|
limitFlow = false,
|
|
68
|
+
showFlowLowTip = false,
|
|
66
69
|
extend = {}
|
|
67
70
|
} = props;
|
|
68
71
|
const {
|
|
@@ -87,6 +90,9 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
87
90
|
*/
|
|
88
91
|
const [componentHideState, setComponentHideState] = useState(false);
|
|
89
92
|
prevTriggerEvent.current = componentHideState ? hideAllComponent : showAllComponent;
|
|
93
|
+
|
|
94
|
+
// 记录切换横屏前的竖屏全屏状态,用于从横屏切回竖屏时恢复
|
|
95
|
+
const prevVerticalFullLayoutRef = useRef(false);
|
|
90
96
|
const eventRef = useRef(instance.event);
|
|
91
97
|
if (eventRef.current !== instance.event) {
|
|
92
98
|
eventRef.current = instance.event;
|
|
@@ -111,11 +117,9 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
111
117
|
setIgnoreStopOnHide(ignoreHideStopPreview);
|
|
112
118
|
}, [ignoreHideStopPreview]);
|
|
113
119
|
const handleOrientationChange = useMemoizedFn(data => {
|
|
114
|
-
console.log(data, 'data=============');
|
|
115
120
|
const {
|
|
116
121
|
orientation
|
|
117
122
|
} = data;
|
|
118
|
-
console.log(orientation, 'orientation=-====');
|
|
119
123
|
if (['portrait', 'landscape-left', 'landscape-right'].includes(orientation)) {
|
|
120
124
|
var _ty;
|
|
121
125
|
if (typeof ((_ty = ty) === null || _ty === void 0 ? void 0 : _ty.getDeviceOrientationSync) !== 'function') return;
|
|
@@ -123,29 +127,36 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
123
127
|
// 不是Player首页的话,禁止以下行为
|
|
124
128
|
return;
|
|
125
129
|
}
|
|
126
|
-
console.log('
|
|
130
|
+
console.log('屏幕方向变化调用');
|
|
127
131
|
setPageOrientation({
|
|
128
132
|
pageOrientation: orientation === 'landscape-left' || orientation === 'landscape-right' ? 'landscape' : 'portrait',
|
|
129
133
|
reverse: orientation === 'landscape-left',
|
|
130
134
|
success: () => {
|
|
131
|
-
console.log('
|
|
135
|
+
console.log('setPageOrientation success');
|
|
132
136
|
},
|
|
133
137
|
fail: err => {
|
|
134
|
-
console.log('
|
|
138
|
+
console.log('setPageOrientation fail', err);
|
|
135
139
|
}
|
|
136
140
|
});
|
|
137
141
|
}
|
|
138
142
|
});
|
|
139
143
|
useEffect(() => {
|
|
140
144
|
var _ty2;
|
|
141
|
-
console.log('getDeviceOrientationSync =======');
|
|
142
145
|
if (typeof ((_ty2 = ty) === null || _ty2 === void 0 ? void 0 : _ty2.getDeviceOrientationSync) !== 'function') return undefined;
|
|
143
146
|
try {
|
|
147
|
+
const {
|
|
148
|
+
deviceType
|
|
149
|
+
} = getSystemInfoSync();
|
|
150
|
+
// 针对pad 暂不支持横屏,且在ios pad模式下 会触发onResize事件, 待解决
|
|
151
|
+
if (deviceType === 'pad') {
|
|
152
|
+
setScreenType('vertical');
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
144
155
|
ty.onOrientationChange(handleOrientationChange);
|
|
145
156
|
const {
|
|
146
157
|
orientation
|
|
147
158
|
} = ty.getDeviceOrientationSync();
|
|
148
|
-
console.log(
|
|
159
|
+
console.log('initial orientation', orientation);
|
|
149
160
|
if (orientation === 'landscape-left' || orientation === 'landscape-right') {
|
|
150
161
|
setScreenType('full');
|
|
151
162
|
}
|
|
@@ -204,7 +215,8 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
204
215
|
screenMode,
|
|
205
216
|
layoutStyle,
|
|
206
217
|
ptzStatus,
|
|
207
|
-
selectedLenInfo
|
|
218
|
+
selectedLenInfo,
|
|
219
|
+
isVerticalFullLayout
|
|
208
220
|
} = useStore({
|
|
209
221
|
topLeftContent: instance.topLeftContent,
|
|
210
222
|
topRightContent: instance.topRightContent,
|
|
@@ -218,7 +230,8 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
218
230
|
screenMode: instance.multiCameraCtx.screenMode,
|
|
219
231
|
layoutStyle: instance.multiCameraCtx.layoutStyle,
|
|
220
232
|
ptzStatus: instance.multiCameraCtx.ptzStatus,
|
|
221
|
-
selectedLenInfo: instance.multiCameraCtx.selectedLenInfo
|
|
233
|
+
selectedLenInfo: instance.multiCameraCtx.selectedLenInfo,
|
|
234
|
+
isVerticalFullLayout: instance.isVerticalFullLayout
|
|
222
235
|
});
|
|
223
236
|
|
|
224
237
|
/* ---------------------------------多目相关副作用统一处理开始----------------------------------------- */
|
|
@@ -233,10 +246,16 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
233
246
|
batchedUpdates(() => {
|
|
234
247
|
switch (screenMode) {
|
|
235
248
|
case MultiCameraScreenMode.full:
|
|
249
|
+
// 同步竖屏全屏布局状态
|
|
250
|
+
updateAtom(instance.isVerticalFullLayout, true);
|
|
251
|
+
|
|
236
252
|
// widgets 常驻显示
|
|
237
|
-
eventRef.current.emit(showAllComponent);
|
|
238
|
-
eventRef.current.emit('disablePlayerTap', true);
|
|
239
|
-
eventRef.current.emit(pauseTimeToHideAllComponent);
|
|
253
|
+
// eventRef.current.emit(showAllComponent);
|
|
254
|
+
// eventRef.current.emit('disablePlayerTap', true);
|
|
255
|
+
// eventRef.current.emit(pauseTimeToHideAllComponent);
|
|
256
|
+
|
|
257
|
+
// 隐藏landscapeTip
|
|
258
|
+
hideContent('absolute', landscapeTipId);
|
|
240
259
|
|
|
241
260
|
// 展示右侧插件
|
|
242
261
|
showContent('absolute', tileActionsId);
|
|
@@ -259,9 +278,18 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
259
278
|
});
|
|
260
279
|
break;
|
|
261
280
|
case MultiCameraScreenMode.short:
|
|
281
|
+
// 同步竖屏全屏布局状态
|
|
282
|
+
updateAtom(instance.isVerticalFullLayout, false);
|
|
283
|
+
|
|
262
284
|
// 恢复 widgets 展示逻辑
|
|
263
|
-
eventRef.current.emit('disablePlayerTap', false);
|
|
264
|
-
showComponents();
|
|
285
|
+
// eventRef.current.emit('disablePlayerTap', false);
|
|
286
|
+
// showComponents();
|
|
287
|
+
|
|
288
|
+
// 隐藏tileTip
|
|
289
|
+
hideContent('absolute', tileTipId);
|
|
290
|
+
|
|
291
|
+
// 隐藏landscapeTip
|
|
292
|
+
hideContent('absolute', landscapeTipId);
|
|
265
293
|
|
|
266
294
|
// 隐藏右侧插件
|
|
267
295
|
hideContent('absolute', tileActionsId);
|
|
@@ -276,9 +304,15 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
276
304
|
hideContent('bottomLeft', 'SmallIntercom');
|
|
277
305
|
break;
|
|
278
306
|
case MultiCameraScreenMode.landscape:
|
|
307
|
+
// 同步竖屏全屏布局状态
|
|
308
|
+
updateAtom(instance.isVerticalFullLayout, false);
|
|
309
|
+
|
|
279
310
|
// 恢复 widgets 展示逻辑
|
|
280
|
-
eventRef.current.emit('disablePlayerTap', false);
|
|
281
|
-
showComponents();
|
|
311
|
+
// eventRef.current.emit('disablePlayerTap', false);
|
|
312
|
+
// showComponents();
|
|
313
|
+
|
|
314
|
+
// 隐藏tileTip
|
|
315
|
+
hideContent('absolute', tileTipId);
|
|
282
316
|
if (multiCameraCtx.protocol.total_split_num === 2 && !storage.getSync(landscapeTipId)) {
|
|
283
317
|
showContent('absolute', landscapeTipId);
|
|
284
318
|
}
|
|
@@ -351,8 +385,32 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
351
385
|
}
|
|
352
386
|
}, [instance, ptzStatus, selectedLenInfo, componentHideState, screenMode]);
|
|
353
387
|
|
|
388
|
+
// 适配横屏进入面板的情况
|
|
389
|
+
useEffect(() => {
|
|
390
|
+
if (!instance.multiCameraCtx.isSupport) return;
|
|
391
|
+
if (hasInitializedLandscapeMultiRef.current) return;
|
|
392
|
+
if (screenType !== 'full') return;
|
|
393
|
+
hasInitializedLandscapeMultiRef.current = true;
|
|
394
|
+
instance.multiCameraCtx.setScreenMode(MultiCameraScreenMode.landscape);
|
|
395
|
+
}, [screenType, instance, layoutStyle]);
|
|
396
|
+
|
|
354
397
|
/* ---------------------------------多目相关副作用统一处理结束----------------------------------------- */
|
|
355
398
|
|
|
399
|
+
// 竖屏全屏副作用处理
|
|
400
|
+
useEffect(() => {
|
|
401
|
+
if (isVerticalFullLayout && screenType === 'vertical') {
|
|
402
|
+
// 竖屏全屏时,控件常驻显示
|
|
403
|
+
eventRef.current.emit(showAllComponent);
|
|
404
|
+
eventRef.current.emit('disablePlayerTap', true);
|
|
405
|
+
eventRef.current.emit(pauseTimeToHideAllComponent);
|
|
406
|
+
// 按宽填充,保证播放流宽度为屏幕宽度,高度自适应
|
|
407
|
+
setScaleMultiple(-1);
|
|
408
|
+
} else {
|
|
409
|
+
// 短屏或横屏时,恢复自动隐藏
|
|
410
|
+
eventRef.current.emit('disablePlayerTap', false);
|
|
411
|
+
showComponents();
|
|
412
|
+
}
|
|
413
|
+
}, [isVerticalFullLayout, screenType, playerFit, instance]);
|
|
356
414
|
useEffect(() => {
|
|
357
415
|
if (createCtx) {
|
|
358
416
|
setScaleMultiple(playerFit === 'contain' ? 1 : -2);
|
|
@@ -369,6 +427,25 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
369
427
|
event.current.emit(playerTap);
|
|
370
428
|
};
|
|
371
429
|
|
|
430
|
+
/** 标记流量不足提示是否已添加过,只允许 addContent 一次 */
|
|
431
|
+
const flowLowTipAddedRef = useRef(false);
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* 监听显示流量不足200MB的提示
|
|
435
|
+
*/
|
|
436
|
+
useEffect(() => {
|
|
437
|
+
if (playState !== PlayState.PLAYING || !showFlowLowTip || flowLowTipAddedRef.current) return;
|
|
438
|
+
if (!instance.hasContent('absolute', showFlowLowTipId)) {
|
|
439
|
+
instance.addContent('absolute', {
|
|
440
|
+
id: showFlowLowTipId,
|
|
441
|
+
content: props => /*#__PURE__*/React.createElement(FlowLowTip, props),
|
|
442
|
+
absoluteContentClassName: 'ipc-player-plugin-flow-low-tip-wrap',
|
|
443
|
+
initProps: _objectSpread({}, props)
|
|
444
|
+
});
|
|
445
|
+
flowLowTipAddedRef.current = true;
|
|
446
|
+
}
|
|
447
|
+
}, [instance, playState, showFlowLowTip]);
|
|
448
|
+
|
|
372
449
|
/**
|
|
373
450
|
* 监听播放器实例创建完成
|
|
374
451
|
*/
|
|
@@ -386,15 +463,20 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
386
463
|
const {
|
|
387
464
|
type
|
|
388
465
|
} = sizeData;
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
deviceType
|
|
392
|
-
} = systemInfo.current;
|
|
393
|
-
// 针对pad 暂不支持横屏,且在ios pad模式下 会触发onResize事件, 待解决
|
|
394
|
-
if (deviceType === 'pad') {
|
|
466
|
+
// 针对pad 和折叠屏展开的情况暂不支持横屏,且在ios pad模式下 会触发onResize事件, 待解决
|
|
467
|
+
if (isSmallScreen) {
|
|
395
468
|
setScreenType('vertical');
|
|
396
469
|
} else {
|
|
397
470
|
setScreenType(type === 'landscape' ? 'full' : 'vertical');
|
|
471
|
+
if (type === 'landscape') {
|
|
472
|
+
// 记录切换横屏前的竖屏全屏状态
|
|
473
|
+
prevVerticalFullLayoutRef.current = isVerticalFullLayout;
|
|
474
|
+
// 横屏时重置竖屏全屏状态
|
|
475
|
+
updateAtom(instance.isVerticalFullLayout, false);
|
|
476
|
+
} else if (!instance.multiCameraCtx.isSupport) {
|
|
477
|
+
// 单目设备从横屏切回竖屏时,恢复之前的竖屏全屏状态
|
|
478
|
+
updateAtom(instance.isVerticalFullLayout, prevVerticalFullLayoutRef.current);
|
|
479
|
+
}
|
|
398
480
|
triggerEvent(showAllComponent);
|
|
399
481
|
}
|
|
400
482
|
// 若为全屏模式并且要求按宽填充,即横屏时充满,主动设置模式为-1即可
|
|
@@ -441,11 +523,6 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
441
523
|
}
|
|
442
524
|
});
|
|
443
525
|
});
|
|
444
|
-
const systemInfo = useRef(null);
|
|
445
|
-
if (!systemInfo.current) {
|
|
446
|
-
systemInfo.current = getSystemInfoSync();
|
|
447
|
-
}
|
|
448
|
-
|
|
449
526
|
// 监听物理返回按键
|
|
450
527
|
const hackHandle = () => {
|
|
451
528
|
setPageOrientation({
|
|
@@ -582,6 +659,9 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
582
659
|
instance.changeStreamStatus(code);
|
|
583
660
|
});
|
|
584
661
|
const disablePlayerTap = useRef(false);
|
|
662
|
+
const hasInitializedLandscapeMultiRef = useRef(false);
|
|
663
|
+
const multiTapTimerRef = useRef(null);
|
|
664
|
+
const prevSelectedIndexRef = useRef(selectedLenInfo.index);
|
|
585
665
|
const handDisablePlayerTap = value => {
|
|
586
666
|
disablePlayerTap.current = !!value;
|
|
587
667
|
};
|
|
@@ -651,6 +731,10 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
651
731
|
eventRef.current.off('disablePlayerTap', handDisablePlayerTap);
|
|
652
732
|
eventRef.current.off('refreshBottomLeft', refreshBottomLeft);
|
|
653
733
|
eventRef.current.off(changeIgnoreHideStopPreview, onChangeIgnoreHideStopPreview);
|
|
734
|
+
if (multiTapTimerRef.current) {
|
|
735
|
+
clearTimeout(multiTapTimerRef.current);
|
|
736
|
+
multiTapTimerRef.current = null;
|
|
737
|
+
}
|
|
654
738
|
if (reGetOrientationTimer.current) {
|
|
655
739
|
clearTimeout(reGetOrientationTimer.current);
|
|
656
740
|
reGetOrientationTimer.current = null;
|
|
@@ -707,19 +791,20 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
707
791
|
return false;
|
|
708
792
|
});
|
|
709
793
|
const playerContainerHeight = screenType === 'vertical' ? (style === null || style === void 0 ? void 0 : style.height) || '100%' : '100vh';
|
|
794
|
+
const isVerticalFullMode = isVerticalFullLayout && screenType === 'vertical';
|
|
710
795
|
return /*#__PURE__*/React.createElement(UIEventContext.Provider, {
|
|
711
796
|
value: {
|
|
712
797
|
event: eventRef.current,
|
|
713
798
|
componentHideState
|
|
714
799
|
}
|
|
715
800
|
}, /*#__PURE__*/React.createElement(View, {
|
|
716
|
-
className: clsx('ipc-player-content', className),
|
|
801
|
+
className: clsx('ipc-player-content', isSmallScreen && 'ipc-player-content-small-screen', className),
|
|
717
802
|
style: _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, defaultCSSVariable), CSSVariable), style), {}, {
|
|
718
803
|
height: playerContainerHeight
|
|
719
804
|
})
|
|
720
805
|
}, /*#__PURE__*/React.createElement(View, {
|
|
721
806
|
style: {
|
|
722
|
-
height:
|
|
807
|
+
height: isVerticalFullMode ? `calc(${playerContainerHeight} - 48px)` : playerContainerHeight
|
|
723
808
|
}
|
|
724
809
|
}, /*#__PURE__*/React.createElement(IPCPlayer, {
|
|
725
810
|
defaultMute: mute,
|
|
@@ -769,8 +854,33 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
769
854
|
eventRef.current.emit(playerTap);
|
|
770
855
|
console.log(prevTriggerEvent.current, 'prevTriggerEvent.current');
|
|
771
856
|
if (instance.multiCameraCtx.isSupport) {
|
|
772
|
-
|
|
773
|
-
|
|
857
|
+
var _instance$multiCamera, _instance$multiCamera2;
|
|
858
|
+
const preTapIndex = (_instance$multiCamera = (_instance$multiCamera2 = instance.multiCameraCtx.selectedLenInfoRef.current) === null || _instance$multiCamera2 === void 0 ? void 0 : _instance$multiCamera2.index) !== null && _instance$multiCamera !== void 0 ? _instance$multiCamera : prevSelectedIndexRef.current;
|
|
859
|
+
instance.multiCameraCtx.selectVideoFiredRef.current = false;
|
|
860
|
+
if (multiTapTimerRef.current) {
|
|
861
|
+
clearTimeout(multiTapTimerRef.current);
|
|
862
|
+
}
|
|
863
|
+
multiTapTimerRef.current = setTimeout(() => {
|
|
864
|
+
var _instance$multiCamera3, _instance$multiCamera4;
|
|
865
|
+
const selectFired = !!instance.multiCameraCtx.selectVideoFiredRef.current;
|
|
866
|
+
const currentIndex = (_instance$multiCamera3 = (_instance$multiCamera4 = instance.multiCameraCtx.selectedLenInfoRef.current) === null || _instance$multiCamera4 === void 0 ? void 0 : _instance$multiCamera4.index) !== null && _instance$multiCamera3 !== void 0 ? _instance$multiCamera3 : preTapIndex;
|
|
867
|
+
if (selectFired && currentIndex === preTapIndex) {
|
|
868
|
+
if (componentHideState) {
|
|
869
|
+
showComponents();
|
|
870
|
+
} else {
|
|
871
|
+
if (timer.current) {
|
|
872
|
+
clearTimeout(timer.current);
|
|
873
|
+
timer.current = null;
|
|
874
|
+
}
|
|
875
|
+
setComponentHideState(true);
|
|
876
|
+
}
|
|
877
|
+
} else {
|
|
878
|
+
// 点击不同镜头或非镜头区域时,保持现有行为
|
|
879
|
+
showComponents();
|
|
880
|
+
}
|
|
881
|
+
prevSelectedIndexRef.current = currentIndex;
|
|
882
|
+
multiTapTimerRef.current = null;
|
|
883
|
+
}, 50);
|
|
774
884
|
} else if (prevTriggerEvent.current === hideAllComponent) {
|
|
775
885
|
triggerEvent(showAllComponent);
|
|
776
886
|
} else {
|
|
@@ -803,7 +913,7 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
803
913
|
className: clsx('ipc-player-bottom-content', {
|
|
804
914
|
'ipc-player-bottom-content-hide': componentHideState,
|
|
805
915
|
'ipc-player-bottom-content-show': !componentHideState,
|
|
806
|
-
'ipc-player-bottom-content-full':
|
|
916
|
+
'ipc-player-bottom-content-full': isVerticalFullMode
|
|
807
917
|
}),
|
|
808
918
|
style: {
|
|
809
919
|
height: screenType === 'vertical' ? '48px' : '72px'
|
package/lib/ui/ui.less
CHANGED
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
.ipc-player-bottom-content-full {
|
|
29
|
-
|
|
29
|
+
:root[theme='dark'] & {
|
|
30
30
|
background: #000;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
:root[theme='light'] & {
|
|
34
34
|
background: #fff;
|
|
35
35
|
--iconColor: #000;
|
|
36
36
|
|
package/lib/utils/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="jest" />
|
|
2
|
+
export declare const isSmallScreen: boolean;
|
|
2
3
|
/**
|
|
3
4
|
* 麦克风对讲按钮径向渐变
|
|
4
5
|
*/
|
|
@@ -13,3 +14,4 @@ export declare const promisify: <TParams extends Record<string, any>, TSuccessRe
|
|
|
13
14
|
fail?: ((error: any) => void) | undefined;
|
|
14
15
|
complete?: (() => void) | undefined;
|
|
15
16
|
}) => void) => (params: Omit<TParams, "complete" | "success" | "fail">) => Promise<TSuccessResult>;
|
|
17
|
+
export * from './videoSplitHelper';
|
package/lib/utils/index.js
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import { getSystemInfoSync } from '@ray-js/ray';
|
|
3
|
+
const {
|
|
4
|
+
windowWidth,
|
|
5
|
+
screenWidth,
|
|
6
|
+
windowHeight
|
|
7
|
+
} = getSystemInfoSync();
|
|
8
|
+
|
|
9
|
+
// pad和折叠屏小窗口展示面板的情况
|
|
10
|
+
export const isSmallScreen = !(screenWidth === windowWidth || screenWidth === windowHeight);
|
|
11
|
+
|
|
2
12
|
/**
|
|
3
13
|
* 麦克风对讲按钮径向渐变
|
|
4
14
|
*/
|
|
@@ -36,4 +46,5 @@ export const promisify = apiFunction => {
|
|
|
36
46
|
}));
|
|
37
47
|
});
|
|
38
48
|
};
|
|
39
|
-
};
|
|
49
|
+
};
|
|
50
|
+
export * from './videoSplitHelper';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { VideoSplitProtocol } from '../interface';
|
|
2
|
+
export type FourDirectionShow = {
|
|
3
|
+
top: boolean;
|
|
4
|
+
right: boolean;
|
|
5
|
+
bottom: boolean;
|
|
6
|
+
left: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare function getLensInfoByIndex(protocol: VideoSplitProtocol | undefined, index?: number): import("../interface").VideoSplitInfoItem | undefined;
|
|
9
|
+
export declare function getLensSupportDirections(protocol: VideoSplitProtocol | undefined, index?: number): number[];
|
|
10
|
+
export declare function getPtzShowMapByProtocol(protocol: VideoSplitProtocol | undefined, index?: number): FourDirectionShow;
|
|
11
|
+
export declare function patchPtzDataShowByProtocol<T extends {
|
|
12
|
+
type: string;
|
|
13
|
+
show: boolean;
|
|
14
|
+
}>(ptzData: T[], protocol: VideoSplitProtocol | undefined, index?: number, isMultiCamera?: boolean): T[];
|
|
15
|
+
export declare function patchZoomDataShowByProtocol<T extends {
|
|
16
|
+
show: boolean;
|
|
17
|
+
}>(zoomData: T[], isMultiCamera?: boolean): T[];
|
|
18
|
+
export declare function isSwipeDirectionSupported(protocol: VideoSplitProtocol | undefined, index: number | undefined, direction: unknown): boolean;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import "core-js/modules/esnext.iterator.constructor.js";
|
|
3
|
+
import "core-js/modules/esnext.iterator.filter.js";
|
|
4
|
+
import "core-js/modules/esnext.iterator.find.js";
|
|
5
|
+
import "core-js/modules/esnext.iterator.map.js";
|
|
6
|
+
export function getLensInfoByIndex(protocol, index) {
|
|
7
|
+
if (!protocol || !index) return undefined;
|
|
8
|
+
return protocol.split_info.find(item => item.index === index);
|
|
9
|
+
}
|
|
10
|
+
export function getLensSupportDirections(protocol, index) {
|
|
11
|
+
const lensInfo = getLensInfoByIndex(protocol, index);
|
|
12
|
+
if (!Array.isArray(lensInfo === null || lensInfo === void 0 ? void 0 : lensInfo.support_directions)) return [];
|
|
13
|
+
return lensInfo.support_directions.filter(direction => Number.isInteger(direction) && direction >= 0 && direction <= 7);
|
|
14
|
+
}
|
|
15
|
+
export function getPtzShowMapByProtocol(protocol, index) {
|
|
16
|
+
const supportSet = new Set(getLensSupportDirections(protocol, index));
|
|
17
|
+
return {
|
|
18
|
+
top: supportSet.has(0),
|
|
19
|
+
right: supportSet.has(2),
|
|
20
|
+
bottom: supportSet.has(4),
|
|
21
|
+
left: supportSet.has(6)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export function patchPtzDataShowByProtocol(ptzData, protocol, index) {
|
|
25
|
+
let isMultiCamera = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
26
|
+
if (!isMultiCamera) return ptzData;
|
|
27
|
+
const showMap = getPtzShowMapByProtocol(protocol, index);
|
|
28
|
+
return ptzData.map(item => {
|
|
29
|
+
let show = false;
|
|
30
|
+
if (item.type === 'top') show = showMap.top;else if (item.type === 'right') show = showMap.right;else if (item.type === 'bottom') show = showMap.bottom;else if (item.type === 'left') show = showMap.left;
|
|
31
|
+
return _objectSpread(_objectSpread({}, item), {}, {
|
|
32
|
+
show
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
export function patchZoomDataShowByProtocol(zoomData) {
|
|
37
|
+
let isMultiCamera = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
38
|
+
if (!isMultiCamera) return zoomData;
|
|
39
|
+
return zoomData.map(item => _objectSpread(_objectSpread({}, item), {}, {
|
|
40
|
+
show: true
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
export function isSwipeDirectionSupported(protocol, index, direction) {
|
|
44
|
+
const directionValue = Number(direction);
|
|
45
|
+
if (!Number.isInteger(directionValue)) return false;
|
|
46
|
+
const supportDirections = getLensSupportDirections(protocol, index);
|
|
47
|
+
return supportDirections.includes(directionValue);
|
|
48
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ComponentConfigProps } from '../../interface';
|
|
3
|
+
import './flowLowTip.less';
|
|
4
|
+
type Props = ComponentConfigProps & {
|
|
5
|
+
className?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare const FlowLowTip: (props: Props) => React.JSX.Element | null;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { View, Text } from '@ray-js/ray';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
4
|
+
import { getServiceUrl } from '@ray-js/ray-ipc-utils';
|
|
5
|
+
import { useMemoizedFn } from 'ahooks';
|
|
6
|
+
import Strings from '../../i18n';
|
|
7
|
+
import { useStore } from '../../ctx/store';
|
|
8
|
+
import { showFlowLowTipId } from '../../ui/constant';
|
|
9
|
+
import './flowLowTip.less';
|
|
10
|
+
// 5秒后自动隐藏
|
|
11
|
+
const AUTO_HIDE_MS = 5000;
|
|
12
|
+
export const FlowLowTip = props => {
|
|
13
|
+
const {
|
|
14
|
+
screenType: screenTypeAtom,
|
|
15
|
+
hideContent,
|
|
16
|
+
className,
|
|
17
|
+
brandColor: brandColorProp,
|
|
18
|
+
devId
|
|
19
|
+
} = props;
|
|
20
|
+
const {
|
|
21
|
+
screenType,
|
|
22
|
+
brandColor
|
|
23
|
+
} = useStore({
|
|
24
|
+
screenType: screenTypeAtom,
|
|
25
|
+
brandColor: brandColorProp
|
|
26
|
+
});
|
|
27
|
+
const [hideFlowLowTip, setHideFlowLowTip] = useState(false);
|
|
28
|
+
const timerRef = useRef(null);
|
|
29
|
+
const handleClose = useMemoizedFn(async function () {
|
|
30
|
+
let jump = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
31
|
+
setHideFlowLowTip(true);
|
|
32
|
+
if (jump) {
|
|
33
|
+
await getServiceUrl(devId, 'traffic_service', {}, true);
|
|
34
|
+
}
|
|
35
|
+
hideContent('absolute', showFlowLowTipId);
|
|
36
|
+
});
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
timerRef.current = setTimeout(handleClose, AUTO_HIDE_MS);
|
|
39
|
+
return () => {
|
|
40
|
+
if (timerRef.current) {
|
|
41
|
+
clearTimeout(timerRef.current);
|
|
42
|
+
timerRef.current = null;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}, [handleClose]);
|
|
46
|
+
if (screenType === 'full') {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
50
|
+
className: clsx(className, 'ipc-player-plugin-flow-low-tip-content', {
|
|
51
|
+
'ipc-player-plugin-full-screen-ptz-control-hide': hideFlowLowTip
|
|
52
|
+
}),
|
|
53
|
+
onClick: () => handleClose(true)
|
|
54
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
55
|
+
className: "ipc-player-plugin-flow-low-tip-text-wrap"
|
|
56
|
+
}, /*#__PURE__*/React.createElement(Text, {
|
|
57
|
+
className: clsx('icon-panel', 'icon-panel-tip-circle', 'ipc-player-plugin-flow-low-tip-icon')
|
|
58
|
+
}), /*#__PURE__*/React.createElement(Text, {
|
|
59
|
+
className: "ipc-player-plugin-flow-low-tip-text"
|
|
60
|
+
}, Strings.getLang('ipc_player_flow_low_tip'))), /*#__PURE__*/React.createElement(View, {
|
|
61
|
+
className: "ipc-player-plugin-flow-low-tip-button-wrap"
|
|
62
|
+
}, /*#__PURE__*/React.createElement(Text, {
|
|
63
|
+
className: clsx('icon-panel', 'icon-panel-tip-right-arrow', 'ipc-player-plugin-flow-low-tip-button-icon')
|
|
64
|
+
})));
|
|
65
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
@animation-time: 0.3s;
|
|
2
|
+
|
|
3
|
+
.ipc-player-plugin-flow-low-tip-wrap {
|
|
4
|
+
position: absolute;
|
|
5
|
+
top: calc(10px * var(--ipc-player-size-scale, 1));
|
|
6
|
+
left: calc(16px * var(--ipc-player-size-scale, 1));
|
|
7
|
+
right: calc(16px * var(--ipc-player-size-scale, 1));
|
|
8
|
+
background-color: #262626;
|
|
9
|
+
z-index: 350;
|
|
10
|
+
border-radius: calc(8px * var(--ipc-player-size-scale, 1));
|
|
11
|
+
overflow: hidden;
|
|
12
|
+
padding: calc(8px * var(--ipc-player-size-scale, 1)) calc(12px * var(--ipc-player-size-scale, 1));
|
|
13
|
+
font-size: calc(12px * var(--ipc-player-size-scale, 1));
|
|
14
|
+
color: #ffffff;
|
|
15
|
+
transform: translate(0, 0);
|
|
16
|
+
transition: @animation-time ease-in;
|
|
17
|
+
animation: ipc-player-plugin-flow-low-tip-move-in @animation-time ease-in-out forwards;
|
|
18
|
+
&.ipc-player-plugin-flow-low-tip-hide {
|
|
19
|
+
animation: ipc-player-plugin-flow-low-tip-move-out @animation-time ease-in-out forwards;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.ipc-player-plugin-flow-low-tip-content {
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: row;
|
|
26
|
+
align-items: center;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.ipc-player-plugin-flow-low-tip-text-wrap {
|
|
30
|
+
flex: 1;
|
|
31
|
+
min-width: 0;
|
|
32
|
+
display: flex;
|
|
33
|
+
flex-direction: row;
|
|
34
|
+
align-items: center;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.ipc-player-plugin-flow-low-tip-icon {
|
|
38
|
+
color: #ffa000;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.ipc-player-plugin-flow-low-tip-text {
|
|
42
|
+
flex: 1;
|
|
43
|
+
min-width: 0;
|
|
44
|
+
padding: 0 calc(4px * var(--ipc-player-size-scale, 1));
|
|
45
|
+
word-wrap: break-word;
|
|
46
|
+
overflow-wrap: break-word;
|
|
47
|
+
white-space: normal;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.ipc-player-plugin-flow-low-tip-button-wrap {
|
|
51
|
+
width: calc(32px * var(--ipc-player-size-scale, 1));
|
|
52
|
+
display: flex;
|
|
53
|
+
justify-content: flex-end;
|
|
54
|
+
align-items: center;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@keyframes ipc-player-plugin-flow-low-tip-move-in {
|
|
58
|
+
0% {
|
|
59
|
+
transform: translate(0, -100vh); /* 从上方滑入 */
|
|
60
|
+
}
|
|
61
|
+
100% {
|
|
62
|
+
transform: translate(0, 0); /* 移动到目标位置 */
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@keyframes ipc-player-plugin-flow-low-tip-move-out {
|
|
67
|
+
0% {
|
|
68
|
+
transform: translate(0, 0); /* 从当前位置开始 */
|
|
69
|
+
}
|
|
70
|
+
100% {
|
|
71
|
+
transform: translate(0, -100vh); /* 向上滑出,隐藏 */
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './flowLowTip';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './flowLowTip';
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
-
import React, { useContext } from 'react';
|
|
2
|
+
import React, { useContext, useEffect } from 'react';
|
|
3
3
|
import { View, setPageOrientation, Text, hideMenuButton, showMenuButton, showStatusBar, hideStatusBar, setNavigationBarBack } from '@ray-js/ray';
|
|
4
|
-
import { useUpdateEffect } from 'ahooks';
|
|
5
4
|
import clsx from 'clsx';
|
|
6
5
|
import { unstable_batchedUpdates as batchedUpdates } from '@ray-core/ray';
|
|
7
6
|
import { UIEventContext } from '../../ui/context';
|
|
@@ -118,7 +117,7 @@ export function FullScreen(props) {
|
|
|
118
117
|
deleteContent('absolute', fullTravelRouteControlId);
|
|
119
118
|
}
|
|
120
119
|
};
|
|
121
|
-
|
|
120
|
+
useEffect(() => {
|
|
122
121
|
var _handlers$screenType;
|
|
123
122
|
(_handlers$screenType = handlers[screenType]) === null || _handlers$screenType === void 0 || _handlers$screenType.call(handlers);
|
|
124
123
|
}, [screenType]);
|