@ray-js/ipc-player-integration 0.0.53-beta.1 → 0.0.53-beta.11

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.
@@ -24,14 +24,33 @@ describe('getCaptureResultSummary', () => {
24
24
  }
25
25
  }
26
26
  });
27
- await expect(getCaptureResultSummary(createCaptureResult(basePath), undefined, 'dev-1')).resolves.toEqual({
27
+ await expect(getCaptureResultSummary(createCaptureResult(basePath), {
28
+ multiLens: true,
29
+ devId: 'dev-1'
30
+ })).resolves.toEqual({
28
31
  count: 4,
29
32
  isMultiLens: true,
30
33
  thumbnailPath: 'thingfile://tmp/capture_123_lens1.jpg'
31
34
  });
32
35
  });
33
- it('keeps the legacy path when the ability is unavailable', async () => {
34
- await expect(getCaptureResultSummary(createCaptureResult(basePath), 4, 'dev-1')).resolves.toEqual({
36
+ it('keeps the single-lens result for a legacy multi-camera device', async () => {
37
+ await expect(getCaptureResultSummary(createCaptureResult(basePath), {
38
+ multiLens: false,
39
+ protocolCount: 4,
40
+ devId: 'dev-1'
41
+ })).resolves.toEqual({
42
+ count: 1,
43
+ isMultiLens: false,
44
+ thumbnailPath: basePath
45
+ });
46
+ expect(mockGetDeviceInfo).not.toHaveBeenCalled();
47
+ });
48
+ it('uses the protocol count when the multi-lens mode is enabled', async () => {
49
+ await expect(getCaptureResultSummary(createCaptureResult(basePath), {
50
+ multiLens: true,
51
+ protocolCount: 4,
52
+ devId: 'dev-1'
53
+ })).resolves.toEqual({
35
54
  count: 4,
36
55
  isMultiLens: true,
37
56
  thumbnailPath: basePath
@@ -46,7 +65,11 @@ describe('getCaptureResultSummary', () => {
46
65
  }
47
66
  }
48
67
  });
49
- await expect(getCaptureResultSummary(createCaptureResult(basePath), 4, 'dev-1')).resolves.toEqual({
68
+ await expect(getCaptureResultSummary(createCaptureResult(basePath), {
69
+ multiLens: true,
70
+ protocolCount: 4,
71
+ devId: 'dev-1'
72
+ })).resolves.toEqual({
50
73
  count: 4,
51
74
  isMultiLens: true,
52
75
  thumbnailPath: 'thingfile://tmp/capture_123_lens1.jpg'
@@ -61,29 +84,33 @@ describe('getCaptureResultSummary', () => {
61
84
  }
62
85
  });
63
86
  const path = 'thingfile://tmp/capture_123_lens1.jpg';
64
- await expect(getCaptureResultSummary(createCaptureResult(path), undefined, 'dev-1')).resolves.toEqual({
87
+ await expect(getCaptureResultSummary(createCaptureResult(path), {
88
+ multiLens: true,
89
+ devId: 'dev-1'
90
+ })).resolves.toEqual({
65
91
  count: 4,
66
92
  isMultiLens: true,
67
93
  thumbnailPath: path
68
94
  });
69
95
  });
70
96
  it('keeps a mono result unchanged', async () => {
71
- await expect(getCaptureResultSummary(createCaptureResult(basePath), undefined, 'dev-1')).resolves.toEqual({
97
+ await expect(getCaptureResultSummary(createCaptureResult(basePath), {
98
+ multiLens: false,
99
+ devId: 'dev-1'
100
+ })).resolves.toEqual({
72
101
  count: 1,
73
102
  isMultiLens: false,
74
103
  thumbnailPath: basePath
75
104
  });
76
105
  });
77
- it('keeps item paths unchanged', async () => {
78
- await expect(getCaptureResultSummary({
79
- items: [{
80
- index: 1,
81
- tempImagePath: basePath,
82
- filePath: basePath
83
- }]
84
- }, undefined, 'dev-1')).resolves.toEqual({
106
+ it('keeps a single-lens result when multi-lens mode has one lens', async () => {
107
+ await expect(getCaptureResultSummary(createCaptureResult(basePath), {
108
+ multiLens: true,
109
+ protocolCount: 1,
110
+ devId: 'dev-1'
111
+ })).resolves.toEqual({
85
112
  count: 1,
86
- isMultiLens: true,
113
+ isMultiLens: false,
87
114
  thumbnailPath: basePath
88
115
  });
89
116
  });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,75 @@
1
+ import { ClarityType } from '@ray-js/ray-ipc-utils/lib/interface';
2
+ import { getCachedAutoClarity, setCachedAutoClarity, subscribeClarityChanged } from './ttt';
3
+ jest.mock('@ray-js/ray-ipc-utils/lib/interface', () => ({
4
+ ClarityType: {
5
+ SS: 'SS',
6
+ SD: 'SD',
7
+ HD: 'HD',
8
+ UD: 'UD',
9
+ SSP: 'SSP',
10
+ AUTO: 'AUTO',
11
+ AUDIO: 'AUDIO'
12
+ }
13
+ }));
14
+ describe('auto clarity cache and listener', () => {
15
+ const storage = new Map();
16
+ let listener;
17
+ beforeEach(() => {
18
+ storage.clear();
19
+ globalThis.ty = {
20
+ getStorageSync: jest.fn(_ref => {
21
+ let {
22
+ key
23
+ } = _ref;
24
+ return storage.get(key);
25
+ }),
26
+ setStorageSync: jest.fn(_ref2 => {
27
+ let {
28
+ key,
29
+ data
30
+ } = _ref2;
31
+ return storage.set(key, data);
32
+ }),
33
+ ipc: {
34
+ onClarityChanged: jest.fn(callback => {
35
+ listener = callback;
36
+ }),
37
+ offClarityChanged: jest.fn()
38
+ }
39
+ };
40
+ });
41
+ it('restores the last reported actual clarity only for its device', () => {
42
+ setCachedAutoClarity('camera-1', ClarityType.HD);
43
+ expect(getCachedAutoClarity('camera-1')).toBe(ClarityType.HD);
44
+ expect(getCachedAutoClarity('camera-2')).toBeNull();
45
+ setCachedAutoClarity('camera-1', ClarityType.AUTO);
46
+ expect(getCachedAutoClarity('camera-1')).toBe(ClarityType.HD);
47
+ globalThis.ty.getStorageSync = jest.fn(() => ({
48
+ data: ClarityType.SD
49
+ }));
50
+ expect(getCachedAutoClarity('camera-1')).toBe(ClarityType.SD);
51
+ });
52
+ it('accepts a new actual clarity report for the same device', () => {
53
+ const handler = jest.fn();
54
+ const unsubscribe = subscribeClarityChanged('camera-1', handler);
55
+ listener({
56
+ deviceId: 'camera-2',
57
+ clarity: ClarityType.SD
58
+ });
59
+ listener({
60
+ deviceId: 'camera-1',
61
+ clarity: ClarityType.AUTO
62
+ });
63
+ listener({
64
+ deviceId: 'camera-1',
65
+ clarity: ClarityType.SD
66
+ });
67
+ expect(handler).toHaveBeenCalledTimes(1);
68
+ expect(handler).toHaveBeenCalledWith({
69
+ deviceId: 'camera-1',
70
+ clarity: ClarityType.SD
71
+ });
72
+ unsubscribe();
73
+ expect(globalThis.ty.ipc.offClarityChanged).toHaveBeenCalledWith(listener);
74
+ });
75
+ });
@@ -1,3 +1,4 @@
1
+ import { ClarityType } from '@ray-js/ray-ipc-utils/lib/interface';
1
2
  export type SmartImageQualityResult = {
2
3
  isPurchase: boolean;
3
4
  buttonState: number;
@@ -48,6 +49,19 @@ export declare function notifyOfflineShown(deviceId: string): boolean;
48
49
  export declare function getNgRawData(): Promise<unknown>;
49
50
  export declare function isClarityChangedSupported(): boolean;
50
51
  export type ClarityChangedResult = {
51
- clarity: 'HD' | 'SD';
52
+ deviceId?: string;
53
+ clarity: ClarityType;
52
54
  };
53
- export declare function clarityChanged(devId: string): Promise<ClarityChangedResult | null>;
55
+ export type ClarityChangedHandler = (result: ClarityChangedResult) => void;
56
+ type ClarityChangedListener = (payload: ClarityChangedResult) => void;
57
+ export declare function getCachedAutoClarity(devId: string): ClarityType | null;
58
+ export declare function setCachedAutoClarity(devId: string, clarity: ClarityType): void;
59
+ export declare function offClarityChanged(listener: ClarityChangedListener): void;
60
+ /**
61
+ * 监听自动清晰度变化,返回取消监听函数。
62
+ *
63
+ * onClarityChanged / offClarityChanged 均使用同一个 listener 引用,
64
+ * 否则宿主无法正确移除监听。
65
+ */
66
+ export declare function subscribeClarityChanged(devId: string, handler: ClarityChangedHandler): () => void;
67
+ export {};
package/lib/utils/ttt.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
+ import { ClarityType } from '@ray-js/ray-ipc-utils/lib/interface';
2
3
  export function getSmartImageQualityState(devId) {
3
4
  return new Promise(resolve => {
4
5
  var _ty$ipc;
@@ -165,35 +166,87 @@ export function getNgRawData() {
165
166
  });
166
167
  }
167
168
 
168
- // 是否支持自动清晰度(ttt 方法 clarityChanged 存在即支持)
169
+ // 是否支持自动清晰度(ttt 方法 onClarityChanged 存在即支持)
169
170
  export function isClarityChangedSupported() {
170
- var _ty$ipc6;
171
- return typeof ((_ty$ipc6 = ty.ipc) === null || _ty$ipc6 === void 0 ? void 0 : _ty$ipc6.clarityChanged) === 'function';
171
+ var _ty5;
172
+ return typeof ty !== 'undefined' && typeof ((_ty5 = ty) === null || _ty5 === void 0 || (_ty5 = _ty5.ipc) === null || _ty5 === void 0 ? void 0 : _ty5.onClarityChanged) === 'function';
172
173
  }
173
- export function clarityChanged(devId) {
174
- return new Promise(resolve => {
175
- var _ty$ipc7;
176
- if (typeof ((_ty$ipc7 = ty.ipc) === null || _ty$ipc7 === void 0 ? void 0 : _ty$ipc7.clarityChanged) !== 'function') {
177
- resolve(null);
174
+ const actualClarityTypes = [ClarityType.SS, ClarityType.SD, ClarityType.HD, ClarityType.UD, ClarityType.SSP];
175
+ const autoClarityStorageKey = devId => `${devId}_auto_clarity`;
176
+ export function getCachedAutoClarity(devId) {
177
+ try {
178
+ const stored = ty.getStorageSync({
179
+ key: autoClarityStorageKey(devId)
180
+ });
181
+ const clarity = typeof stored === 'string' ? stored : stored === null || stored === void 0 ? void 0 : stored.data;
182
+ return actualClarityTypes.includes(clarity) ? clarity : null;
183
+ } catch (error) {
184
+ return null;
185
+ }
186
+ }
187
+ export function setCachedAutoClarity(devId, clarity) {
188
+ if (!actualClarityTypes.includes(clarity)) return;
189
+ try {
190
+ ty.setStorageSync({
191
+ key: autoClarityStorageKey(devId),
192
+ data: clarity
193
+ });
194
+ } catch (error) {
195
+ console.warn('res===setCachedAutoClarity fail', error);
196
+ }
197
+ }
198
+ export function offClarityChanged(listener) {
199
+ var _ty6;
200
+ const ipc = typeof ty !== 'undefined' ? (_ty6 = ty) === null || _ty6 === void 0 ? void 0 : _ty6.ipc : undefined;
201
+ if (!ipc || typeof ipc.offClarityChanged !== 'function') {
202
+ return;
203
+ }
204
+ try {
205
+ ipc.offClarityChanged(listener);
206
+ } catch (error) {
207
+ console.warn('res===offClarityChanged fail', error);
208
+ }
209
+ }
210
+
211
+ /**
212
+ * 监听自动清晰度变化,返回取消监听函数。
213
+ *
214
+ * onClarityChanged / offClarityChanged 均使用同一个 listener 引用,
215
+ * 否则宿主无法正确移除监听。
216
+ */
217
+ export function subscribeClarityChanged(devId, handler) {
218
+ var _ty7;
219
+ const ipc = typeof ty !== 'undefined' ? (_ty7 = ty) === null || _ty7 === void 0 ? void 0 : _ty7.ipc : undefined;
220
+ if (!ipc || typeof ipc.onClarityChanged !== 'function') {
221
+ return () => undefined;
222
+ }
223
+ const listener = payload => {
224
+ console.log('[resolution] onClarityChanged 事件到达', JSON.stringify(payload !== null && payload !== void 0 ? payload : null));
225
+ const {
226
+ deviceId,
227
+ clarity
228
+ } = payload || {};
229
+ if (!actualClarityTypes.includes(clarity)) {
230
+ console.warn('[resolution] onClarityChanged 未返回实际清晰度');
178
231
  return;
179
232
  }
180
- if (!isClarityChangedSupported()) {
181
- resolve(null);
233
+ // 一页多设备时只认自己的;宿主没带 deviceId 就不过滤
234
+ if (deviceId && deviceId !== devId) {
235
+ console.warn('[resolution] onClarityChanged 非本设备,已忽略', `${deviceId} != ${devId}`);
182
236
  return;
183
237
  }
184
- try {
185
- ty.ipc.clarityChanged({
186
- devId,
187
- success: res => {
188
- resolve(res !== null && res !== void 0 ? res : null);
189
- },
190
- fail: e => {
191
- console.warn('res===clarityChanged fail', e);
192
- resolve(null);
193
- }
194
- });
195
- } catch (e) {
196
- resolve(null);
197
- }
198
- });
238
+ handler({
239
+ deviceId,
240
+ clarity
241
+ });
242
+ };
243
+ try {
244
+ ipc.onClarityChanged(listener);
245
+ } catch (error) {
246
+ console.warn('res===onClarityChanged fail', error);
247
+ return () => undefined;
248
+ }
249
+ return () => {
250
+ offClarityChanged(listener);
251
+ };
199
252
  }
@@ -1,11 +1,9 @@
1
- import "core-js/modules/esnext.iterator.constructor.js";
2
- import "core-js/modules/esnext.iterator.map.js";
3
1
  import React from 'react';
4
2
  import { Image, Text, View } from '@ray-js/ray';
5
3
  import clsx from 'clsx';
6
4
  import Strings from '../../i18n';
7
5
  import './captureResult.less';
8
- const THUMBNAIL_LAYERS = ['back', 'middle', 'front'];
6
+ const BACKDROP_LAYERS = ['back', 'middle'];
9
7
  const TEXT_KEYS = {
10
8
  record: {
11
9
  check: 'ipc_player_record_success_check',
@@ -59,14 +57,12 @@ export function CaptureResultToast(_ref) {
59
57
  className: clsx('ipc-player-plugin-capture-result-toast', legacyCls.toast, className)
60
58
  }, /*#__PURE__*/React.createElement(View, {
61
59
  className: clsx('ipc-player-plugin-capture-result-image-box', legacyCls.imageBox, isMultiLens && ['ipc-player-plugin-capture-result-image-box-multi', legacyCls.imageBoxMulti])
62
- }, isMultiLens ? THUMBNAIL_LAYERS.slice(0, count).map((layer, index) => /*#__PURE__*/React.createElement(Image, {
60
+ }, isMultiLens ? /*#__PURE__*/React.createElement(React.Fragment, null, BACKDROP_LAYERS.map(layer => /*#__PURE__*/React.createElement(View, {
63
61
  key: layer,
64
- className: imageClassName,
65
- src: thumbnailPath,
66
- style: {
67
- left: `${index * 5}px`,
68
- zIndex: index + 1
69
- }
62
+ className: clsx('ipc-player-plugin-capture-result-backdrop', `ipc-player-plugin-capture-result-image-${layer}`)
63
+ })), /*#__PURE__*/React.createElement(Image, {
64
+ className: clsx(imageClassName, 'ipc-player-plugin-capture-result-image-front'),
65
+ src: thumbnailPath
70
66
  })) : /*#__PURE__*/React.createElement(Image, {
71
67
  className: imageClassName,
72
68
  src: thumbnailPath
@@ -1,22 +1,36 @@
1
1
  .ipc-player-plugin-capture-result-toast,
2
2
  .ipc-player-plugin-record-success-toast,
3
3
  .ipc-player-plugin-screenshot-toast {
4
+ --capture-result-text-color: var(--fontColor, #fff);
5
+ --capture-result-near-backdrop-color: rgba(255, 255, 255, 0.2);
6
+ --capture-result-far-backdrop-color: rgba(255, 255, 255, 0.1);
7
+
4
8
  z-index: 100;
5
9
  display: flex;
6
10
  flex: 1;
7
11
  align-items: center;
8
- padding: calc(8px * var(--ipc-player-size-scale, 1))
12
+ padding: calc(7px * var(--ipc-player-size-scale, 1))
13
+ calc(16px * var(--ipc-player-size-scale, 1))
14
+ calc(7px * var(--ipc-player-size-scale, 1))
9
15
  calc(12px * var(--ipc-player-size-scale, 1));
10
16
  background-color: var(--shot-card-bg-color);
11
17
  border-radius: calc(8px * var(--ipc-player-size-scale, 1));
12
18
  }
13
19
 
20
+ :root[theme='light'] .ipc-player-plugin-capture-result-toast {
21
+ --capture-result-text-color: #1a1a1a;
22
+ --capture-result-near-backdrop-color: rgba(0, 0, 0, 0.1);
23
+ --capture-result-far-backdrop-color: rgba(0, 0, 0, 0.05);
24
+
25
+ background-color: #fff;
26
+ }
27
+
14
28
  .ipc-player-plugin-capture-result-image-box,
15
29
  .ipc-player-plugin-record-success-toast-image-box,
16
30
  .ipc-player-plugin-screenshot-toast-image-box {
17
31
  position: relative;
18
32
  width: calc(66px * var(--ipc-player-size-scale, 1));
19
- height: calc(66px * 0.57 * var(--ipc-player-size-scale, 1));
33
+ height: calc(39px * var(--ipc-player-size-scale, 1));
20
34
  overflow: hidden;
21
35
  border-radius: calc(4px * var(--ipc-player-size-scale, 1));
22
36
  }
@@ -29,17 +43,39 @@
29
43
  object-fit: cover;
30
44
  }
31
45
 
32
- .ipc-player-plugin-capture-result-image-box-multi .ipc-player-plugin-capture-result-image,
33
- .ipc-player-plugin-record-success-toast-image-box-multi .ipc-player-plugin-record-success-toast-image,
34
- .ipc-player-plugin-screenshot-toast-image-box-multi .ipc-player-plugin-screenshot-toast-image {
46
+ .ipc-player-plugin-capture-result-backdrop,
47
+ .ipc-player-plugin-capture-result-image-front {
35
48
  position: absolute;
36
- top: 0;
37
- width: calc(56px * var(--ipc-player-size-scale, 1));
38
49
  box-sizing: border-box;
39
- border: 1px solid var(--shot-card-bg-color);
40
50
  border-radius: calc(4px * var(--ipc-player-size-scale, 1));
41
51
  }
42
52
 
53
+ .ipc-player-plugin-capture-result-image-back {
54
+ top: calc(1px * var(--ipc-player-size-scale, 1));
55
+ left: calc(5px * var(--ipc-player-size-scale, 1));
56
+ z-index: 1;
57
+ width: calc(56px * var(--ipc-player-size-scale, 1));
58
+ height: calc(28px * var(--ipc-player-size-scale, 1));
59
+ background: var(--capture-result-far-backdrop-color);
60
+ }
61
+
62
+ .ipc-player-plugin-capture-result-image-middle {
63
+ top: calc(3px * var(--ipc-player-size-scale, 1));
64
+ left: calc(2.5px * var(--ipc-player-size-scale, 1));
65
+ z-index: 2;
66
+ width: calc(61px * var(--ipc-player-size-scale, 1));
67
+ height: calc(30.5px * var(--ipc-player-size-scale, 1));
68
+ background: var(--capture-result-near-backdrop-color);
69
+ }
70
+
71
+ .ipc-player-plugin-capture-result-image-front {
72
+ top: calc(5px * var(--ipc-player-size-scale, 1));
73
+ left: 0;
74
+ z-index: 3;
75
+ width: calc(66px * var(--ipc-player-size-scale, 1));
76
+ height: calc(33px * var(--ipc-player-size-scale, 1));
77
+ }
78
+
43
79
  .ipc-player-plugin-capture-result-play-icon-box,
44
80
  .ipc-player-plugin-record-success-play-icon-box {
45
81
  position: absolute;
@@ -49,18 +85,23 @@
49
85
  display: flex;
50
86
  align-items: center;
51
87
  justify-content: center;
52
- width: 30px;
53
- height: 30px;
88
+ width: calc(16px * var(--ipc-player-size-scale, 1));
89
+ height: calc(16px * var(--ipc-player-size-scale, 1));
54
90
  overflow: hidden;
55
91
  background-color: rgba(0, 0, 0, 0.2);
56
92
  border-radius: 50%;
57
93
  transform: translate(-50%, -50%);
58
94
  }
59
95
 
96
+ .ipc-player-plugin-capture-result-image-box-multi
97
+ .ipc-player-plugin-capture-result-play-icon-box {
98
+ top: calc(50% + 2px * var(--ipc-player-size-scale, 1));
99
+ }
100
+
60
101
  .ipc-player-plugin-capture-result-play-icon,
61
102
  .ipc-player-plugin-record-success-play-icon {
62
103
  color: #ffffff;
63
- font-size: calc(18px * var(--ipc-player-size-scale, 1)) !important;
104
+ font-size: calc(9px * var(--ipc-player-size-scale, 1)) !important;
64
105
  }
65
106
 
66
107
  .ipc-player-plugin-capture-result-title,
@@ -69,17 +110,20 @@
69
110
  display: flex;
70
111
  flex: 1;
71
112
  flex-direction: column;
113
+ min-width: 0;
72
114
  margin-right: calc(12px * var(--ipc-player-size-scale, 1));
73
- margin-left: calc(12px * var(--ipc-player-size-scale, 1));
74
- color: var(--fontColor);
115
+ margin-left: calc(8px * var(--ipc-player-size-scale, 1));
116
+ color: var(--capture-result-text-color, var(--fontColor));
75
117
  font-size: calc(14px * var(--ipc-player-size-scale, 1));
118
+ line-height: calc(20px * var(--ipc-player-size-scale, 1));
76
119
  word-break: break-word;
77
120
  }
78
121
 
79
122
  .ipc-player-plugin-capture-result-count {
80
123
  margin-top: calc(2px * var(--ipc-player-size-scale, 1));
81
- color: var(--fontColor);
124
+ color: var(--capture-result-text-color, var(--fontColor));
82
125
  font-size: calc(12px * var(--ipc-player-size-scale, 1));
126
+ line-height: calc(17px * var(--ipc-player-size-scale, 1));
83
127
  opacity: 0.5;
84
128
  }
85
129
 
@@ -88,6 +132,7 @@
88
132
  .ipc-player-plugin-screenshot-toast-bottom {
89
133
  min-width: calc(52px * var(--ipc-player-size-scale, 1));
90
134
  max-width: calc(100px * var(--ipc-player-size-scale, 1));
135
+ flex-shrink: 0;
91
136
  padding: calc(5px * var(--ipc-player-size-scale, 1))
92
137
  calc(11px * var(--ipc-player-size-scale, 1));
93
138
  overflow: hidden;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,80 @@
1
+ import React from 'react';
2
+ import { renderToStaticMarkup } from 'react-dom/server';
3
+ jest.mock('@ray-js/ray', () => {
4
+ const React = require('react');
5
+ return {
6
+ Image: _ref => {
7
+ let {
8
+ className,
9
+ src
10
+ } = _ref;
11
+ return /*#__PURE__*/React.createElement("img", {
12
+ alt: "",
13
+ className: className,
14
+ src: src
15
+ });
16
+ },
17
+ Text: _ref2 => {
18
+ let {
19
+ children,
20
+ className
21
+ } = _ref2;
22
+ return /*#__PURE__*/React.createElement("span", {
23
+ className: className
24
+ }, children);
25
+ },
26
+ View: _ref3 => {
27
+ let {
28
+ children,
29
+ className
30
+ } = _ref3;
31
+ return /*#__PURE__*/React.createElement("div", {
32
+ className: className
33
+ }, children);
34
+ }
35
+ };
36
+ });
37
+ jest.mock('../../i18n', () => ({
38
+ __esModule: true,
39
+ default: {
40
+ getLang: key => key,
41
+ formatString: (template, count) => `${template}:${count}`
42
+ }
43
+ }));
44
+ jest.mock('./captureResult.less', () => ({}));
45
+ const {
46
+ CaptureResultToast
47
+ } = require('./captureResult');
48
+ const renderToast = count => renderToStaticMarkup(/*#__PURE__*/React.createElement(CaptureResultToast, {
49
+ brandColor: "#ff592a",
50
+ count: count,
51
+ kind: "screenshot",
52
+ onCheck: () => undefined,
53
+ thumbnailPath: "thingfile://capture.jpg"
54
+ }));
55
+ const countClass = (markup, className) => [...markup.matchAll(/class="([^"]*)"/g)].filter(_ref4 => {
56
+ let [, names] = _ref4;
57
+ return names.split(/\s+/).includes(className);
58
+ }).length;
59
+ describe('CaptureResultToast', () => {
60
+ it('keeps the single-item thumbnail unchanged', () => {
61
+ const markup = renderToast(1);
62
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-backdrop')).toBe(0);
63
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-image-front')).toBe(0);
64
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-image')).toBe(1);
65
+ });
66
+ it('renders both backdrops for two captured items', () => {
67
+ const markup = renderToast(2);
68
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-backdrop')).toBe(2);
69
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-image-back')).toBe(1);
70
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-image-middle')).toBe(1);
71
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-image-front')).toBe(1);
72
+ });
73
+ it('caps the backdrop count at two', () => {
74
+ const markup = renderToast(4);
75
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-backdrop')).toBe(2);
76
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-image-back')).toBe(1);
77
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-image-middle')).toBe(1);
78
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-image-front')).toBe(1);
79
+ });
80
+ });
@@ -117,7 +117,11 @@ export function RecordVideo(props) {
117
117
  var _props$multiCameraCtx;
118
118
  const requestId = ++recordResultRequestIdRef.current;
119
119
  const splitNum = (_props$multiCameraCtx = props.multiCameraCtx) === null || _props$multiCameraCtx === void 0 || (_props$multiCameraCtx = _props$multiCameraCtx.protocol) === null || _props$multiCameraCtx === void 0 ? void 0 : _props$multiCameraCtx.total_split_num;
120
- const summary = await getCaptureResultSummary(recordInfo, splitNum, devId);
120
+ const summary = await getCaptureResultSummary(recordInfo, {
121
+ multiLens: props.multiLens,
122
+ protocolCount: splitNum,
123
+ devId
124
+ });
121
125
  if (requestId !== recordResultRequestIdRef.current) return;
122
126
  if (!summary) return;
123
127
  setState({
@@ -1,19 +1,16 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import { View, Text } from '@ray-js/ray';
3
3
  import clsx from 'clsx';
4
- import React, { useContext, useEffect } from 'react';
4
+ import React, { useContext } from 'react';
5
5
  import { useMemoizedFn } from 'ahooks';
6
- import { ClarityType } from '@ray-js/ray-ipc-utils/lib/interface';
7
6
  import Strings from '../../i18n';
8
7
  import { FullResolutionControl } from './fullResolutionControl';
9
- import { fullResolutionId, pauseTimeToHideAllComponent, hideAllComponent, widgetLabs, widgetClick, autoClarityChange } from '../../ui/constant';
8
+ import { fullResolutionId, pauseTimeToHideAllComponent, hideAllComponent, widgetLabs, widgetClick } from '../../ui/constant';
10
9
  import { UIEventContext } from '../../ui/context';
11
10
  import { useStore } from '../../ctx/store';
12
- import { clarityChanged } from '../../utils/ttt';
13
11
  import './resolution.less';
14
12
  export const Resolution = props => {
15
13
  const {
16
- devId,
17
14
  setResolution,
18
15
  addContent,
19
16
  hasContent,
@@ -31,30 +28,6 @@ export const Resolution = props => {
31
28
  const {
32
29
  event
33
30
  } = useContext(UIEventContext);
34
-
35
- // 广播自动清晰度状态给 VideoBitKBP 等监听方;
36
- // 自动模式下读取一次当前实际清晰度,仅用于码率区域展示。
37
- useEffect(() => {
38
- const emitClarity = (enabled, clarity) => {
39
- event.emit(autoClarityChange, {
40
- enabled,
41
- clarity
42
- });
43
- };
44
- if (resolution !== ClarityType.AUTO) {
45
- emitClarity(false, null);
46
- return;
47
- }
48
- emitClarity(true, null);
49
- if (devId) {
50
- clarityChanged(devId).then(res => {
51
- if (res !== null && res !== void 0 && res.clarity) {
52
- emitClarity(true, res.clarity);
53
- }
54
- });
55
- }
56
- // eslint-disable-next-line react-hooks/exhaustive-deps
57
- }, [devId, resolution]);
58
31
  const onResolution = useMemoizedFn(() => {
59
32
  event.emit(widgetClick, {
60
33
  widgetId: widgetLabs.RESOLUTION
@@ -139,7 +139,11 @@ export function Screenshot(props) {
139
139
  var _props$multiCameraCtx;
140
140
  setIgnoreHideStopPreview(false);
141
141
  const splitNum = (_props$multiCameraCtx = props.multiCameraCtx) === null || _props$multiCameraCtx === void 0 || (_props$multiCameraCtx = _props$multiCameraCtx.protocol) === null || _props$multiCameraCtx === void 0 ? void 0 : _props$multiCameraCtx.total_split_num;
142
- const summary = await getCaptureResultSummary(res, splitNum, devId);
142
+ const summary = await getCaptureResultSummary(res, {
143
+ multiLens: props.multiLens,
144
+ protocolCount: splitNum,
145
+ devId
146
+ });
143
147
  if (requestId !== snapshotRequestIdRef.current) return;
144
148
  if (!summary) {
145
149
  handleSnapshotFail({});