@ray-js/ipc-player-integration 0.0.34 → 0.0.35-beta.10

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 (51) hide show
  1. package/lib/ctx/ctx.composition.js +11 -1
  2. package/lib/features/initPlayerWidgets/index.d.ts +1 -0
  3. package/lib/features/initPlayerWidgets/index.js +8 -0
  4. package/lib/i18n/index.d.ts +24 -0
  5. package/lib/i18n/strings.d.ts +12 -0
  6. package/lib/i18n/strings.js +14 -2
  7. package/lib/interface.d.ts +1 -1
  8. package/lib/res/try/try_close.png +0 -0
  9. package/lib/res/try/try_en.png +0 -0
  10. package/lib/res/try/try_open.png +0 -0
  11. package/lib/res/try/try_zh.png +0 -0
  12. package/lib/ui/bottomLeftContent.d.ts +4 -1
  13. package/lib/ui/bottomLeftContent.js +93 -8
  14. package/lib/ui/bottomRightContent.d.ts +3 -1
  15. package/lib/ui/bottomRightContent.js +11 -4
  16. package/lib/ui/constant.d.ts +9 -0
  17. package/lib/ui/constant.js +10 -0
  18. package/lib/ui/index.d.ts +1 -1
  19. package/lib/ui/index.js +1 -1
  20. package/lib/ui/ui.d.ts +1 -0
  21. package/lib/ui/ui.js +106 -57
  22. package/lib/ui/ui.less +5 -1
  23. package/lib/utils/index.d.ts +2 -1
  24. package/lib/utils/index.js +3 -11
  25. package/lib/utils/navigation.d.ts +7 -0
  26. package/lib/utils/navigation.js +23 -0
  27. package/lib/utils/ttt.d.ts +42 -0
  28. package/lib/utils/ttt.js +123 -0
  29. package/lib/widgets/floodlight/floodlight.d.ts +4 -0
  30. package/lib/widgets/floodlight/floodlight.js +55 -0
  31. package/lib/widgets/floodlight/floodlight.less +4 -0
  32. package/lib/widgets/floodlight/index.d.ts +1 -0
  33. package/lib/widgets/floodlight/index.js +1 -0
  34. package/lib/widgets/index.d.ts +4 -0
  35. package/lib/widgets/index.js +4 -0
  36. package/lib/widgets/siren/index.d.ts +1 -0
  37. package/lib/widgets/siren/index.js +1 -0
  38. package/lib/widgets/siren/siren.d.ts +4 -0
  39. package/lib/widgets/siren/siren.js +55 -0
  40. package/lib/widgets/siren/siren.less +4 -0
  41. package/lib/widgets/trialBadge/index.d.ts +17 -0
  42. package/lib/widgets/trialBadge/index.js +88 -0
  43. package/lib/widgets/trialBadge/index.less +57 -0
  44. package/lib/widgets/trialBadge/useTrialBadge.d.ts +8 -0
  45. package/lib/widgets/trialBadge/useTrialBadge.js +42 -0
  46. package/lib/widgets/tryExperience/index.d.ts +1 -0
  47. package/lib/widgets/tryExperience/index.js +1 -0
  48. package/lib/widgets/tryExperience/tryExperience.d.ts +14 -0
  49. package/lib/widgets/tryExperience/tryExperience.js +145 -0
  50. package/lib/widgets/tryExperience/tryExperience.less +13 -0
  51. package/package.json +3 -3
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { ComponentConfigProps } from '../../interface';
3
+ import './siren.less';
4
+ export declare const Siren: (props: ComponentConfigProps) => React.JSX.Element | null;
@@ -0,0 +1,55 @@
1
+ import { View, Text } from '@ray-js/ray';
2
+ import React, { useContext } from 'react';
3
+ import clsx from 'clsx';
4
+ import { useDpState } from '../../hooks';
5
+ import { useStore } from '../../ctx/store';
6
+ import { UIEventContext } from '../../ui/context';
7
+ import { widgetLabs, widgetClick, pauseTimeToHideAllComponent, startTimeToHideAllComponent } from '../../ui/constant';
8
+ import './siren.less';
9
+ const SIREN_SWITCH_DP_CODE = 'siren_switch';
10
+ export const Siren = props => {
11
+ const {
12
+ devId,
13
+ screenType: screenTypeAtom,
14
+ className,
15
+ event: propsEvent
16
+ } = props;
17
+ const {
18
+ event: ctxEvent
19
+ } = useContext(UIEventContext);
20
+ const event = propsEvent !== null && propsEvent !== void 0 ? propsEvent : ctxEvent;
21
+ const {
22
+ screenType,
23
+ brandColor
24
+ } = useStore({
25
+ screenType: screenTypeAtom,
26
+ brandColor: props.brandColor
27
+ });
28
+ const [state, dpSchema, sendDp] = useDpState({
29
+ devId,
30
+ dpCodes: [SIREN_SWITCH_DP_CODE]
31
+ });
32
+ const supported = !!(dpSchema !== null && dpSchema !== void 0 && dpSchema[SIREN_SWITCH_DP_CODE]);
33
+ const enabled = !!state[SIREN_SWITCH_DP_CODE];
34
+ if (screenType !== 'full' || !supported) {
35
+ return null;
36
+ }
37
+ return /*#__PURE__*/React.createElement(View, {
38
+ className: clsx(className),
39
+ onClick: () => {
40
+ event.emit(widgetClick, {
41
+ widgetId: widgetLabs.SIREN
42
+ });
43
+ event.emit(pauseTimeToHideAllComponent);
44
+ sendDp({
45
+ [SIREN_SWITCH_DP_CODE]: !enabled
46
+ });
47
+ event.emit(startTimeToHideAllComponent);
48
+ }
49
+ }, /*#__PURE__*/React.createElement(Text, {
50
+ className: clsx('icon-panel', 'icon-panel-jingdi', 'ipc-player-plugin-siren-text-icon'),
51
+ style: {
52
+ color: enabled ? brandColor : undefined
53
+ }
54
+ }));
55
+ };
@@ -0,0 +1,4 @@
1
+ .ipc-player-plugin-siren-text-icon {
2
+ color: var(--iconColor);
3
+ font-size: calc(var(--iconPlayerSize) * var(--ipc-player-size-scale, 1)) !important;
4
+ }
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import './index.less';
3
+ type Props = {
4
+ className?: string;
5
+ /** 主题色(用于「开通」按钮背景)。默认与 player brandColor 一致 */
6
+ brandColor?: string;
7
+ /** 试看倒计时初始秒数,来源于 smartImageQualityState.trialRemainingSec */
8
+ trialRemainingSec?: number;
9
+ /** 刷新令牌,变化时重置倒计时状态 */
10
+ refreshToken?: number;
11
+ /** 点击「开通」按钮回调 */
12
+ onSubscribe?: () => void;
13
+ /** 倒计时归零时触发,本组件保证整个生命周期内只回调一次 */
14
+ onCountdownEnd?: () => void;
15
+ };
16
+ export declare const TrialBadge: ({ className, brandColor, trialRemainingSec, refreshToken, onSubscribe, onCountdownEnd, }: Props) => React.JSX.Element;
17
+ export { useTrialBadge } from './useTrialBadge';
@@ -0,0 +1,88 @@
1
+ import React, { useEffect, useRef, useState } from 'react';
2
+ import { Image, Text, View } from '@ray-js/ray';
3
+ import clsx from 'clsx';
4
+ import Strings from '../../i18n';
5
+ import tryOpen from '../../res/try/try_open.png';
6
+ import './index.less';
7
+ /** 兜底主题色,与 player ctx 中 brandColor 默认值保持一致 */
8
+ const FALLBACK_BRAND_COLOR = '#FF592A';
9
+
10
+ /** 将秒数格式化为 mm:ss */
11
+ const formatCountdown = seconds => {
12
+ const safe = Math.max(0, Math.floor(seconds));
13
+ const m = Math.floor(safe / 60);
14
+ return `${String(m).padStart(2, '0')}:${String(safe % 60).padStart(2, '0')}`;
15
+ };
16
+ export const TrialBadge = _ref => {
17
+ let {
18
+ className,
19
+ brandColor = FALLBACK_BRAND_COLOR,
20
+ trialRemainingSec = 0,
21
+ refreshToken,
22
+ onSubscribe,
23
+ onCountdownEnd
24
+ } = _ref;
25
+ const [remainingSec, setRemainingSec] = useState(Math.max(0, Math.floor(trialRemainingSec)));
26
+ /** 防止 onCountdownEnd 被重复触发;同时持有最新回调,避免依赖变化导致 effect 重跑 */
27
+ const endedRef = useRef(false);
28
+ const onCountdownEndRef = useRef(onCountdownEnd);
29
+ onCountdownEndRef.current = onCountdownEnd;
30
+ useEffect(() => {
31
+ endedRef.current = false;
32
+ setRemainingSec(Math.max(0, Math.floor(trialRemainingSec)));
33
+ }, [trialRemainingSec, refreshToken]);
34
+ useEffect(() => {
35
+ if (remainingSec <= 0) {
36
+ if (!endedRef.current) {
37
+ var _onCountdownEndRef$cu;
38
+ endedRef.current = true;
39
+ (_onCountdownEndRef$cu = onCountdownEndRef.current) === null || _onCountdownEndRef$cu === void 0 || _onCountdownEndRef$cu.call(onCountdownEndRef);
40
+ }
41
+ return undefined;
42
+ }
43
+ const timer = setInterval(() => {
44
+ setRemainingSec(prev => {
45
+ const next = prev - 1;
46
+ if (next <= 0) {
47
+ clearInterval(timer);
48
+ if (!endedRef.current) {
49
+ var _onCountdownEndRef$cu2;
50
+ endedRef.current = true;
51
+ (_onCountdownEndRef$cu2 = onCountdownEndRef.current) === null || _onCountdownEndRef$cu2 === void 0 || _onCountdownEndRef$cu2.call(onCountdownEndRef);
52
+ }
53
+ return 0;
54
+ }
55
+ return next;
56
+ });
57
+ }, 1000);
58
+ return () => clearInterval(timer);
59
+ }, [trialRemainingSec, refreshToken]);
60
+ const countdownText = formatCountdown(remainingSec);
61
+ return /*#__PURE__*/React.createElement(View, {
62
+ className: clsx('ipc-player-trial-badge', className)
63
+ }, /*#__PURE__*/React.createElement(Image, {
64
+ className: "ipc-player-trial-badge-icon",
65
+ src: tryOpen,
66
+ mode: "heightFix"
67
+ }), /*#__PURE__*/React.createElement(Text, {
68
+ className: "ipc-player-trial-badge-status"
69
+ }, Strings.getLang('ipc_player_trial_in_use')), /*#__PURE__*/React.createElement(Text, {
70
+ className: "ipc-player-trial-badge-divider"
71
+ }, "|"), /*#__PURE__*/React.createElement(Text, {
72
+ className: "ipc-player-trial-badge-preview"
73
+ }, `${countdownText} ${Strings.getLang('ipc_player_trial_preview_text')}`), /*#__PURE__*/React.createElement(View, {
74
+ className: "ipc-player-trial-badge-cta",
75
+ style: {
76
+ backgroundColor: brandColor
77
+ },
78
+ onClick: e => {
79
+ if (e && typeof e.stopPropagation === 'function') {
80
+ e.stopPropagation();
81
+ }
82
+ onSubscribe === null || onSubscribe === void 0 || onSubscribe();
83
+ }
84
+ }, /*#__PURE__*/React.createElement(Text, {
85
+ className: "ipc-player-trial-badge-cta-text"
86
+ }, Strings.getLang('ipc_player_trial_subscribe'))));
87
+ };
88
+ export { useTrialBadge } from './useTrialBadge';
@@ -0,0 +1,57 @@
1
+ .ipc-player-trial-badge {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ height: 28px;
5
+ padding: 0 4px 0 8px;
6
+ border-radius: 6px;
7
+ background: rgba(0, 0, 0, 0.65);
8
+ flex-shrink: 0;
9
+ vertical-align: middle;
10
+ white-space: nowrap;
11
+ }
12
+
13
+ .ipc-player-trial-badge-icon {
14
+ display: block;
15
+ height: 20px;
16
+ width: auto;
17
+ margin-right: 6px;
18
+ flex-shrink: 0;
19
+ }
20
+
21
+ .ipc-player-trial-badge-status {
22
+ font-size: 12px;
23
+ color: #ffffff;
24
+ font-weight: 500;
25
+ line-height: 1;
26
+ }
27
+
28
+ .ipc-player-trial-badge-divider {
29
+ margin: 0 6px;
30
+ font-size: 12px;
31
+ color: rgba(255, 255, 255, 0.45);
32
+ line-height: 1;
33
+ }
34
+
35
+ .ipc-player-trial-badge-preview {
36
+ font-size: 12px;
37
+ color: rgba(255, 255, 255, 0.78);
38
+ line-height: 1;
39
+ margin-right: 8px;
40
+ }
41
+
42
+ .ipc-player-trial-badge-cta {
43
+ display: inline-flex;
44
+ align-items: center;
45
+ justify-content: center;
46
+ height: 22px;
47
+ padding: 0 10px;
48
+ border-radius: 11px;
49
+ flex-shrink: 0;
50
+ }
51
+
52
+ .ipc-player-trial-badge-cta-text {
53
+ font-size: 12px;
54
+ color: #ffffff;
55
+ font-weight: 600;
56
+ line-height: 1;
57
+ }
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ import type { EventInstance } from '../../interface';
3
+ export declare const useTrialBadge: (event: EventInstance, devId: string, trialRemainingSec: number) => {
4
+ showTrialBadge: boolean;
5
+ setShowTrialBadge: import("react").Dispatch<import("react").SetStateAction<boolean>>;
6
+ handleTrialSubscribe: () => Promise<void>;
7
+ handleCountdownEnd: () => Promise<void>;
8
+ };
@@ -0,0 +1,42 @@
1
+ import { useCallback, useEffect, useState } from 'react';
2
+ import { setTrailFinish } from '../../utils/ttt';
3
+ import { gotoSecurityCloudService2 } from '../../utils';
4
+ import { trialCountdownEnd } from '../../ui/constant';
5
+ import Strings from '../../i18n';
6
+ export const useTrialBadge = (event, devId, trialRemainingSec) => {
7
+ const [showTrialBadge, setShowTrialBadge] = useState(false);
8
+ useEffect(() => {
9
+ if (trialRemainingSec > 0 && trialRemainingSec < 300) {
10
+ setShowTrialBadge(true);
11
+ }
12
+ }, [trialRemainingSec]);
13
+ const handleTrialSubscribe = useCallback(async () => {
14
+ try {
15
+ const res = await gotoSecurityCloudService2(devId);
16
+ console.log('res===gotoSecurityCloudService2', res);
17
+ } catch (error) {
18
+ ty.showToast({
19
+ title: Strings.getLang('ipc_player_fetch_error'),
20
+ icon: 'none'
21
+ });
22
+ }
23
+ }, [devId]);
24
+ const handleCountdownEnd = useCallback(async () => {
25
+ try {
26
+ setShowTrialBadge(false);
27
+ event.emit(trialCountdownEnd);
28
+ await setTrailFinish(devId);
29
+ } catch (error) {
30
+ ty.showToast({
31
+ title: Strings.getLang('ipc_player_fetch_error'),
32
+ icon: 'none'
33
+ });
34
+ }
35
+ }, [devId, event]);
36
+ return {
37
+ showTrialBadge,
38
+ setShowTrialBadge,
39
+ handleTrialSubscribe,
40
+ handleCountdownEnd
41
+ };
42
+ };
@@ -0,0 +1 @@
1
+ export * from './tryExperience';
@@ -0,0 +1 @@
1
+ export * from './tryExperience';
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { ComponentConfigProps } from '../../interface';
3
+ import './tryExperience.less';
4
+ type Props = ComponentConfigProps & {
5
+ className?: string;
6
+ hideTryExperienceMenu?: boolean;
7
+ buttonState?: number;
8
+ trialRemainingSec?: number;
9
+ isPurchase?: boolean;
10
+ canOpenSettings?: boolean;
11
+ isLowPhone?: boolean;
12
+ };
13
+ export declare const TryExperience: (props: Props) => React.JSX.Element | null;
14
+ export {};
@@ -0,0 +1,145 @@
1
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
+ import { View, Image, getSystemInfoSync, showToast } from '@ray-js/ray';
3
+ import clsx from 'clsx';
4
+ import React, { useState, useEffect, useCallback } from 'react';
5
+ import { useStore } from '../../ctx/store';
6
+ import Strings from '../../i18n';
7
+ import { getAIFrameFeature, gotoAIDrawMiniProgram, setAIFrameFeature } from '../../utils';
8
+ import { refreshSmartImageQualityEvent } from '../../ui/constant';
9
+ import tryZh from '../../res/try/try_zh.png';
10
+ import tryEn from '../../res/try/try_en.png';
11
+ import tryOpen from '../../res/try/try_open.png';
12
+ import tryClose from '../../res/try/try_close.png';
13
+ import './tryExperience.less';
14
+ /** ty.ipc.test1 返回的体验状态 */
15
+ var TryExperienceStatus = /*#__PURE__*/function (TryExperienceStatus) {
16
+ TryExperienceStatus[TryExperienceStatus["Default"] = 0] = "Default";
17
+ TryExperienceStatus[TryExperienceStatus["Open"] = 1] = "Open";
18
+ TryExperienceStatus[TryExperienceStatus["Close"] = 2] = "Close";
19
+ return TryExperienceStatus;
20
+ }(TryExperienceStatus || {});
21
+ const ZH_LANG_REGEX = /^zh(_|-|$)/i;
22
+ const getDefaultLangIcon = () => {
23
+ try {
24
+ const {
25
+ language = ''
26
+ } = getSystemInfoSync() || {};
27
+ return ZH_LANG_REGEX.test(String(language)) ? tryZh : tryEn;
28
+ } catch {
29
+ return tryEn;
30
+ }
31
+ };
32
+ const pickIconByStatus = buttonState => {
33
+ switch (buttonState) {
34
+ case TryExperienceStatus.Open:
35
+ return tryOpen;
36
+ case TryExperienceStatus.Close:
37
+ return tryClose;
38
+ case TryExperienceStatus.Default:
39
+ return getDefaultLangIcon();
40
+ default:
41
+ return '';
42
+ }
43
+ };
44
+ export const TryExperience = props => {
45
+ const {
46
+ className,
47
+ hideTryExperienceMenu,
48
+ buttonState,
49
+ trialRemainingSec,
50
+ isPurchase,
51
+ canOpenSettings,
52
+ isLowPhone,
53
+ devId
54
+ } = props;
55
+ const {
56
+ brandColor,
57
+ recording
58
+ } = useStore({
59
+ brandColor: props.brandColor,
60
+ recording: props.recording
61
+ });
62
+ const [imgSrc, setImgSrc] = useState();
63
+ useEffect(() => {
64
+ console.log('res===buttonState', buttonState);
65
+ if (isLowPhone) {
66
+ setImgSrc(tryClose);
67
+ } else if (buttonState) {
68
+ const iconUrl = pickIconByStatus(buttonState);
69
+ setImgSrc(iconUrl);
70
+ } else {
71
+ setImgSrc(undefined);
72
+ }
73
+ }, [buttonState]);
74
+ const onTryExperience = useCallback(async () => {
75
+ if (isLowPhone) {
76
+ showToast({
77
+ title: Strings.getLang('ipc_player_low_phone_not_support'),
78
+ icon: 'none'
79
+ });
80
+ return;
81
+ }
82
+ if (recording) {
83
+ showToast({
84
+ title: Strings.getLang('ipc_player_recording_now_tip'),
85
+ icon: 'none'
86
+ });
87
+ return;
88
+ }
89
+ try {
90
+ const getAI = await getAIFrameFeature(devId);
91
+ if (buttonState === TryExperienceStatus.Open) {
92
+ var _getAI$aiFrameFeature, _getAI$aiFrameFeature2, _getAI$aiFrameFeature3, _props$event;
93
+ const scope = _objectSpread(_objectSpread({}, (_getAI$aiFrameFeature = getAI.aiFrameFeature) === null || _getAI$aiFrameFeature === void 0 ? void 0 : _getAI$aiFrameFeature.scope), {}, {
94
+ inPreview: false
95
+ });
96
+ await setAIFrameFeature({
97
+ devId,
98
+ scene: 'inPreview',
99
+ // 实时预览场景
100
+ enabled: getAI.enabled,
101
+ aiFrameFeature: {
102
+ scope,
103
+ feature: (_getAI$aiFrameFeature2 = getAI.aiFrameFeature) === null || _getAI$aiFrameFeature2 === void 0 ? void 0 : _getAI$aiFrameFeature2.feature,
104
+ exportEnabled: (_getAI$aiFrameFeature3 = getAI.aiFrameFeature) === null || _getAI$aiFrameFeature3 === void 0 ? void 0 : _getAI$aiFrameFeature3.exportEnabled
105
+ }
106
+ });
107
+ (_props$event = props.event) === null || _props$event === void 0 || _props$event.emit(refreshSmartImageQualityEvent);
108
+ } else if (buttonState === TryExperienceStatus.Close && isPurchase || buttonState === TryExperienceStatus.Close && trialRemainingSec < 300 && trialRemainingSec > 0) {
109
+ var _getAI$aiFrameFeature4, _getAI$aiFrameFeature5, _getAI$aiFrameFeature6, _props$event2;
110
+ const scope = _objectSpread(_objectSpread({}, (_getAI$aiFrameFeature4 = getAI.aiFrameFeature) === null || _getAI$aiFrameFeature4 === void 0 ? void 0 : _getAI$aiFrameFeature4.scope), {}, {
111
+ inPreview: true
112
+ });
113
+ await setAIFrameFeature({
114
+ devId,
115
+ scene: 'inPreview',
116
+ // 实时预览场景
117
+ enabled: getAI.enabled,
118
+ aiFrameFeature: {
119
+ scope,
120
+ feature: (_getAI$aiFrameFeature5 = getAI.aiFrameFeature) === null || _getAI$aiFrameFeature5 === void 0 ? void 0 : _getAI$aiFrameFeature5.feature,
121
+ exportEnabled: (_getAI$aiFrameFeature6 = getAI.aiFrameFeature) === null || _getAI$aiFrameFeature6 === void 0 ? void 0 : _getAI$aiFrameFeature6.exportEnabled
122
+ }
123
+ });
124
+ (_props$event2 = props.event) === null || _props$event2 === void 0 || _props$event2.emit(refreshSmartImageQualityEvent);
125
+ } else {
126
+ gotoAIDrawMiniProgram(devId, brandColor);
127
+ }
128
+ } catch (error) {
129
+ //
130
+ }
131
+ }, [buttonState, recording, isPurchase, trialRemainingSec]);
132
+ if (hideTryExperienceMenu) {
133
+ return null;
134
+ }
135
+ return /*#__PURE__*/React.createElement(React.Fragment, null, imgSrc && canOpenSettings && /*#__PURE__*/React.createElement(View, {
136
+ className: clsx(className),
137
+ onClick: onTryExperience
138
+ }, /*#__PURE__*/React.createElement(View, {
139
+ className: "try-experience-box"
140
+ }, /*#__PURE__*/React.createElement(Image, {
141
+ className: "try-experience-icon",
142
+ src: imgSrc,
143
+ mode: "heightFix"
144
+ }))));
145
+ };
@@ -0,0 +1,13 @@
1
+ .try-experience-box {
2
+ display: inline-flex;
3
+ justify-content: center;
4
+ align-items: center;
5
+ min-height: calc(var(--iconBoxSize) * var(--ipc-player-size-scale, 1));
6
+ }
7
+
8
+ .try-experience-icon {
9
+ display: block;
10
+ height: calc(var(--iconBoxSize) * var(--ipc-player-size-scale, 1));
11
+ width: auto;
12
+ flex-shrink: 0;
13
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ray-js/ipc-player-integration",
3
- "version": "0.0.34",
3
+ "version": "0.0.35-beta.10",
4
4
  "description": "IPC 融合播放器",
5
5
  "main": "lib/index",
6
6
  "files": [
@@ -37,7 +37,7 @@
37
37
  "dependencies": {
38
38
  "@ray-js/direction-control": "^0.0.8",
39
39
  "@ray-js/ipc-ptz-zoom": "^0.0.3",
40
- "@ray-js/ray-ipc-player": "^2.1.0",
40
+ "@ray-js/ray-ipc-player": "2.1.1-beta.3",
41
41
  "@ray-js/ray-ipc-utils": "^1.1.15",
42
42
  "@ray-js/svg": "0.2.0",
43
43
  "clsx": "^1.2.1",
@@ -64,7 +64,7 @@
64
64
  "husky": {
65
65
  "hooks": {
66
66
  "commit-msg": "commitlint -E HUSKY_GIT_PARAMS --config commitlint.config.js",
67
- "pre-commit": "lint-staged"
67
+ "pre-commit": "node ./scripts/check-protected-files.js && lint-staged"
68
68
  }
69
69
  },
70
70
  "lint-staged": {