@xiping/react-components 1.0.53 → 1.0.55

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.
@@ -1,7 +1,8 @@
1
- import { jsxs as G, jsx as n } from "react/jsx-runtime";
2
- import T from "clsx";
3
- import { useState as L, useRef as s, useCallback as a, useEffect as E, useMemo as g } from "react";
4
- const W = (N) => {
1
+ import { jsxs as j, jsx as t } from "react/jsx-runtime";
2
+ import F from "clsx";
3
+ import { useState as E, useRef as i, useCallback as a, useEffect as y, useMemo as w } from "react";
4
+ /* empty css */
5
+ const q = (N) => {
5
6
  const {
6
7
  originalImage: c,
7
8
  modifiedImage: b,
@@ -9,39 +10,39 @@ const W = (N) => {
9
10
  dividerWidth: l = 1,
10
11
  originalLabel: I = "原图",
11
12
  modifiedLabel: P = "处理过的图"
12
- } = N, [i, z] = L(50), [x, $] = L(16 / 9), p = s(null), u = s(!1), o = s(null), d = s(null), t = s(null), k = a((e) => {
13
- if (!p.current) return;
14
- (!d.current || !u.current) && (d.current = p.current.getBoundingClientRect());
15
- const r = d.current, h = (e - r.left) / r.width * 100, f = Math.min(100, Math.max(0, h));
16
- z(f);
13
+ } = N, [s, $] = E(50), [x, A] = E(16 / 9), h = i(null), u = i(!1), o = i(null), d = i(null), n = i(null), k = a((e) => {
14
+ if (!h.current) return;
15
+ (!d.current || !u.current) && (d.current = h.current.getBoundingClientRect());
16
+ const r = d.current, g = (e - r.left) / r.width * 100, p = Math.min(100, Math.max(0, g));
17
+ $(p);
17
18
  }, []), m = a((e) => {
18
19
  u.current && (o.current !== null && cancelAnimationFrame(o.current), o.current = requestAnimationFrame(() => {
19
20
  k(e);
20
21
  }));
21
- }, [k]), y = a((e) => {
22
+ }, [k]), M = a((e) => {
22
23
  m(e.clientX);
23
- }, [m]), M = a((e) => {
24
+ }, [m]), R = a((e) => {
24
25
  e.touches.length > 0 && m(e.touches[0].clientX);
25
- }, [m]), R = a(() => {
26
+ }, [m]), L = a(() => {
26
27
  u.current = !0, d.current = null;
27
- const e = (w) => y(w), r = (w) => M(w), v = () => {
28
- u.current = !1, o.current !== null && (cancelAnimationFrame(o.current), o.current = null), t.current && (t.current(), t.current = null);
29
- }, h = () => v(), f = () => v();
30
- window.addEventListener("mousemove", e), window.addEventListener("touchmove", r, { passive: !1 }), window.addEventListener("mouseup", h), window.addEventListener("touchend", f);
31
- const D = () => {
32
- window.removeEventListener("mousemove", e), window.removeEventListener("touchmove", r), window.removeEventListener("mouseup", h), window.removeEventListener("touchend", f);
28
+ const e = (f) => M(f), r = (f) => R(f), v = () => {
29
+ u.current = !1, o.current !== null && (cancelAnimationFrame(o.current), o.current = null), n.current && (n.current(), n.current = null);
30
+ }, g = () => v(), p = () => v();
31
+ window.addEventListener("mousemove", e), window.addEventListener("touchmove", r, { passive: !1 }), window.addEventListener("mouseup", g), window.addEventListener("touchend", p);
32
+ const T = () => {
33
+ window.removeEventListener("mousemove", e), window.removeEventListener("touchmove", r), window.removeEventListener("mouseup", g), window.removeEventListener("touchend", p);
33
34
  };
34
- t.current = D;
35
- }, [y, M]);
36
- E(() => () => {
37
- t.current && (t.current(), t.current = null);
38
- }, []), E(() => {
35
+ n.current = T;
36
+ }, [M, R]);
37
+ y(() => () => {
38
+ n.current && (n.current(), n.current = null);
39
+ }, []), y(() => {
39
40
  const e = new Image();
40
41
  e.onload = () => {
41
- $(e.width / e.height);
42
+ A(e.width / e.height);
42
43
  }, e.src = c;
43
44
  }, [c]);
44
- const j = g(
45
+ const C = w(
45
46
  () => ({
46
47
  backgroundRepeat: "no-repeat",
47
48
  backgroundPosition: "top left",
@@ -50,54 +51,54 @@ const W = (N) => {
50
51
  aspectRatio: x
51
52
  }),
52
53
  [c, x]
53
- ), A = g(
54
+ ), D = w(
54
55
  () => ({
55
- width: `${i}%`,
56
+ width: `${s}%`,
56
57
  backgroundImage: `url(${b})`,
57
58
  backgroundRepeat: "no-repeat",
58
59
  backgroundPosition: "top left",
59
60
  backgroundSize: "auto 100%"
60
61
  }),
61
- [i, b]
62
- ), C = g(
62
+ [s, b]
63
+ ), G = w(
63
64
  () => ({
64
- left: `${i}%`,
65
+ left: `${s}%`,
65
66
  transform: "translateX(-50%)",
66
67
  width: typeof l == "number" ? `${l}px` : l
67
68
  }),
68
- [i, l]
69
+ [s, l]
69
70
  );
70
- return /* @__PURE__ */ G(
71
+ return /* @__PURE__ */ j(
71
72
  "div",
72
73
  {
73
- ref: p,
74
- className: T("relative select-none overflow-hidden w-full", S),
75
- style: j,
74
+ ref: h,
75
+ className: F("xiping-image-compare-container", S),
76
+ style: C,
76
77
  children: [
77
- /* @__PURE__ */ n("div", { className: "absolute top-4 left-4 px-3 py-1.5 bg-black/60 text-white text-sm font-medium rounded backdrop-blur-sm z-10", children: I }),
78
- /* @__PURE__ */ n(
78
+ /* @__PURE__ */ t("div", { className: "xiping-image-compare-label xiping-image-compare-label-original", children: I }),
79
+ /* @__PURE__ */ t(
79
80
  "div",
80
81
  {
81
- className: "absolute inset-0 h-full overflow-hidden",
82
- style: A,
83
- children: /* @__PURE__ */ n("div", { className: "absolute top-4 right-4 px-3 py-1.5 bg-black/60 text-white text-sm font-medium rounded backdrop-blur-sm z-10", children: P })
82
+ className: "xiping-image-compare-overlay",
83
+ style: D,
84
+ children: /* @__PURE__ */ t("div", { className: "xiping-image-compare-label xiping-image-compare-label-modified", children: P })
84
85
  }
85
86
  ),
86
- /* @__PURE__ */ n(
87
+ /* @__PURE__ */ t(
87
88
  "div",
88
89
  {
89
- className: "absolute top-0 bottom-0 bg-white cursor-ew-resize",
90
- style: C,
91
- onMouseDown: R,
92
- onTouchStart: R,
93
- children: /* @__PURE__ */ n("div", { className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-8 h-8 rounded-full bg-white shadow-lg flex items-center justify-center", children: /* @__PURE__ */ n(
90
+ className: "xiping-image-compare-divider",
91
+ style: G,
92
+ onMouseDown: L,
93
+ onTouchStart: L,
94
+ children: /* @__PURE__ */ t("div", { className: "xiping-image-compare-divider-button", children: /* @__PURE__ */ t(
94
95
  "svg",
95
96
  {
96
- className: "w-6 h-6 text-gray-600",
97
+ className: "xiping-image-compare-divider-icon",
97
98
  fill: "none",
98
99
  stroke: "currentColor",
99
100
  viewBox: "0 0 24 24",
100
- children: /* @__PURE__ */ n(
101
+ children: /* @__PURE__ */ t(
101
102
  "path",
102
103
  {
103
104
  strokeLinecap: "round",
@@ -115,5 +116,5 @@ const W = (N) => {
115
116
  );
116
117
  };
117
118
  export {
118
- W as default
119
+ q as default
119
120
  };
@@ -30,13 +30,10 @@ const P = ({
30
30
  "div",
31
31
  {
32
32
  ref: h ? a : null,
33
- className: W(
34
- "xiping-subtitle-player__item",
35
- {
36
- "xiping-subtitle-player__item--active": h,
37
- "xiping-subtitle-player__item--past": w
38
- }
39
- ),
33
+ className: W("xiping-subtitle-player__item", {
34
+ "xiping-subtitle-player__item--active": h,
35
+ "xiping-subtitle-player__item--past": w
36
+ }),
40
37
  "data-label": i || void 0,
41
38
  onClick: c ? (l) => c(l, t, i) : void 0,
42
39
  style: c ? { cursor: "pointer" } : void 0,
@@ -46,7 +43,14 @@ const P = ({
46
43
  /* @__PURE__ */ s("div", { className: "xiping-subtitle-player__text", children: t.text.split(`
47
44
  `).map((l, d) => {
48
45
  if (!t.words || t.words.length === 0)
49
- return /* @__PURE__ */ s("div", { className: "xiping-subtitle-player__line", children: l }, d);
46
+ return /* @__PURE__ */ s(
47
+ "div",
48
+ {
49
+ className: "xiping-subtitle-player__line",
50
+ children: l
51
+ },
52
+ d
53
+ );
50
54
  const f = A(
51
55
  l,
52
56
  t.words,
@@ -54,7 +58,14 @@ const P = ({
54
58
  d,
55
59
  u ? N(t, i) : void 0
56
60
  );
57
- return x = f.nextWordIndex, /* @__PURE__ */ s("div", { className: "xiping-subtitle-player__line", children: f.nodes }, d);
61
+ return x = f.nextWordIndex, /* @__PURE__ */ s(
62
+ "div",
63
+ {
64
+ className: "xiping-subtitle-player__line",
65
+ children: f.nodes
66
+ },
67
+ d
68
+ );
58
69
  }) })
59
70
  ]
60
71
  },
@@ -16,7 +16,7 @@ export interface VideoSubtitlePlayerProps {
16
16
  }
17
17
  /**
18
18
  * 视频字幕播放器组件
19
- * 左侧:上部分16:9视频播放器,下部分字幕显示
19
+ * 左侧:上部分视频播放器(填充模式),下部分字幕显示
20
20
  * 右侧:字幕详情(单词/短语的发音、解释等)
21
21
  */
22
22
  export declare const VideoSubtitlePlayer: React.FC<VideoSubtitlePlayerProps>;
@@ -1,125 +1,128 @@
1
- import { jsxs as a, jsx as e } from "react/jsx-runtime";
2
- import { useRef as b, useEffect as c, useCallback as C } from "react";
1
+ import { jsx as e, jsxs as t } from "react/jsx-runtime";
2
+ import { useRef as N, useEffect as u, useCallback as H } from "react";
3
3
  import I from "xgplayer";
4
4
  /* empty css */
5
- import { SubtitlePlayer as R } from "../subtitle-player/SubtitlePlayer.js";
6
- import { useVideoSubtitleStore as j } from "./useVideoSubtitleStore.js";
5
+ import { PanelGroup as z, Panel as o, PanelResizeHandle as S } from "react-resizable-panels";
6
+ import { SubtitlePlayer as j } from "../subtitle-player/SubtitlePlayer.js";
7
+ import { useVideoSubtitleStore as D } from "./useVideoSubtitleStore.js";
7
8
  /* empty css */
8
- const z = ({
9
- videoUrl: u,
10
- subtitles: o,
11
- poster: m,
12
- className: N = "",
9
+ const q = ({
10
+ videoUrl: m,
11
+ subtitles: p,
12
+ poster: v,
13
+ className: P = "",
13
14
  style: w,
14
- onFetchDetail: p
15
+ onFetchDetail: c
15
16
  }) => {
16
- const n = b(null), d = b(null), {
17
+ const n = N(null), d = N(null), {
17
18
  currentTime: r,
18
- isPlaying: D,
19
- setCurrentTime: v,
19
+ isPlaying: E,
20
+ setCurrentTime: _,
20
21
  setIsPlaying: s,
21
- setSubtitles: _,
22
+ setSubtitles: h,
22
23
  currentDetail: l,
23
- isLoadingDetail: P,
24
+ isLoadingDetail: T,
24
25
  fetchDetail: y
25
- } = j();
26
- c(() => {
27
- _(o);
28
- }, [o, _]), c(() => {
26
+ } = D();
27
+ u(() => {
28
+ h(p);
29
+ }, [p, h]), u(() => {
29
30
  if (!n.current) return;
30
- const t = `xiping-video-subtitle-player-${Date.now()}`;
31
- n.current && (n.current.id = t);
31
+ const a = `xiping-video-subtitle-player-${Date.now()}`;
32
+ n.current && (n.current.id = a);
32
33
  const i = new I({
33
- id: t,
34
- url: u,
35
- poster: m,
34
+ id: a,
35
+ url: m,
36
+ poster: v,
36
37
  autoplay: !1,
37
- fluid: !0,
38
+ fluid: !1,
38
39
  width: "100%",
39
40
  height: "100%",
40
41
  controls: !0
41
42
  });
42
43
  d.current = i;
43
- const h = () => {
44
- const T = i.currentTime || 0;
45
- v(T);
46
- }, f = () => {
47
- s(!0);
44
+ const f = () => {
45
+ const R = i.currentTime || 0;
46
+ _(R);
48
47
  }, x = () => {
49
- s(!1);
48
+ s(!0);
50
49
  }, g = () => {
51
50
  s(!1);
51
+ }, b = () => {
52
+ s(!1);
52
53
  };
53
- return i.on("timeupdate", h), i.on("play", f), i.on("pause", x), i.on("ended", g), () => {
54
- i.off("timeupdate", h), i.off("play", f), i.off("pause", x), i.off("ended", g), i.destroy(), d.current = null;
54
+ return i.on("timeupdate", f), i.on("play", x), i.on("pause", g), i.on("ended", b), () => {
55
+ i.off("timeupdate", f), i.off("play", x), i.off("pause", g), i.off("ended", b), i.destroy(), d.current = null;
55
56
  };
56
- }, [u, m, v, s]), c(() => {
57
+ }, [m, v, _, s]), u(() => {
57
58
  if (d.current) {
58
- const t = d.current;
59
- Math.abs(t.currentTime - r) > 0.5 && (t.currentTime = r);
59
+ const a = d.current;
60
+ Math.abs(a.currentTime - r) > 0.5 && (a.currentTime = r);
60
61
  }
61
62
  }, [r]);
62
- const S = C(
63
- async (t) => {
64
- p ? await p(t) : await y(t);
63
+ const C = H(
64
+ async (a) => {
65
+ c ? await c(a) : await y(a);
65
66
  },
66
- [p, y]
67
- );
68
- return /* @__PURE__ */ a(
69
- "div",
70
- {
71
- className: `xiping-video-subtitle-player ${N}`,
72
- style: w,
73
- children: [
74
- /* @__PURE__ */ a("div", { className: "xiping-video-subtitle-player__left", children: [
75
- /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__video-container", children: /* @__PURE__ */ e(
76
- "div",
77
- {
78
- ref: n,
79
- className: "xiping-video-subtitle-player__video"
80
- }
81
- ) }),
82
- /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__subtitle-container", children: /* @__PURE__ */ e(
83
- R,
84
- {
85
- subtitles: o,
86
- currentTime: r,
87
- mode: "current",
88
- onWordHoverChange: S
89
- }
90
- ) })
91
- ] }),
92
- /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__right", children: /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail", children: P ? /* @__PURE__ */ a("div", { className: "xiping-video-subtitle-player__detail-loading", children: [
93
- /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-loading-spinner" }),
94
- /* @__PURE__ */ e("span", { children: "加载中..." })
95
- ] }) : l ? /* @__PURE__ */ a("div", { className: "xiping-video-subtitle-player__detail-content", children: [
96
- /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-word", children: l.word }),
97
- l.pronunciation && /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-pronunciation", children: l.pronunciation }),
98
- l.partOfSpeech && /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-pos", children: l.partOfSpeech }),
99
- l.translation && /* @__PURE__ */ a("div", { className: "xiping-video-subtitle-player__detail-translation", children: [
100
- /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-label", children: "中文翻译" }),
101
- /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-text", children: l.translation })
102
- ] }),
103
- l.definition && /* @__PURE__ */ a("div", { className: "xiping-video-subtitle-player__detail-definition", children: [
104
- /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-label", children: "英文解释" }),
105
- /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-text", children: l.definition })
106
- ] }),
107
- l.examples && l.examples.length > 0 && /* @__PURE__ */ a("div", { className: "xiping-video-subtitle-player__detail-examples", children: [
108
- /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-label", children: "例句" }),
109
- l.examples.map((t, i) => /* @__PURE__ */ a("div", { className: "xiping-video-subtitle-player__detail-example", children: [
110
- /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-example-en", children: t.sentence }),
111
- /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-example-zh", children: t.translation })
112
- ] }, i))
113
- ] })
114
- ] }) : /* @__PURE__ */ a("div", { className: "xiping-video-subtitle-player__detail-empty", children: [
115
- /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-empty-icon", children: "📖" }),
116
- /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-empty-text", children: "将鼠标悬停在字幕单词上查看详情" })
117
- ] }) }) })
118
- ]
119
- }
67
+ [c, y]
120
68
  );
69
+ return /* @__PURE__ */ e("div", { className: `xiping-video-subtitle-player ${P}`, style: w, children: /* @__PURE__ */ t(z, { direction: "horizontal", children: [
70
+ /* @__PURE__ */ e(o, { defaultSize: 65, minSize: 40, children: /* @__PURE__ */ t(z, { direction: "vertical", children: [
71
+ /* @__PURE__ */ e(o, { defaultSize: 60, minSize: 30, children: /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__video-wrapper", children: /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__video-container", children: /* @__PURE__ */ e(
72
+ "div",
73
+ {
74
+ ref: n,
75
+ className: "xiping-video-subtitle-player__video"
76
+ }
77
+ ) }) }) }),
78
+ /* @__PURE__ */ e(S, { className: "xiping-video-subtitle-player__resize-handle xiping-video-subtitle-player__resize-handle--vertical" }),
79
+ /* @__PURE__ */ e(o, { defaultSize: 40, minSize: 20, children: /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__subtitle-container", children: /* @__PURE__ */ e(
80
+ j,
81
+ {
82
+ subtitles: p,
83
+ currentTime: r,
84
+ mode: "current",
85
+ onWordHoverChange: C
86
+ }
87
+ ) }) })
88
+ ] }) }),
89
+ /* @__PURE__ */ e(S, { className: "xiping-video-subtitle-player__resize-handle xiping-video-subtitle-player__resize-handle--horizontal" }),
90
+ /* @__PURE__ */ e(o, { defaultSize: 35, minSize: 25, maxSize: 50, children: /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__right", children: /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail", children: T ? /* @__PURE__ */ t("div", { className: "xiping-video-subtitle-player__detail-loading", children: [
91
+ /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-loading-spinner" }),
92
+ /* @__PURE__ */ e("span", { children: "加载中..." })
93
+ ] }) : l ? /* @__PURE__ */ t("div", { className: "xiping-video-subtitle-player__detail-content", children: [
94
+ /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-word", children: l.word }),
95
+ l.pronunciation && /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-pronunciation", children: l.pronunciation }),
96
+ l.partOfSpeech && /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-pos", children: l.partOfSpeech }),
97
+ l.translation && /* @__PURE__ */ t("div", { className: "xiping-video-subtitle-player__detail-translation", children: [
98
+ /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-label", children: "中文翻译" }),
99
+ /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-text", children: l.translation })
100
+ ] }),
101
+ l.definition && /* @__PURE__ */ t("div", { className: "xiping-video-subtitle-player__detail-definition", children: [
102
+ /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-label", children: "英文解释" }),
103
+ /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-text", children: l.definition })
104
+ ] }),
105
+ l.examples && l.examples.length > 0 && /* @__PURE__ */ t("div", { className: "xiping-video-subtitle-player__detail-examples", children: [
106
+ /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-label", children: "例句" }),
107
+ l.examples.map((a, i) => /* @__PURE__ */ t(
108
+ "div",
109
+ {
110
+ className: "xiping-video-subtitle-player__detail-example",
111
+ children: [
112
+ /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-example-en", children: a.sentence }),
113
+ /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-example-zh", children: a.translation })
114
+ ]
115
+ },
116
+ i
117
+ ))
118
+ ] })
119
+ ] }) : /* @__PURE__ */ t("div", { className: "xiping-video-subtitle-player__detail-empty", children: [
120
+ /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-empty-icon", children: "📖" }),
121
+ /* @__PURE__ */ e("div", { className: "xiping-video-subtitle-player__detail-empty-text", children: "将鼠标悬停在字幕单词上查看详情" })
122
+ ] }) }) }) })
123
+ ] }) });
121
124
  };
122
125
  export {
123
- z as VideoSubtitlePlayer,
124
- z as default
126
+ q as VideoSubtitlePlayer,
127
+ q as default
125
128
  };