@arcblock/terminal 3.1.20 → 3.1.22

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/Player.js CHANGED
@@ -1,114 +1,132 @@
1
- import { jsxs as F, jsx as a } from "react/jsx-runtime";
2
- import { useRef as k, useReducer as I, useCallback as f, useEffect as A } from "react";
3
- import o from "prop-types";
4
- import P from "lodash/isUndefined";
5
- import S from "lodash/noop";
6
- import H from "./Terminal.js";
7
- import { PlayerRoot as Y } from "./styles.js";
8
- import { defaultOptions as _, formatFrames as U, defaultState as X, findFrameAt as j, getPlayerClass as $, getFrameClass as G, formatTime as K } from "./util.js";
9
- const ie = 8;
10
- function Q({ ...E }) {
11
- const s = Object.assign({}, E);
12
- P(s.onComplete) && (s.onComplete = S), P(s.onStart) && (s.onStart = S), P(s.onStop) && (s.onStop = S), P(s.onPause) && (s.onPause = S), P(s.onTick) && (s.onTick = S), P(s.onJump) && (s.onJump = S);
13
- const e = Object.assign({}, _, s.options), { frames: c, totalDuration: g } = U(s.frames, e), D = {
14
- cols: e.cols,
15
- rows: e.rows,
16
- cursorStyle: e.cursorStyle,
17
- cursorBlink: e.cursorBlink ?? !0,
18
- fontFamily: e.fontFamily,
19
- fontSize: e.fontSize,
20
- lineHeight: e.lineHeight,
21
- letterSpacing: e.letterSpacing,
1
+ import { jsxs as S, jsx as a } from "react/jsx-runtime";
2
+ import { useRef as g, useReducer as H, useCallback as f, useEffect as q } from "react";
3
+ import l from "prop-types";
4
+ import F from "lodash/isUndefined";
5
+ import P from "lodash/noop";
6
+ import Y from "./Terminal.js";
7
+ import { PlayerRoot as _ } from "./styles.js";
8
+ import { defaultOptions as U, formatFrames as X, defaultState as $, findFrameAt as D, getPlayerClass as G, getFrameClass as K, formatTime as Q } from "./util.js";
9
+ const se = 8;
10
+ function V({ ...z }) {
11
+ const s = Object.assign({}, z);
12
+ F(s.onComplete) && (s.onComplete = P), F(s.onStart) && (s.onStart = P), F(s.onStop) && (s.onStop = P), F(s.onPause) && (s.onPause = P), F(s.onTick) && (s.onTick = P), F(s.onJump) && (s.onJump = P);
13
+ const r = Object.assign({}, U, s.options), { frames: c, totalDuration: h } = X(s.frames, r), J = {
14
+ cols: r.cols,
15
+ rows: r.rows,
16
+ cursorStyle: r.cursorStyle,
17
+ cursorBlink: r.cursorBlink ?? !0,
18
+ fontFamily: r.fontFamily,
19
+ fontSize: r.fontSize,
20
+ lineHeight: r.lineHeight,
21
+ letterSpacing: r.letterSpacing,
22
22
  allowTransparency: !0,
23
23
  scrollback: 0,
24
- theme: e.enableTheme ? e.theme : {}
25
- }, z = (r, n) => {
24
+ theme: r.enableTheme ? r.theme : {}
25
+ }, I = (e, n) => {
26
26
  switch (n.type) {
27
27
  case "jump":
28
- return { ...r, ...n.payload };
28
+ return { ...e, ...n.payload };
29
29
  case "start":
30
- return { ...r, isStarted: !0, lastTickTime: Date.now() };
30
+ return { ...e, isStarted: !0, lastTickTime: Date.now() };
31
31
  case "play":
32
- return { ...r, isPlaying: !0, lastTickTime: Date.now(), ...n.payload };
32
+ return { ...e, isPlaying: !0, lastTickTime: Date.now(), ...n.payload };
33
33
  case "pause":
34
- return { ...r, isPlaying: !1, ...n.payload };
34
+ return { ...e, isPlaying: !1, ...n.payload };
35
35
  case "tickStart":
36
- return { ...r, isRendering: !0, lastTickTime: Date.now(), ...n.payload };
36
+ return { ...e, isRendering: !0, lastTickTime: Date.now(), ...n.payload };
37
37
  case "tickEnd":
38
- return { ...r, isRendering: !1, lastTickTime: Date.now(), ...n.payload };
38
+ return { ...e, isRendering: !1, lastTickTime: Date.now(), ...n.payload };
39
39
  case "reset":
40
- return { ...r, currentFrame: -1, currentTime: 0, ...n.payload };
40
+ return { ...e, currentFrame: -1, currentTime: 0, ...n.payload };
41
41
  default:
42
- return { ...r, lastTickTime: Date.now(), ...n.payload };
42
+ return { ...e, lastTickTime: Date.now(), ...n.payload };
43
43
  }
44
- }, i = k(null), x = k(null), J = k(null), d = k(null), p = k(null), [t, u] = I(z, X), C = f(
45
- (r) => new Promise((n) => {
46
- const l = c[r];
47
- l && l.content && i.current ? (t.requireReset && i.current.reset(), i.current.write(l.content, () => {
44
+ }, i = g(null), N = g(null), v = g(null), d = g(null), p = g(null), A = g(!1), [t, u] = H(I, $), j = f(
45
+ (e) => new Promise((n) => {
46
+ const o = c[e];
47
+ o && o.content && i.current ? (t.requireReset && i.current.reset(), i.current.write(o.content, () => {
48
48
  n();
49
49
  })) : n();
50
50
  }),
51
51
  [c, t.requireReset]
52
- ), q = f(
53
- (r) => {
54
- const n = c[r];
52
+ ), E = f(
53
+ (e) => {
54
+ const n = c[e];
55
55
  n && n.content && i.current && (t.requireReset && i.current.reset(), i.current.write(n.content));
56
56
  },
57
57
  [c, t.requireReset]
58
58
  ), m = f(
59
- (r) => {
60
- typeof s[r] == "function" && s[r]({ state: t, frames: c, options: e });
59
+ (e) => {
60
+ typeof s[e] == "function" && s[e]({ state: t, frames: c, options: r });
61
61
  },
62
- [s, t, c, e]
63
- ), N = f(
64
- (r) => {
62
+ [s, t, c, r]
63
+ ), R = f(
64
+ (e) => {
65
65
  if (!i.current) return;
66
66
  i.current.reset();
67
- const n = j(c, r);
67
+ const n = D(c, e);
68
68
  if (n >= 0)
69
- for (let l = 0; l <= n; l++)
70
- q(l);
69
+ for (let o = 0; o <= n; o++)
70
+ E(o);
71
71
  },
72
- [c, q]
73
- ), L = f(
74
- (r) => {
75
- if (!x.current || !i.current || !t.isStarted)
72
+ [c, E]
73
+ ), M = f(
74
+ (e) => {
75
+ if (!N.current || !i.current || !t.isStarted)
76
76
  return !1;
77
- const n = x.current.getBoundingClientRect().width, l = r.nativeEvent.offsetX, h = Math.floor(g * l / n), T = j(c, h), w = t.isPlaying;
77
+ const n = N.current.getBoundingClientRect().width, o = e.nativeEvent.offsetX, T = Math.floor(h * o / n), b = D(c, T), w = t.isPlaying;
78
78
  return u({
79
79
  type: "jump",
80
80
  payload: {
81
- currentTime: h,
82
- currentFrame: T,
81
+ currentTime: T,
82
+ currentFrame: b,
83
83
  isPlaying: w
84
84
  // Keep the same playing state
85
85
  }
86
- }), p.current = null, N(h), m("onJump"), !1;
86
+ }), p.current = null, R(T), m("onJump"), !1;
87
87
  },
88
- [t.isStarted, t.isPlaying, g, c, N, m]
89
- ), M = f(() => (t.currentFrame >= c.length - 1 ? (i.current.resize(), u({ type: "reset", payload: { currentFrame: -1, currentTime: 0 } }), i.current && i.current.reset(), p.current = null, u({ type: "play", payload: { currentFrame: -1, currentTime: 0 } })) : (p.current = null, u({ type: "play" })), m("onPlay"), !1), [t.currentFrame, c.length, m]), b = f(() => (t.isStarted === !1 && (i.current.resize(), u({ type: "start" }), i.current && i.current.reset()), p.current = null, u({ type: "play", payload: { currentFrame: -1, currentTime: 0 } }), m("onStart"), !1), [t.isStarted, m]), O = f(() => (u({ type: "pause" }), m("onPause"), !1), [m]);
90
- A(() => {
91
- i.current && (i.current.focus(), e.autoplay ? b() : N(Math.min(Math.abs(e.thumbnailTime), g)));
88
+ [t.isStarted, t.isPlaying, h, c, R, m]
89
+ ), O = f(() => (t.currentFrame >= c.length - 1 ? (i.current.resize(), u({ type: "reset", payload: { currentFrame: -1, currentTime: 0 } }), i.current && i.current.reset(), p.current = null, u({ type: "play", payload: { currentFrame: -1, currentTime: 0 } })) : (p.current = null, u({ type: "play" })), m("onPlay"), !1), [t.currentFrame, c.length, m]), k = f(() => (t.isStarted === !1 && (i.current.resize(), u({ type: "start" }), i.current && i.current.reset()), p.current = null, u({ type: "play", payload: { currentFrame: -1, currentTime: 0 } }), m("onStart"), !1), [t.isStarted, m]), L = f(() => (u({ type: "pause" }), m("onPause"), !1), [m]);
90
+ q(() => {
91
+ if (!v.current || !r.autoplay || A.current)
92
+ return;
93
+ const e = new IntersectionObserver(
94
+ (n) => {
95
+ const [o] = n;
96
+ o.isIntersecting && !t.isStarted && (k(), A.current = !0, e.unobserve(v.current), e.disconnect());
97
+ },
98
+ {
99
+ threshold: 0.1,
100
+ // Trigger when 10% of the element is visible
101
+ rootMargin: "0px 0px 0px 0px"
102
+ // Add some margin to avoid triggering too early
103
+ }
104
+ );
105
+ return e.observe(v.current), () => {
106
+ e.disconnect();
107
+ };
108
+ }, [r.autoplay, t.isStarted, k]), q(() => {
109
+ i.current && (i.current.focus(), r.autoplay || R(Math.min(Math.abs(r.thumbnailTime), h)));
92
110
  }, []);
93
- const v = k(t);
94
- v.current = t;
95
- const R = f(async () => {
96
- const r = v.current;
97
- if (!r.isPlaying || r.isRendering)
111
+ const x = g(t);
112
+ x.current = t;
113
+ const B = f(async () => {
114
+ const e = x.current;
115
+ if (!e.isPlaying || e.isRendering)
98
116
  return;
99
117
  const n = performance.now();
100
118
  if (!p.current) {
101
- const y = r.currentFrame >= 0 && c[r.currentFrame]?.startTime || 0;
119
+ const y = e.currentFrame >= 0 && c[e.currentFrame]?.startTime || 0;
102
120
  p.current = n - y;
103
121
  }
104
- const l = n - p.current, { currentFrame: h } = r, T = h + 1;
105
- if (h >= c.length - 1) {
106
- if (m("onComplete"), e.repeat) {
122
+ const o = n - p.current, { currentFrame: T } = e, b = T + 1;
123
+ if (T >= c.length - 1) {
124
+ if (m("onComplete"), r.repeat) {
107
125
  p.current = n, u({ type: "reset", payload: { currentTime: 0, currentFrame: -1 } });
108
126
  return;
109
127
  }
110
128
  const y = {
111
- currentTime: g,
129
+ currentTime: h,
112
130
  currentFrame: c.length - 1,
113
131
  requireReset: !0,
114
132
  isStarted: !1
@@ -116,92 +134,92 @@ function Q({ ...E }) {
116
134
  u({ type: "pause", payload: y }), p.current = null;
117
135
  return;
118
136
  }
119
- const w = c[T];
137
+ const w = c[b];
120
138
  if (!w) {
121
- t.isPlaying && (d.current = requestAnimationFrame(R));
139
+ t.isPlaying && (d.current = requestAnimationFrame(B));
122
140
  return;
123
141
  }
124
- const B = w.startTime || 0;
125
- if (l >= B) {
142
+ const C = w.startTime || 0;
143
+ if (o >= C) {
126
144
  u({
127
145
  type: "tickStart",
128
146
  payload: {
129
- currentTime: B,
130
- currentFrame: T
147
+ currentTime: C,
148
+ currentFrame: b
131
149
  }
132
150
  });
133
151
  try {
134
- await C(T);
152
+ await j(b);
135
153
  const y = {
136
- currentTime: B,
137
- currentFrame: T
154
+ currentTime: C,
155
+ currentFrame: b
138
156
  };
139
- r.requireReset && (y.requireReset = !1), u({ type: "tickEnd", payload: y }), m("onTick");
157
+ e.requireReset && (y.requireReset = !1), u({ type: "tickEnd", payload: y }), m("onTick");
140
158
  } catch (y) {
141
159
  console.error("Frame rendering error:", y);
142
160
  }
143
161
  } else
144
- u({ type: "tick", payload: { currentTime: l } });
145
- }, [c, C, m, e.repeat, g]);
146
- return A(() => {
147
- let r = !0;
162
+ u({ type: "tick", payload: { currentTime: o } });
163
+ }, [c, j, m, r.repeat, h]);
164
+ return q(() => {
165
+ let e = !0;
148
166
  const n = async () => {
149
- for (; r && v.current.isPlaying; )
150
- await new Promise((l) => {
151
- d.current = requestAnimationFrame(l);
152
- }), r && v.current.isPlaying && await R();
167
+ for (; e && x.current.isPlaying; )
168
+ await new Promise((o) => {
169
+ d.current = requestAnimationFrame(o);
170
+ }), e && x.current.isPlaying && await B();
153
171
  };
154
172
  return t.isPlaying ? n() : (d.current && (cancelAnimationFrame(d.current), d.current = null), p.current = null), () => {
155
- r = !1, d.current && (cancelAnimationFrame(d.current), d.current = null);
173
+ e = !1, d.current && (cancelAnimationFrame(d.current), d.current = null);
156
174
  };
157
- }, [t.isPlaying, R]), e.controls && (e.frameBox.title = null, e.frameBox.type = null, e.frameBox.style = {}, e.theme?.background === "transparent" ? e.frameBox.style.background = "black" : e.theme?.background && (e.frameBox.style.background = e.theme.background), e.frameBox.style.padding = "10px", e.frameBox.style.paddingBottom = "40px"), /* @__PURE__ */ F(Y, { className: $(e, t), ref: J, children: [
158
- /* @__PURE__ */ a("div", { className: "cover", onClick: b }),
159
- /* @__PURE__ */ a("div", { className: "start", onClick: b, children: /* @__PURE__ */ F("svg", { style: { enableBackground: "new 0 0 30 30" }, viewBox: "0 0 30 30", children: [
175
+ }, [t.isPlaying, B]), r.controls && (r.frameBox.title = null, r.frameBox.type = null, r.frameBox.style = {}, r.theme?.background === "transparent" ? r.frameBox.style.background = "black" : r.theme?.background && (r.frameBox.style.background = r.theme.background), r.frameBox.style.padding = "10px", r.frameBox.style.paddingBottom = "40px"), /* @__PURE__ */ S(_, { className: G(r, t), ref: v, children: [
176
+ /* @__PURE__ */ a("div", { className: "cover", onClick: k }),
177
+ /* @__PURE__ */ a("div", { className: "start", onClick: k, children: /* @__PURE__ */ S("svg", { style: { enableBackground: "new 0 0 30 30" }, viewBox: "0 0 30 30", children: [
160
178
  /* @__PURE__ */ a("polygon", { points: "6.583,3.186 5,4.004 5,15 26,15 26.483,14.128 " }),
161
179
  /* @__PURE__ */ a("polygon", { points: "6.583,26.814 5,25.996 5,15 26,15 26.483,15.872 " }),
162
180
  /* @__PURE__ */ a("circle", { cx: "26", cy: "15", r: "1" }),
163
181
  /* @__PURE__ */ a("circle", { cx: "6", cy: "4", r: "1" }),
164
182
  /* @__PURE__ */ a("circle", { cx: "6", cy: "26", r: "1" })
165
183
  ] }) }),
166
- /* @__PURE__ */ a("div", { className: "terminal", children: /* @__PURE__ */ F("div", { className: G(e), style: e.frameBox.style || {}, children: [
167
- /* @__PURE__ */ F("div", { className: "terminal-titlebar", children: [
168
- /* @__PURE__ */ F("div", { className: "buttons", children: [
184
+ /* @__PURE__ */ a("div", { className: "terminal", children: /* @__PURE__ */ S("div", { className: K(r), style: r.frameBox.style || {}, children: [
185
+ /* @__PURE__ */ S("div", { className: "terminal-titlebar", children: [
186
+ /* @__PURE__ */ S("div", { className: "buttons", children: [
169
187
  /* @__PURE__ */ a("div", { className: "close-button" }),
170
188
  /* @__PURE__ */ a("div", { className: "minimize-button" }),
171
189
  /* @__PURE__ */ a("div", { className: "maximize-button" })
172
190
  ] }),
173
- /* @__PURE__ */ a("div", { className: "title", children: e.frameBox.title || "" })
191
+ /* @__PURE__ */ a("div", { className: "title", children: r.frameBox.title || "" })
174
192
  ] }),
175
- /* @__PURE__ */ a("div", { className: "terminal-body", children: /* @__PURE__ */ a(H, { ref: i, options: D }) })
193
+ /* @__PURE__ */ a("div", { className: "terminal-body", children: /* @__PURE__ */ a(Y, { ref: i, options: J }) })
176
194
  ] }) }),
177
- /* @__PURE__ */ F("div", { className: "controller", children: [
178
- !t.isPlaying && t.isStarted && /* @__PURE__ */ a("div", { className: "play", onClick: M, title: "Play", children: /* @__PURE__ */ a("span", { className: "icon" }) }),
179
- t.isPlaying && /* @__PURE__ */ a("div", { className: "pause", onClick: O, title: "Pause", children: /* @__PURE__ */ a("span", { className: "icon" }) }),
180
- !t.isPlaying && !t.isStarted && /* @__PURE__ */ a("div", { className: "play", onClick: b, title: "Start", children: /* @__PURE__ */ a("span", { className: "icon" }) }),
181
- /* @__PURE__ */ a("div", { className: "timer", children: K(t.currentTime) }),
182
- /* @__PURE__ */ a("div", { className: "progressbar-wrapper", children: /* @__PURE__ */ a("div", { className: "progressbar", ref: x, onClick: L, children: /* @__PURE__ */ a("div", { className: "progress", style: { width: `${t.currentTime / g * 100}%` } }) }) })
195
+ /* @__PURE__ */ S("div", { className: "controller", children: [
196
+ !t.isPlaying && t.isStarted && /* @__PURE__ */ a("div", { className: "play", onClick: O, title: "Play", children: /* @__PURE__ */ a("span", { className: "icon" }) }),
197
+ t.isPlaying && /* @__PURE__ */ a("div", { className: "pause", onClick: L, title: "Pause", children: /* @__PURE__ */ a("span", { className: "icon" }) }),
198
+ !t.isPlaying && !t.isStarted && /* @__PURE__ */ a("div", { className: "play", onClick: k, title: "Start", children: /* @__PURE__ */ a("span", { className: "icon" }) }),
199
+ /* @__PURE__ */ a("div", { className: "timer", children: Q(t.currentTime) }),
200
+ /* @__PURE__ */ a("div", { className: "progressbar-wrapper", children: /* @__PURE__ */ a("div", { className: "progressbar", ref: N, onClick: M, children: /* @__PURE__ */ a("div", { className: "progress", style: { width: `${t.currentTime / h * 100}%` } }) }) })
183
201
  ] })
184
202
  ] });
185
203
  }
186
- Q.propTypes = {
187
- frames: o.array.isRequired,
188
- options: o.shape({
189
- autoplay: o.bool,
190
- repeat: o.bool,
191
- controls: o.bool,
192
- frameBox: o.object,
193
- theme: o.object,
194
- cols: o.number,
195
- rows: o.number
204
+ V.propTypes = {
205
+ frames: l.array.isRequired,
206
+ options: l.shape({
207
+ autoplay: l.bool,
208
+ repeat: l.bool,
209
+ controls: l.bool,
210
+ frameBox: l.object,
211
+ theme: l.object,
212
+ cols: l.number,
213
+ rows: l.number
196
214
  }).isRequired,
197
- onComplete: o.func,
198
- onStart: o.func,
199
- onStop: o.func,
200
- onPause: o.func,
201
- onTick: o.func,
202
- onJump: o.func
215
+ onComplete: l.func,
216
+ onStart: l.func,
217
+ onStop: l.func,
218
+ onPause: l.func,
219
+ onTick: l.func,
220
+ onJump: l.func
203
221
  };
204
222
  export {
205
- ie as PLAYER_FRAME_DELAY,
206
- Q as default
223
+ se as PLAYER_FRAME_DELAY,
224
+ V as default
207
225
  };
package/lib/Terminal.js CHANGED
@@ -1,19 +1,21 @@
1
1
  import { jsx as n } from "react/jsx-runtime";
2
2
  import h from "react";
3
- import i from "prop-types";
3
+ import r from "prop-types";
4
4
  import { Terminal as m } from "@xterm/xterm";
5
5
  import { WebLinksAddon as a } from "@xterm/addon-web-links";
6
6
  import { FitAddon as d } from "@xterm/addon-fit";
7
- import l from "lodash/debounce";
8
- import s from "lodash/noop";
9
- import { TerminalRoot as p } from "./styles.js";
10
- class u extends h.Component {
7
+ import p from "lodash/debounce";
8
+ import o from "lodash/noop";
9
+ import { TerminalRoot as f } from "./styles.js";
10
+ class l extends h.Component {
11
11
  xterm = null;
12
12
  container = null;
13
13
  shouldTriggerFitWhenWrite = !1;
14
14
  componentDidMount() {
15
15
  const { value: t = "", options: e = {} } = this.props;
16
- this.fitAddon = new d(), this.xterm = new m(e), this.xterm.loadAddon(new a()), this.xterm.loadAddon(this.fitAddon), this.xterm.open(this.container), this.xterm.onData(this.onData.bind(this)), this.xterm.onRender(this.onRender.bind(this)), t && this.xterm.write(t), this.debounceFit = l(() => {
16
+ this.fitAddon = new d(), this.xterm = new m(e), this.xterm.loadAddon(new a()), this.xterm.loadAddon(this.fitAddon), this.xterm.open(this.container), this.xterm.onData(this.onData.bind(this)), this.xterm.onRender(this.onRender.bind(this)), t && this.xterm.write(t), setTimeout(() => {
17
+ this.xterm && this.fitAddon.fit();
18
+ }, 0), this.debounceFit = p(() => {
17
19
  this.fitAddon.fit();
18
20
  }, 500), window.addEventListener("resize", this.debounceFit);
19
21
  }
@@ -21,8 +23,8 @@ class u extends h.Component {
21
23
  this.xterm && (this.xterm.dispose(), this.xterm = null), window.removeEventListener("resize", this.debounceFit);
22
24
  }
23
25
  shouldComponentUpdate(t) {
24
- const { value: e = "" } = t, { value: r = "" } = this.props;
25
- return t.hasOwnProperty("value") && e !== r && this.xterm && (this.xterm.clear(), setTimeout(() => {
26
+ const { value: e = "" } = t, { value: i = "" } = this.props;
27
+ return t.hasOwnProperty("value") && e !== i && this.xterm && (this.xterm.clear(), setTimeout(() => {
26
28
  this.xterm.write(e);
27
29
  }, 0)), !1;
28
30
  }
@@ -39,20 +41,18 @@ class u extends h.Component {
39
41
  this.xterm && this.xterm.reset();
40
42
  }
41
43
  onData = (t) => {
42
- const { onData: e = s } = this.props;
44
+ const { onData: e = o } = this.props;
43
45
  e(t);
44
46
  };
45
47
  onRender = (t) => {
46
- const { onRender: e = s } = this.props;
48
+ const { onRender: e = o } = this.props;
47
49
  e(t);
48
50
  };
49
- resize() {
50
- if (this.xterm) {
51
- const { cols: t, rows: e } = this.props.options;
52
- this.shouldTriggerFitWhenWrite = !0, setTimeout(() => {
53
- this.xterm.resize(Math.round(t), Math.round(e)), this.shouldTriggerFitWhenWrite = !0;
54
- }, 250);
55
- }
51
+ resize(t, e) {
52
+ this.xterm && (this.shouldTriggerFitWhenWrite = !0, setTimeout(() => {
53
+ const i = Math.round(t ?? this.props.options.cols), s = Math.round(e ?? this.props.options.rows);
54
+ typeof i == "number" && typeof s == "number" && this.xterm.resize(i, s), this.shouldTriggerFitWhenWrite = !0;
55
+ }, 250));
56
56
  }
57
57
  setOption(t, e) {
58
58
  this.xterm && (this.xterm.options[t] = e);
@@ -65,27 +65,27 @@ class u extends h.Component {
65
65
  this.xterm && this.xterm.refresh(0, this.xterm.rows - 1);
66
66
  }
67
67
  render() {
68
- const { className: t = "", style: e = {} } = this.props, r = ["react-xterm", t].filter(Boolean).join(" ");
68
+ const { className: t = "", style: e = {} } = this.props, i = ["react-xterm", t].filter(Boolean).join(" ");
69
69
  return /* @__PURE__ */ n(
70
- p,
70
+ f,
71
71
  {
72
- ref: (o) => {
73
- this.container = o;
72
+ ref: (s) => {
73
+ this.container = s;
74
74
  },
75
- className: r,
75
+ className: i,
76
76
  style: e
77
77
  }
78
78
  );
79
79
  }
80
80
  }
81
- u.propTypes = {
82
- onData: i.func,
83
- onRender: i.func,
84
- options: i.object,
85
- value: i.string,
86
- className: i.string,
87
- style: i.object
81
+ l.propTypes = {
82
+ onData: r.func,
83
+ onRender: r.func,
84
+ options: r.object,
85
+ value: r.string,
86
+ className: r.string,
87
+ style: r.object
88
88
  };
89
89
  export {
90
- u as default
90
+ l as default
91
91
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/terminal",
3
- "version": "3.1.20",
3
+ "version": "3.1.22",
4
4
  "description": "A react wrapper for xterm allowing you to easily render a terminal in the browser",
5
5
  "keywords": [
6
6
  "react",
@@ -40,10 +40,10 @@
40
40
  "peerDependencies": {
41
41
  "react": "^19.0.0"
42
42
  },
43
- "gitHead": "acb1c932b5f600dc38e44aa2b4491a943562b81e",
43
+ "gitHead": "11d0b4fb6ae868d94d232e4e120ee6b25497ee21",
44
44
  "dependencies": {
45
- "@arcblock/react-hooks": "3.1.20",
46
- "@arcblock/ux": "3.1.20",
45
+ "@arcblock/react-hooks": "3.1.22",
46
+ "@arcblock/ux": "3.1.22",
47
47
  "@emotion/react": "^11.14.0",
48
48
  "@emotion/styled": "^11.14.0",
49
49
  "@xterm/addon-fit": "^0.10.0",
package/src/Player.jsx CHANGED
@@ -85,6 +85,7 @@ export default function Player({ ...rawProps }) {
85
85
  const container = useRef(null);
86
86
  const animationRef = useRef(null);
87
87
  const startTimeRef = useRef(null);
88
+ const autoPlayRef = useRef(false);
88
89
  const [state, dispatch] = useReducer(stateReducer, defaultState);
89
90
 
90
91
  // Render a frame with Promise-based approach
@@ -234,6 +235,38 @@ export default function Player({ ...rawProps }) {
234
235
  return false;
235
236
  }, [emitEvent]);
236
237
 
238
+ // Intersection Observer for viewport detection
239
+ useEffect(() => {
240
+ if (!container.current || !options.autoplay || autoPlayRef.current) {
241
+ return;
242
+ }
243
+
244
+ const observer = new IntersectionObserver(
245
+ (entries) => {
246
+ const [entry] = entries;
247
+ if (entry.isIntersecting && !state.isStarted) {
248
+ // 根据视野范围自动开始播放
249
+ onStart();
250
+ autoPlayRef.current = true;
251
+ // 播放后,断开 observer,避免触发多次
252
+ observer.unobserve(container.current);
253
+ observer.disconnect();
254
+ }
255
+ },
256
+ {
257
+ threshold: 0.1, // Trigger when 10% of the element is visible
258
+ rootMargin: '0px 0px 0px 0px', // Add some margin to avoid triggering too early
259
+ }
260
+ );
261
+
262
+ observer.observe(container.current);
263
+
264
+ // eslint-disable-next-line consistent-return
265
+ return () => {
266
+ observer.disconnect();
267
+ };
268
+ }, [options.autoplay, state.isStarted, onStart]);
269
+
237
270
  // Render thumbnailTime
238
271
  useEffect(() => {
239
272
  if (!terminal.current) {
@@ -243,9 +276,7 @@ export default function Player({ ...rawProps }) {
243
276
  // Focus terminal to ensure cursor is visible
244
277
  terminal.current.focus();
245
278
 
246
- if (options.autoplay) {
247
- onStart();
248
- } else {
279
+ if (!options.autoplay) {
249
280
  doJump(Math.min(Math.abs(options.thumbnailTime), totalDuration));
250
281
  }
251
282
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -3,6 +3,7 @@ export { default as AutoPlay } from './demo/autoplay';
3
3
  export { default as Loop } from './demo/loop';
4
4
  export { default as AutoPlayLoop } from './demo/autoplay-loop';
5
5
  export { default as RecordingGuide } from './demo/recording-guide';
6
+ export { default as BlockletLogTerminal } from './demo/blocklet-log-terminal';
6
7
 
7
8
  export default {
8
9
  title: 'Data Display/Terminal/Player',
package/src/Terminal.jsx CHANGED
@@ -33,6 +33,12 @@ export default class Terminal extends React.Component {
33
33
  this.xterm.write(value);
34
34
  }
35
35
 
36
+ setTimeout(() => {
37
+ if (this.xterm) {
38
+ this.fitAddon.fit();
39
+ }
40
+ }, 0);
41
+
36
42
  this.debounceFit = debounce(() => {
37
43
  this.fitAddon.fit();
38
44
  }, 500);
@@ -100,12 +106,15 @@ export default class Terminal extends React.Component {
100
106
  onRender(data);
101
107
  };
102
108
 
103
- resize() {
109
+ resize(_cols, _rows) {
104
110
  if (this.xterm) {
105
- const { cols, rows } = this.props.options;
106
111
  this.shouldTriggerFitWhenWrite = true;
107
112
  setTimeout(() => {
108
- this.xterm.resize(Math.round(cols), Math.round(rows));
113
+ const cols = Math.round(_cols ?? this.props.options.cols);
114
+ const rows = Math.round(_rows ?? this.props.options.rows);
115
+ if (typeof cols === 'number' && typeof rows === 'number') {
116
+ this.xterm.resize(cols, rows);
117
+ }
109
118
  this.shouldTriggerFitWhenWrite = true;
110
119
  }, 250);
111
120
  }