@midscene/visualizer 0.30.10 → 0.30.11-beta-20251218071621.0

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 (123) hide show
  1. package/dist/es/component/blackboard/index.css +8 -0
  2. package/dist/es/component/blackboard/index.mjs +137 -68
  3. package/dist/es/component/config-selector/index.mjs +102 -4
  4. package/dist/es/component/context-preview/index.mjs +1 -2
  5. package/dist/es/component/env-config/index.mjs +1 -2
  6. package/dist/es/component/env-config-reminder/index.css +8 -0
  7. package/dist/es/component/env-config-reminder/index.mjs +1 -2
  8. package/dist/es/component/form-field/index.mjs +5 -10
  9. package/dist/es/component/history-selector/index.css +38 -1
  10. package/dist/es/component/history-selector/index.mjs +1 -2
  11. package/dist/es/component/logo/index.mjs +7 -3
  12. package/dist/es/component/misc/index.mjs +1 -4
  13. package/dist/es/component/nav-actions/index.mjs +1 -2
  14. package/dist/es/component/nav-actions/style.css +1 -1
  15. package/dist/es/component/player/index.css +26 -0
  16. package/dist/es/component/player/index.mjs +376 -364
  17. package/dist/es/component/playground/index.css +291 -31
  18. package/dist/es/component/playground-result/index.css +10 -0
  19. package/dist/es/component/playground-result/index.mjs +129 -10
  20. package/dist/es/component/prompt-input/index.css +281 -31
  21. package/dist/es/component/prompt-input/index.mjs +83 -25
  22. package/dist/es/component/screenshot-viewer/index.css +214 -0
  23. package/dist/es/component/screenshot-viewer/index.mjs +282 -0
  24. package/dist/es/component/service-mode-control/index.mjs +1 -2
  25. package/dist/es/component/shiny-text/index.css +35 -3
  26. package/dist/es/component/shiny-text/index.mjs +3 -3
  27. package/dist/es/component/universal-playground/index.css +61 -1
  28. package/dist/es/component/universal-playground/index.mjs +106 -83
  29. package/dist/es/component/universal-playground/providers/context-provider.mjs +56 -18
  30. package/dist/es/component/universal-playground/providers/indexeddb-storage-provider.mjs +213 -139
  31. package/dist/es/component/universal-playground/providers/storage-provider.mjs +199 -121
  32. package/dist/es/hooks/usePlaygroundExecution.mjs +297 -146
  33. package/dist/es/hooks/usePlaygroundState.mjs +141 -75
  34. package/dist/es/hooks/useSafeOverrideAIConfig.mjs +2 -6
  35. package/dist/es/hooks/useServerValid.mjs +37 -12
  36. package/dist/es/hooks/useTheme.mjs +25 -0
  37. package/dist/es/icons/avatar.mjs +46 -4
  38. package/dist/es/icons/close.mjs +46 -4
  39. package/dist/es/icons/global-perspective.mjs +47 -5
  40. package/dist/es/icons/history.mjs +48 -6
  41. package/dist/es/icons/magnifying-glass.mjs +47 -5
  42. package/dist/es/icons/player-setting.mjs +48 -6
  43. package/dist/es/icons/setting.mjs +47 -5
  44. package/dist/es/icons/show-marker.mjs +47 -5
  45. package/dist/es/index.mjs +4 -4
  46. package/dist/es/store/history.mjs +46 -7
  47. package/dist/es/store/store.mjs +68 -2
  48. package/dist/es/types.mjs +1 -1
  49. package/dist/es/utils/constants.mjs +7 -3
  50. package/dist/es/utils/index.mjs +4 -1
  51. package/dist/es/utils/pixi-loader.mjs +37 -11
  52. package/dist/es/utils/replay-scripts.mjs +160 -111
  53. package/dist/lib/component/blackboard/index.css +8 -0
  54. package/dist/lib/component/blackboard/index.js +139 -70
  55. package/dist/lib/component/config-selector/index.js +103 -5
  56. package/dist/lib/component/context-preview/index.js +3 -4
  57. package/dist/lib/component/env-config/index.js +3 -4
  58. package/dist/lib/component/env-config-reminder/index.css +8 -0
  59. package/dist/lib/component/env-config-reminder/index.js +3 -4
  60. package/dist/lib/component/form-field/index.js +10 -15
  61. package/dist/lib/component/history-selector/index.css +38 -1
  62. package/dist/lib/component/history-selector/index.js +3 -4
  63. package/dist/lib/component/index.js +6 -8
  64. package/dist/lib/component/logo/index.js +9 -5
  65. package/dist/lib/component/misc/index.js +6 -9
  66. package/dist/lib/component/nav-actions/index.js +3 -4
  67. package/dist/lib/component/nav-actions/style.css +1 -1
  68. package/dist/lib/component/player/index.css +26 -0
  69. package/dist/lib/component/player/index.js +376 -365
  70. package/dist/lib/component/playground/index.css +291 -31
  71. package/dist/lib/component/playground/index.js +31 -33
  72. package/dist/lib/component/playground-result/index.css +10 -0
  73. package/dist/lib/component/playground-result/index.js +131 -12
  74. package/dist/lib/component/prompt-input/index.css +281 -31
  75. package/dist/lib/component/prompt-input/index.js +84 -26
  76. package/dist/lib/component/screenshot-viewer/index.css +214 -0
  77. package/dist/lib/component/screenshot-viewer/index.js +316 -0
  78. package/dist/lib/component/service-mode-control/index.js +3 -4
  79. package/dist/lib/component/shiny-text/index.css +35 -3
  80. package/dist/lib/component/shiny-text/index.js +5 -5
  81. package/dist/lib/component/universal-playground/index.css +61 -1
  82. package/dist/lib/component/universal-playground/index.js +108 -84
  83. package/dist/lib/component/universal-playground/providers/context-provider.js +58 -20
  84. package/dist/lib/component/universal-playground/providers/indexeddb-storage-provider.js +217 -143
  85. package/dist/lib/component/universal-playground/providers/storage-provider.js +207 -129
  86. package/dist/lib/hooks/usePlaygroundExecution.js +299 -148
  87. package/dist/lib/hooks/usePlaygroundState.js +143 -77
  88. package/dist/lib/hooks/useSafeOverrideAIConfig.js +4 -8
  89. package/dist/lib/hooks/useServerValid.js +39 -14
  90. package/dist/lib/hooks/useTheme.js +59 -0
  91. package/dist/lib/icons/avatar.js +48 -6
  92. package/dist/lib/icons/close.js +48 -6
  93. package/dist/lib/icons/global-perspective.js +49 -7
  94. package/dist/lib/icons/history.js +50 -8
  95. package/dist/lib/icons/magnifying-glass.js +49 -7
  96. package/dist/lib/icons/player-setting.js +50 -8
  97. package/dist/lib/icons/setting.js +49 -7
  98. package/dist/lib/icons/show-marker.js +49 -7
  99. package/dist/lib/index.js +44 -34
  100. package/dist/lib/store/history.js +48 -9
  101. package/dist/lib/store/store.js +74 -8
  102. package/dist/lib/types.js +3 -3
  103. package/dist/lib/utils/color.js +2 -2
  104. package/dist/lib/utils/constants.js +20 -4
  105. package/dist/lib/utils/index.js +10 -4
  106. package/dist/lib/utils/pixi-loader.js +41 -15
  107. package/dist/lib/utils/playground-utils.js +4 -4
  108. package/dist/lib/utils/replay-scripts.js +164 -115
  109. package/dist/types/component/config-selector/index.d.ts +2 -0
  110. package/dist/types/component/player/index.d.ts +0 -1
  111. package/dist/types/component/playground-result/index.d.ts +1 -0
  112. package/dist/types/component/prompt-input/index.d.ts +2 -1
  113. package/dist/types/component/screenshot-viewer/index.d.ts +15 -0
  114. package/dist/types/hooks/usePlaygroundExecution.d.ts +1 -1
  115. package/dist/types/hooks/usePlaygroundState.d.ts +3 -3
  116. package/dist/types/hooks/useTheme.d.ts +7 -0
  117. package/dist/types/index.d.ts +3 -3
  118. package/dist/types/store/store.d.ts +18 -1
  119. package/dist/types/types.d.ts +14 -4
  120. package/dist/types/utils/constants.d.ts +5 -1
  121. package/dist/types/utils/index.d.ts +1 -0
  122. package/dist/types/utils/replay-scripts.d.ts +1 -1
  123. package/package.json +12 -22
@@ -31,3 +31,11 @@
31
31
  width: 100%;
32
32
  }
33
33
 
34
+ [data-theme="dark"] .blackboard .footer, [data-theme="dark"] .blackboard .bottom-tip-item {
35
+ color: rgba(255, 255, 255, .45);
36
+ }
37
+
38
+ [data-theme="dark"] .blackboard-main-content canvas {
39
+ border-color: rgba(255, 255, 255, .12);
40
+ }
41
+
@@ -1,14 +1,37 @@
1
- 'use client';
1
+ "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import "pixi.js/unsafe-eval";
4
- import { Checkbox } from "antd";
5
4
  import { Application, Container, Graphics, Rectangle, Sprite, Text, Texture } from "pixi.js";
6
5
  import { useEffect, useMemo, useRef, useState } from "react";
7
6
  import { colorForName, highlightColorForType } from "../../utils/color.mjs";
8
7
  import "./index.css";
9
- import { treeToList } from "@midscene/shared/extractor";
10
- import { DropShadowFilter } from "pixi-filters";
11
- import { useBlackboardPreference } from "../../store/store.mjs";
8
+ import { DropShadowFilter, GlowFilter } from "pixi-filters";
9
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
10
+ try {
11
+ var info = gen[key](arg);
12
+ var value = info.value;
13
+ } catch (error) {
14
+ reject(error);
15
+ return;
16
+ }
17
+ if (info.done) resolve(value);
18
+ else Promise.resolve(value).then(_next, _throw);
19
+ }
20
+ function _async_to_generator(fn) {
21
+ return function() {
22
+ var self = this, args = arguments;
23
+ return new Promise(function(resolve, reject) {
24
+ var gen = fn.apply(self, args);
25
+ function _next(value) {
26
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
27
+ }
28
+ function _throw(err) {
29
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
30
+ }
31
+ _next(void 0);
32
+ });
33
+ };
34
+ }
12
35
  const itemFillAlpha = 0.4;
13
36
  const highlightAlpha = 0.4;
14
37
  const pointRadius = 10;
@@ -61,7 +84,7 @@ const rectMarkForItem = (rect, name, type)=>{
61
84
  };
62
85
  const Blackboard = (props)=>{
63
86
  const highlightElements = props.highlightElements || [];
64
- const highlightIds = highlightElements.map((e)=>e.id);
87
+ highlightElements.map((e)=>e.id);
65
88
  const highlightRect = props.highlightRect;
66
89
  const highlightPoints = props.highlightPoints;
67
90
  const context = props.uiContext;
@@ -75,31 +98,39 @@ const Blackboard = (props)=>{
75
98
  const elementMarkContainer = useMemo(()=>new Container(), []);
76
99
  const [hoverElement, setHoverElement] = useState(null);
77
100
  const pixiBgRef = useRef(void 0);
78
- const { backgroundVisible, setBackgroundVisible, elementsVisible, setElementsVisible } = useBlackboardPreference();
101
+ const animationFrameRef = useRef(null);
102
+ const highlightGraphicsRef = useRef([]);
103
+ const glowFiltersRef = useRef([]);
104
+ const backgroundVisible = true;
105
+ const elementsVisible = true;
79
106
  useEffect(()=>{
80
- Promise.resolve((async ()=>{
81
- if (!domRef.current || !screenWidth) return;
82
- await app.init({
83
- width: screenWidth,
84
- height: screenHeight,
85
- background: 0xffffff
86
- });
87
- const canvasEl = domRef.current;
88
- domRef.current.appendChild(app.canvas);
89
- const { clientWidth } = domRef.current.parentElement;
90
- const targetHeight = 0.6 * window.innerHeight;
91
- const viewportRatio = clientWidth / targetHeight;
92
- if (screenWidth / screenHeight <= viewportRatio) {
93
- const ratio = targetHeight / screenHeight;
94
- canvasEl.style.width = `${Math.floor(screenWidth * ratio)}px`;
95
- canvasEl.style.height = `${Math.floor(screenHeight * ratio)}px`;
96
- }
97
- app.stage.addChild(highlightContainer);
98
- app.stage.addChild(elementMarkContainer);
99
- setAppInitialed(true);
100
- })());
107
+ Promise.resolve((()=>_async_to_generator(function*() {
108
+ if (!domRef.current || !screenWidth) return;
109
+ yield app.init({
110
+ width: screenWidth,
111
+ height: screenHeight,
112
+ background: 0xffffff
113
+ });
114
+ const canvasEl = domRef.current;
115
+ domRef.current.appendChild(app.canvas);
116
+ const { clientWidth } = domRef.current.parentElement;
117
+ const targetHeight = 0.6 * window.innerHeight;
118
+ const viewportRatio = clientWidth / targetHeight;
119
+ if (screenWidth / screenHeight <= viewportRatio) {
120
+ const ratio = targetHeight / screenHeight;
121
+ canvasEl.style.width = `${Math.floor(screenWidth * ratio)}px`;
122
+ canvasEl.style.height = `${Math.floor(screenHeight * ratio)}px`;
123
+ }
124
+ app.stage.addChild(highlightContainer);
125
+ app.stage.addChild(elementMarkContainer);
126
+ setAppInitialed(true);
127
+ })())());
101
128
  return ()=>{
102
129
  console.log('will destroy');
130
+ if (null !== animationFrameRef.current) {
131
+ cancelAnimationFrame(animationFrameRef.current);
132
+ animationFrameRef.current = null;
133
+ }
103
134
  try {
104
135
  app.destroy(true, {
105
136
  children: true,
@@ -170,26 +201,54 @@ const Blackboard = (props)=>{
170
201
  elementMarkContainer.removeChildren();
171
202
  highlightContainer.eventMode = 'passive';
172
203
  elementMarkContainer.eventMode = 'passive';
204
+ highlightGraphicsRef.current = [];
205
+ glowFiltersRef.current = [];
173
206
  if (highlightRect) {
174
207
  const [graphics] = rectMarkForItem(highlightRect, 'Search Area', 'searchArea');
175
208
  highlightContainer.addChild(graphics);
176
209
  }
177
210
  if (highlightElements.length) highlightElements.forEach((element)=>{
178
211
  const { rect, content, id } = element;
179
- const [graphics] = rectMarkForItem(rect, content, 'highlight');
180
- highlightContainer.addChild(graphics);
212
+ const items = rectMarkForItem(rect, content, 'highlight');
213
+ const graphics = items[0];
214
+ const glowFilter = new GlowFilter({
215
+ distance: 30,
216
+ outerStrength: 3,
217
+ innerStrength: 0,
218
+ color: 0xfd5907,
219
+ quality: 0.5
220
+ });
221
+ const existingFilters = graphics.filters;
222
+ if (Array.isArray(existingFilters)) graphics.filters = [
223
+ ...existingFilters,
224
+ glowFilter
225
+ ];
226
+ else if (existingFilters) graphics.filters = [
227
+ existingFilters,
228
+ glowFilter
229
+ ];
230
+ else graphics.filters = [
231
+ glowFilter
232
+ ];
233
+ items.forEach((item)=>highlightContainer.addChild(item));
234
+ highlightGraphicsRef.current.push(graphics);
235
+ glowFiltersRef.current.push(glowFilter);
181
236
  });
182
237
  if (null == highlightPoints ? void 0 : highlightPoints.length) highlightPoints.forEach((point)=>{
183
238
  const graphics = pointMarkForItem(point, 'highlightPoint');
239
+ const glowFilter = new GlowFilter({
240
+ distance: 25,
241
+ outerStrength: 2.5,
242
+ innerStrength: 0,
243
+ color: 0xfd5907,
244
+ quality: 0.5
245
+ });
246
+ graphics.filters = [
247
+ glowFilter
248
+ ];
184
249
  highlightContainer.addChild(graphics);
185
- });
186
- const elements = treeToList(context.tree);
187
- elements.forEach((element)=>{
188
- const { rect, content, id } = element;
189
- const ifHighlight = highlightIds.includes(id) || (null == hoverElement ? void 0 : hoverElement.id) === id;
190
- if (ifHighlight) return;
191
- const [graphics] = rectMarkForItem(rect, content, 'element');
192
- elementMarkContainer.addChild(graphics);
250
+ highlightGraphicsRef.current.push(graphics);
251
+ glowFiltersRef.current.push(glowFilter);
193
252
  });
194
253
  elementMarkContainer.visible = elementsVisible;
195
254
  return {
@@ -199,19 +258,50 @@ const Blackboard = (props)=>{
199
258
  app,
200
259
  appInitialed,
201
260
  highlightElements,
202
- context.tree,
203
261
  hoverElement,
204
262
  highlightRect,
205
263
  highlightPoints
206
264
  ]);
207
- const onSetBackgroundVisible = (e)=>{
208
- setBackgroundVisible(e.target.checked);
209
- if (pixiBgRef.current) pixiBgRef.current.visible = e.target.checked;
210
- };
211
- const onSetElementsVisible = (e)=>{
212
- setElementsVisible(e.target.checked);
213
- elementMarkContainer.visible = e.target.checked;
214
- };
265
+ useEffect(()=>{
266
+ if (!appInitialed || 0 === highlightGraphicsRef.current.length) return void console.log('Animation skipped:', {
267
+ appInitialed,
268
+ graphicsCount: highlightGraphicsRef.current.length
269
+ });
270
+ console.log('Starting pulsing animation for', highlightGraphicsRef.current.length, 'graphics');
271
+ const graphicsToAnimate = highlightGraphicsRef.current;
272
+ const glowFilters = glowFiltersRef.current;
273
+ const pulseDuration = 1200;
274
+ const minAlpha = 0.4;
275
+ const maxAlpha = 1.0;
276
+ const minGlowStrength = 2.0;
277
+ const maxGlowStrength = 5.0;
278
+ const startTime = performance.now();
279
+ const animate = ()=>{
280
+ const elapsed = performance.now() - startTime;
281
+ const progress = elapsed % pulseDuration / pulseDuration;
282
+ const sineValue = Math.sin(progress * Math.PI * 2);
283
+ const normalizedSine = (sineValue + 1) / 2;
284
+ const alpha = minAlpha + normalizedSine * (maxAlpha - minAlpha);
285
+ const glowStrength = minGlowStrength + normalizedSine * (maxGlowStrength - minGlowStrength);
286
+ graphicsToAnimate.forEach((graphics, index)=>{
287
+ graphics.alpha = alpha;
288
+ if (glowFilters[index]) glowFilters[index].outerStrength = glowStrength;
289
+ });
290
+ animationFrameRef.current = requestAnimationFrame(animate);
291
+ };
292
+ animate();
293
+ return ()=>{
294
+ console.log('Stopping pulsing animation');
295
+ if (null !== animationFrameRef.current) {
296
+ cancelAnimationFrame(animationFrameRef.current);
297
+ animationFrameRef.current = null;
298
+ }
299
+ };
300
+ }, [
301
+ appInitialed,
302
+ highlightElements,
303
+ highlightPoints
304
+ ]);
215
305
  let bottomTipA = null;
216
306
  if (1 === highlightElementRects.length) bottomTipA = /*#__PURE__*/ jsx("div", {
217
307
  className: "bottom-tip",
@@ -243,27 +333,6 @@ const Blackboard = (props)=>{
243
333
  },
244
334
  ref: domRef
245
335
  }),
246
- /*#__PURE__*/ jsx("div", {
247
- className: "blackboard-filter",
248
- style: {
249
- display: props.hideController ? 'none' : 'block'
250
- },
251
- children: /*#__PURE__*/ jsxs("div", {
252
- className: "overlay-control",
253
- children: [
254
- /*#__PURE__*/ jsx(Checkbox, {
255
- checked: backgroundVisible,
256
- onChange: onSetBackgroundVisible,
257
- children: "Background"
258
- }),
259
- /*#__PURE__*/ jsx(Checkbox, {
260
- checked: elementsVisible,
261
- onChange: onSetElementsVisible,
262
- children: "Elements"
263
- })
264
- ]
265
- })
266
- }),
267
336
  /*#__PURE__*/ jsx("div", {
268
337
  className: "bottom-tip",
269
338
  style: {
@@ -2,9 +2,8 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Checkbox, Dropdown, Radio } from "antd";
3
3
  import setting from "../../icons/setting.mjs";
4
4
  import { useEnvConfig } from "../../store/store.mjs";
5
- import { deepThinkTip, domIncludedTip, screenshotIncludedTip, trackingTip } from "../../utils/constants.mjs";
6
- const ConfigSelector = (param)=>{
7
- let { showDeepThinkOption = false, enableTracking = false, showDataExtractionOptions = false, hideDomAndScreenshotOptions = false } = param;
5
+ import { alwaysRefreshScreenInfoTip, autoDismissKeyboardTip, deepThinkTip, domIncludedTip, imeStrategyTip, keyboardDismissStrategyTip, screenshotIncludedTip, trackingTip } from "../../utils/constants.mjs";
6
+ const ConfigSelector = ({ showDeepThinkOption = false, enableTracking = false, showDataExtractionOptions = false, hideDomAndScreenshotOptions = false, deviceType })=>{
8
7
  const forceSameTabNavigation = useEnvConfig((state)=>state.forceSameTabNavigation);
9
8
  const setForceSameTabNavigation = useEnvConfig((state)=>state.setForceSameTabNavigation);
10
9
  const deepThink = useEnvConfig((state)=>state.deepThink);
@@ -13,7 +12,16 @@ const ConfigSelector = (param)=>{
13
12
  const setScreenshotIncluded = useEnvConfig((state)=>state.setScreenshotIncluded);
14
13
  const domIncluded = useEnvConfig((state)=>state.domIncluded);
15
14
  const setDomIncluded = useEnvConfig((state)=>state.setDomIncluded);
16
- if (!enableTracking && !showDeepThinkOption && !showDataExtractionOptions) return null;
15
+ const imeStrategy = useEnvConfig((state)=>state.imeStrategy);
16
+ const setImeStrategy = useEnvConfig((state)=>state.setImeStrategy);
17
+ const autoDismissKeyboard = useEnvConfig((state)=>state.autoDismissKeyboard);
18
+ const setAutoDismissKeyboard = useEnvConfig((state)=>state.setAutoDismissKeyboard);
19
+ const keyboardDismissStrategy = useEnvConfig((state)=>state.keyboardDismissStrategy);
20
+ const setKeyboardDismissStrategy = useEnvConfig((state)=>state.setKeyboardDismissStrategy);
21
+ const alwaysRefreshScreenInfo = useEnvConfig((state)=>state.alwaysRefreshScreenInfo);
22
+ const setAlwaysRefreshScreenInfo = useEnvConfig((state)=>state.setAlwaysRefreshScreenInfo);
23
+ const hasDeviceOptions = 'android' === deviceType || 'ios' === deviceType;
24
+ if (!enableTracking && !showDeepThinkOption && !showDataExtractionOptions && !hasDeviceOptions) return null;
17
25
  const configItems = buildConfigItems();
18
26
  return /*#__PURE__*/ jsx("div", {
19
27
  className: "selector-trigger",
@@ -98,6 +106,96 @@ const ConfigSelector = (param)=>{
98
106
  key: 'dom-included-config'
99
107
  });
100
108
  }
109
+ if ('android' === deviceType) {
110
+ items.push({
111
+ label: /*#__PURE__*/ jsxs("div", {
112
+ style: {
113
+ padding: '4px 0'
114
+ },
115
+ children: [
116
+ /*#__PURE__*/ jsx("div", {
117
+ style: {
118
+ marginBottom: '4px',
119
+ fontSize: '14px'
120
+ },
121
+ children: imeStrategyTip
122
+ }),
123
+ /*#__PURE__*/ jsxs(Radio.Group, {
124
+ size: "small",
125
+ value: imeStrategy,
126
+ onChange: (e)=>setImeStrategy(e.target.value),
127
+ children: [
128
+ /*#__PURE__*/ jsx(Radio, {
129
+ value: "always-yadb",
130
+ children: "Always YADB"
131
+ }),
132
+ /*#__PURE__*/ jsx(Radio, {
133
+ value: "yadb-for-non-ascii",
134
+ children: "YADB for non-ASCII"
135
+ })
136
+ ]
137
+ })
138
+ ]
139
+ }),
140
+ key: 'ime-strategy-config'
141
+ });
142
+ items.push({
143
+ label: /*#__PURE__*/ jsx(Checkbox, {
144
+ onChange: (e)=>setAutoDismissKeyboard(e.target.checked),
145
+ checked: autoDismissKeyboard,
146
+ children: autoDismissKeyboardTip
147
+ }),
148
+ key: 'auto-dismiss-keyboard-config'
149
+ });
150
+ items.push({
151
+ label: /*#__PURE__*/ jsxs("div", {
152
+ style: {
153
+ padding: '4px 0'
154
+ },
155
+ children: [
156
+ /*#__PURE__*/ jsx("div", {
157
+ style: {
158
+ marginBottom: '4px',
159
+ fontSize: '14px'
160
+ },
161
+ children: keyboardDismissStrategyTip
162
+ }),
163
+ /*#__PURE__*/ jsxs(Radio.Group, {
164
+ size: "small",
165
+ value: keyboardDismissStrategy,
166
+ onChange: (e)=>setKeyboardDismissStrategy(e.target.value),
167
+ children: [
168
+ /*#__PURE__*/ jsx(Radio, {
169
+ value: "esc-first",
170
+ children: "ESC first"
171
+ }),
172
+ /*#__PURE__*/ jsx(Radio, {
173
+ value: "back-first",
174
+ children: "Back first"
175
+ })
176
+ ]
177
+ })
178
+ ]
179
+ }),
180
+ key: 'keyboard-dismiss-strategy-config'
181
+ });
182
+ items.push({
183
+ label: /*#__PURE__*/ jsx(Checkbox, {
184
+ onChange: (e)=>setAlwaysRefreshScreenInfo(e.target.checked),
185
+ checked: alwaysRefreshScreenInfo,
186
+ children: alwaysRefreshScreenInfoTip
187
+ }),
188
+ key: 'always-refresh-screen-info-config'
189
+ });
190
+ }
191
+ if ('ios' === deviceType) items.push({
192
+ label: /*#__PURE__*/ jsx(Checkbox, {
193
+ onChange: (e)=>setAutoDismissKeyboard(e.target.checked),
194
+ checked: autoDismissKeyboard,
195
+ children: autoDismissKeyboardTip
196
+ }),
197
+ key: 'auto-dismiss-keyboard-config'
198
+ });
101
199
  return items;
102
200
  }
103
201
  };
@@ -3,8 +3,7 @@ import { Button } from "antd";
3
3
  import blackboard from "../blackboard/index.mjs";
4
4
  import { iconForStatus } from "../misc/index.mjs";
5
5
  import playground_demo_ui_context from "../playground/playground-demo-ui-context.json";
6
- const ContextPreview = (param)=>{
7
- let { uiContextPreview, setUiContextPreview, showContextPreview } = param;
6
+ const ContextPreview = ({ uiContextPreview, setUiContextPreview, showContextPreview })=>{
8
7
  if (!showContextPreview) return null;
9
8
  return /*#__PURE__*/ jsxs("div", {
10
9
  className: "form-part context-panel",
@@ -3,8 +3,7 @@ import { SettingOutlined } from "@ant-design/icons";
3
3
  import { Input, Modal, Tooltip } from "antd";
4
4
  import { useEffect, useRef, useState } from "react";
5
5
  import { useEnvConfig } from "../../store/store.mjs";
6
- function EnvConfig(param) {
7
- let { showTooltipWhenEmpty = true, showModelName = true, tooltipPlacement = 'bottom', mode = 'icon' } = param;
6
+ function EnvConfig({ showTooltipWhenEmpty = true, showModelName = true, tooltipPlacement = 'bottom', mode = 'icon' }) {
8
7
  const { config, configString, loadConfig, syncFromStorage } = useEnvConfig();
9
8
  const [isModalOpen, setIsModalOpen] = useState(false);
10
9
  const [tempConfigString, setTempConfigString] = useState(configString);
@@ -20,3 +20,11 @@
20
20
  font-size: 14px;
21
21
  }
22
22
 
23
+ [data-theme="dark"] .env-config-reminder {
24
+ background: rgba(82, 38, 7, .3);
25
+ }
26
+
27
+ [data-theme="dark"] .env-config-reminder .reminder-text {
28
+ color: #f8fafd;
29
+ }
30
+
@@ -3,8 +3,7 @@ import { ExclamationCircleFilled } from "@ant-design/icons";
3
3
  import { useEnvConfig } from "../../store/store.mjs";
4
4
  import { EnvConfig } from "../env-config/index.mjs";
5
5
  import "./index.css";
6
- const EnvConfigReminder = (param)=>{
7
- let { className = '' } = param;
6
+ const EnvConfigReminder = ({ className = '' })=>{
8
7
  const { config } = useEnvConfig();
9
8
  const configAlreadySet = Object.keys(config || {}).length >= 1;
10
9
  if (configAlreadySet) return null;
@@ -2,8 +2,7 @@ import { jsx } from "react/jsx-runtime";
2
2
  import { Form, Input, InputNumber, Select } from "antd";
3
3
  const { TextArea } = Input;
4
4
  const renderLabel = (label, isOptional)=>`${label}${isOptional ? ' (Optional)' : ''}`;
5
- const TextField = (param)=>{
6
- let { name, label, isRequired, marginBottom, placeholder: customPlaceholder } = param;
5
+ const TextField = ({ name, label, isRequired, marginBottom, placeholder: customPlaceholder })=>{
7
6
  const placeholder = customPlaceholder || `Enter ${name}`;
8
7
  return /*#__PURE__*/ jsx(Form.Item, {
9
8
  name: [
@@ -26,8 +25,7 @@ const TextField = (param)=>{
26
25
  })
27
26
  }, name);
28
27
  };
29
- const LocateField = (param)=>{
30
- let { name, label, isRequired, marginBottom, placeholder: customPlaceholder } = param;
28
+ const LocateField = ({ name, label, isRequired, marginBottom, placeholder: customPlaceholder })=>{
31
29
  const placeholder = customPlaceholder || `Describe the ${name}, use natural language`;
32
30
  return /*#__PURE__*/ jsx(Form.Item, {
33
31
  name: [
@@ -51,8 +49,7 @@ const LocateField = (param)=>{
51
49
  })
52
50
  }, name);
53
51
  };
54
- const EnumField = (param)=>{
55
- let { name, label, fieldSchema, isRequired, marginBottom, placeholder: customPlaceholder } = param;
52
+ const EnumField = ({ name, label, fieldSchema, isRequired, marginBottom, placeholder: customPlaceholder })=>{
56
53
  var _fieldSchema__def;
57
54
  const enumValues = (null == (_fieldSchema__def = fieldSchema._def) ? void 0 : _fieldSchema__def.values) || [];
58
55
  const selectOptions = enumValues.map((value)=>({
@@ -81,8 +78,7 @@ const EnumField = (param)=>{
81
78
  })
82
79
  }, name);
83
80
  };
84
- const NumberField = (param)=>{
85
- let { name, label, isRequired, marginBottom, placeholder: customPlaceholder } = param;
81
+ const NumberField = ({ name, label, isRequired, marginBottom, placeholder: customPlaceholder })=>{
86
82
  const defaultPlaceholder = 'distance' === name ? 500 : 0;
87
83
  const placeholderValue = customPlaceholder ? Number(customPlaceholder) || defaultPlaceholder : defaultPlaceholder;
88
84
  const min = 0;
@@ -126,8 +122,7 @@ const NumberField = (param)=>{
126
122
  })
127
123
  }, name);
128
124
  };
129
- const BooleanField = (param)=>{
130
- let { name, label, isRequired, marginBottom, placeholder: customPlaceholder } = param;
125
+ const BooleanField = ({ name, label, isRequired, marginBottom, placeholder: customPlaceholder })=>{
131
126
  const selectOptions = [
132
127
  {
133
128
  value: true,
@@ -77,7 +77,12 @@
77
77
  border: none;
78
78
  }
79
79
 
80
- .history-modal-container .history-search-section .search-input-wrapper .search-input:hover, .history-modal-container .history-search-section .search-input-wrapper .search-input:focus-within {
80
+ .history-modal-container .history-search-section .search-input-wrapper .search-input:hover {
81
+ background: #fff;
82
+ border-color: #d9d9d9;
83
+ }
84
+
85
+ .history-modal-container .history-search-section .search-input-wrapper .search-input:focus-within {
81
86
  background: #fff;
82
87
  border-color: #d9d9d9;
83
88
  }
@@ -133,3 +138,35 @@
133
138
  padding: 40px 20px;
134
139
  }
135
140
 
141
+ [data-theme="dark"] .history-selector .history-timestamp, [data-theme="dark"] .history-selector .history-path {
142
+ color: rgba(255, 255, 255, .45);
143
+ }
144
+
145
+ [data-theme="dark"] .history-selector .history-description {
146
+ color: #f8fafd;
147
+ }
148
+
149
+ [data-theme="dark"] .history-selector .history-no-items {
150
+ color: rgba(255, 255, 255, .45);
151
+ }
152
+
153
+ [data-theme="dark"] .history-selector .history-item:hover {
154
+ background: rgba(255, 255, 255, .08);
155
+ }
156
+
157
+ [data-theme="dark"] .history-selector .history-item .history-clear-icon {
158
+ border-color: rgba(255, 255, 255, .12);
159
+ }
160
+
161
+ [data-theme="dark"] .history-selector .history-item .history-clear-icon:hover {
162
+ border-color: #40a9ff;
163
+ }
164
+
165
+ [data-theme="dark"] .history-selector .history-load-more {
166
+ color: #1890ff;
167
+ }
168
+
169
+ [data-theme="dark"] .history-selector .history-load-more:hover {
170
+ color: #40a9ff;
171
+ }
172
+
@@ -7,8 +7,7 @@ import magnifying_glass from "../../icons/magnifying-glass.mjs";
7
7
  import { useHistoryStore } from "../../store/history.mjs";
8
8
  import "./index.css";
9
9
  const { Text } = Typography;
10
- const HistorySelector = (param)=>{
11
- let { onSelect, history, currentType } = param;
10
+ const HistorySelector = ({ onSelect, history, currentType })=>{
12
11
  const [isModalOpen, setIsModalOpen] = useState(false);
13
12
  const [searchText, setSearchText] = useState('');
14
13
  const clearHistory = useHistoryStore((state)=>state.clearHistory);
@@ -1,9 +1,13 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
+ import { useTheme } from "../../hooks/useTheme.mjs";
2
3
  import "./index.css";
3
4
  const LogoUrl = 'https://lf3-static.bytednsdoc.com/obj/eden-cn/vhaeh7vhabf/Midscene.png';
4
- const Logo = (param)=>{
5
- let { hideLogo = false } = param;
5
+ const LogoUrlLight = 'https://lf3-static.bytednsdoc.com/obj/eden-cn/nupipfups/Midscene/midscene_with_text_light.png';
6
+ const LogoUrlDark = 'https://lf3-static.bytednsdoc.com/obj/eden-cn/nupipfups/Midscene/midscene_with_text_dark.png';
7
+ const Logo = ({ hideLogo = false })=>{
8
+ const { isDarkMode } = useTheme();
6
9
  if (hideLogo) return null;
10
+ const logoSrc = isDarkMode ? LogoUrlDark : LogoUrlLight;
7
11
  return /*#__PURE__*/ jsx("div", {
8
12
  className: "logo",
9
13
  children: /*#__PURE__*/ jsx("a", {
@@ -12,7 +16,7 @@ const Logo = (param)=>{
12
16
  rel: "noreferrer",
13
17
  children: /*#__PURE__*/ jsx("img", {
14
18
  alt: "Midscene_logo",
15
- src: "https://lf3-static.bytednsdoc.com/obj/eden-cn/vhaeh7vhabf/Midscene.png"
19
+ src: logoSrc
16
20
  })
17
21
  })
18
22
  });
@@ -70,9 +70,7 @@ const errorMessageServerNotReady = /*#__PURE__*/ jsxs("span", {
70
70
  })
71
71
  ]
72
72
  });
73
- const serverLaunchTip = function() {
74
- let notReadyMessage = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : errorMessageServerNotReady;
75
- return /*#__PURE__*/ jsx("div", {
73
+ const serverLaunchTip = (notReadyMessage = errorMessageServerNotReady)=>/*#__PURE__*/ jsx("div", {
76
74
  className: "server-tip",
77
75
  children: /*#__PURE__*/ jsx(Alert, {
78
76
  message: "Playground Server Not Ready",
@@ -80,7 +78,6 @@ const serverLaunchTip = function() {
80
78
  type: "warning"
81
79
  })
82
80
  });
83
- };
84
81
  const emptyResultTip = /*#__PURE__*/ jsx("div", {
85
82
  className: "result-empty-tip",
86
83
  style: {
@@ -3,8 +3,7 @@ import { GithubOutlined, QuestionCircleOutlined } from "@ant-design/icons";
3
3
  import { Typography } from "antd";
4
4
  import { EnvConfig } from "../env-config/index.mjs";
5
5
  import "./style.css";
6
- function NavActions(param) {
7
- let { showEnvConfig = true, showTooltipWhenEmpty = false, showModelName = false, githubUrl = 'https://github.com/web-infra-dev/midscene', helpUrl = 'https://midscenejs.com/quick-experience.html', className = '' } = param;
6
+ function NavActions({ showEnvConfig = true, showTooltipWhenEmpty = false, showModelName = false, githubUrl = 'https://github.com/web-infra-dev/midscene', helpUrl = 'https://midscenejs.com/quick-experience.html', className = '' }) {
8
7
  return /*#__PURE__*/ jsxs("div", {
9
8
  className: `nav-actions ${className}`,
10
9
  children: [
@@ -26,7 +26,7 @@
26
26
  }
27
27
 
28
28
  [data-theme="dark"] .nav-actions .nav-icon {
29
- color: rgba(255, 255, 255, .65);
29
+ color: #f8fafd;
30
30
  }
31
31
 
32
32
  [data-theme="dark"] .nav-actions .nav-icon:hover {
@@ -183,3 +183,29 @@
183
183
  display: flex;
184
184
  }
185
185
 
186
+ [data-theme="dark"] .player-container {
187
+ background: #141414;
188
+ border-color: #292929;
189
+ }
190
+
191
+ [data-theme="dark"] .player-container[data-fit-mode="height"] {
192
+ background: #292929;
193
+ border-color: #292929;
194
+ }
195
+
196
+ [data-theme="dark"] .player-container[data-fit-mode="height"] .canvas-container {
197
+ background-color: #141414;
198
+ }
199
+
200
+ [data-theme="dark"] .player-container .canvas-container {
201
+ background-color: #1f1f1f;
202
+ }
203
+
204
+ [data-theme="dark"] .player-container .player-tools, [data-theme="dark"] .player-container .player-tools .ant-spin, [data-theme="dark"] .player-container .player-tools .status-icon svg {
205
+ color: #f8fafd;
206
+ }
207
+
208
+ [data-theme="dark"] .player-container .player-tools .status-icon:hover {
209
+ background: rgba(255, 255, 255, .08);
210
+ }
211
+