@xiping/react-components 1.0.57 → 1.0.59
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/README.md +92 -6
- package/dist/cjs/components/comic-text/ComicText.css +1 -1
- package/dist/cjs/components/dock/Duck.css +1 -1
- package/dist/cjs/components/gradient-text/index.css +1 -1
- package/dist/cjs/components/gradient-text/index.js +1 -1
- package/dist/cjs/components/image-compare/ImageCompare.css +1 -1
- package/dist/cjs/components/image-viewer/ImageThumbnails.css +1 -1
- package/dist/cjs/components/image-viewer/ImageViewer.css +1 -1
- package/dist/cjs/components/message/Message.js +1 -1
- package/dist/cjs/components/scratch-to-reveal/ScratchToReveal.css +1 -1
- package/dist/cjs/components/subtitle-player/LyricsMode.css +1 -1
- package/dist/cjs/components/subtitle-player/SubtitlePlayer.js +1 -1
- package/dist/cjs/components/txt-reader/TxtReader.js +1 -1
- package/dist/cjs/components/typing-animation/index.js +1 -1
- package/dist/cjs/components/variable-proximity/index.css +1 -1
- package/dist/cjs/components/variable-proximity/index.js +1 -1
- package/dist/cjs/components/video-subtitle-player/VideoSubtitlePlayer.css +1 -1
- package/dist/cjs/components/video-subtitle-player/VideoSubtitlePlayer.d.ts +3 -3
- package/dist/cjs/components/video-subtitle-player/VideoSubtitlePlayer.js +1 -1
- package/dist/cjs/components/video-subtitle-player/VideoSubtitlePlayer.mobile.css +1 -0
- package/dist/cjs/components/video-subtitle-player/VideoSubtitlePlayer.pc.css +1 -0
- package/dist/cjs/components/video-subtitle-player/VideoSubtitlePlayerMobile.d.ts +20 -0
- package/dist/cjs/components/video-subtitle-player/VideoSubtitlePlayerMobile.js +1 -0
- package/dist/cjs/components/video-subtitle-player/VideoSubtitlePlayerPC.d.ts +23 -0
- package/dist/cjs/components/video-subtitle-player/VideoSubtitlePlayerPC.js +1 -0
- package/dist/cjs/components/video-subtitle-player/layouts/VideoSubtitlePlayerLayoutMobile.d.ts +8 -0
- package/dist/cjs/components/video-subtitle-player/layouts/VideoSubtitlePlayerLayoutMobile.js +1 -0
- package/dist/cjs/components/video-subtitle-player/layouts/VideoSubtitlePlayerLayoutPC.d.ts +6 -0
- package/dist/cjs/components/video-subtitle-player/layouts/VideoSubtitlePlayerLayoutPC.js +1 -0
- package/dist/cjs/components/video-subtitle-player/layouts/index.d.ts +3 -0
- package/dist/cjs/components/video-subtitle-player/layouts/types.d.ts +17 -0
- package/dist/cjs/components/video-subtitle-player/useXGPlayer.d.ts +10 -0
- package/dist/cjs/components/video-subtitle-player/useXGPlayer.js +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/node_modules/.pnpm/xgplayer@3.0.23_core-js@3.47.0/node_modules/xgplayer/dist/index.min.css +1 -1
- package/dist/cjs/react-components.css +114 -0
- package/dist/cjs/utils/utils.d.ts +1 -0
- package/dist/es/components/comic-text/ComicText.css +1 -1
- package/dist/es/components/confetti-button/index.js +1 -1
- package/dist/es/components/dock/Duck.css +1 -1
- package/dist/es/components/gradient-text/index.css +1 -1
- package/dist/es/components/gradient-text/index.js +6 -7
- package/dist/es/components/image-compare/ImageCompare.css +1 -1
- package/dist/es/components/image-viewer/ImageThumbnails.css +1 -1
- package/dist/es/components/image-viewer/ImageViewer.css +1 -1
- package/dist/es/components/message/Message.js +15 -16
- package/dist/es/components/scratch-to-reveal/ScratchToReveal.css +1 -1
- package/dist/es/components/subtitle-player/LyricsMode.css +1 -1
- package/dist/es/components/subtitle-player/SubtitlePlayer.js +9 -10
- package/dist/es/components/txt-reader/TxtReader.js +9 -10
- package/dist/es/components/typing-animation/index.js +17 -18
- package/dist/es/components/variable-proximity/index.css +1 -1
- package/dist/es/components/variable-proximity/index.js +28 -29
- package/dist/es/components/video-subtitle-player/VideoSubtitlePlayer.css +1 -1
- package/dist/es/components/video-subtitle-player/VideoSubtitlePlayer.d.ts +3 -3
- package/dist/es/components/video-subtitle-player/VideoSubtitlePlayer.js +65 -126
- package/dist/es/components/video-subtitle-player/VideoSubtitlePlayer.mobile.css +1 -0
- package/dist/es/components/video-subtitle-player/VideoSubtitlePlayer.pc.css +1 -0
- package/dist/es/components/video-subtitle-player/VideoSubtitlePlayerMobile.d.ts +20 -0
- package/dist/es/components/video-subtitle-player/VideoSubtitlePlayerMobile.js +47 -0
- package/dist/es/components/video-subtitle-player/VideoSubtitlePlayerPC.d.ts +23 -0
- package/dist/es/components/video-subtitle-player/VideoSubtitlePlayerPC.js +75 -0
- package/dist/es/components/video-subtitle-player/layouts/VideoSubtitlePlayerLayoutMobile.d.ts +8 -0
- package/dist/es/components/video-subtitle-player/layouts/VideoSubtitlePlayerLayoutMobile.js +21 -0
- package/dist/es/components/video-subtitle-player/layouts/VideoSubtitlePlayerLayoutPC.d.ts +6 -0
- package/dist/es/components/video-subtitle-player/layouts/VideoSubtitlePlayerLayoutPC.js +50 -0
- package/dist/es/components/video-subtitle-player/layouts/index.d.ts +3 -0
- package/dist/es/components/video-subtitle-player/layouts/types.d.ts +17 -0
- package/dist/es/components/video-subtitle-player/useXGPlayer.d.ts +10 -0
- package/dist/es/components/video-subtitle-player/useXGPlayer.js +36 -0
- package/dist/es/index.js +51 -51
- package/dist/es/node_modules/.pnpm/xgplayer@3.0.23_core-js@3.47.0/node_modules/xgplayer/dist/index.min.css +1 -1
- package/dist/es/react-components.css +114 -0
- package/dist/es/utils/utils.d.ts +1 -0
- package/package.json +29 -30
package/README.md
CHANGED
|
@@ -1,15 +1,101 @@
|
|
|
1
1
|
# @xiping/react-components
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
A modern React component library built with TypeScript, providing rich animation components, media components, and interactive components.
|
|
4
|
+
|
|
5
|
+
## Documentation & Demo
|
|
6
|
+
|
|
7
|
+
[View Documentation and Demo](https://xiping-react-components.vercel.app/)
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
6
10
|
|
|
7
11
|
```shell
|
|
8
12
|
npm i @xiping/react-components
|
|
9
|
-
|
|
13
|
+
# or
|
|
10
14
|
yarn add @xiping/react-components
|
|
11
|
-
|
|
15
|
+
# or
|
|
12
16
|
pnpm add @xiping/react-components
|
|
13
17
|
```
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### Basic Import
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { ShinyButton, BlurFade } from "@xiping/react-components";
|
|
25
|
+
|
|
26
|
+
function App() {
|
|
27
|
+
return (
|
|
28
|
+
<div>
|
|
29
|
+
<ShinyButton>Click me</ShinyButton>
|
|
30
|
+
<BlurFade>
|
|
31
|
+
<h1>Hello World</h1>
|
|
32
|
+
</BlurFade>
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Global Styles (Optional)
|
|
39
|
+
|
|
40
|
+
If your project uses Tailwind CSS, you can import the global styles:
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import "@xiping/react-components/style.css";
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Requirements
|
|
47
|
+
|
|
48
|
+
- **React**: >= 18 || >= 19
|
|
49
|
+
- **React DOM**: >= 18 || >= 19
|
|
50
|
+
|
|
51
|
+
## Components
|
|
52
|
+
|
|
53
|
+
### Text Animations
|
|
54
|
+
|
|
55
|
+
- `BlurFade` - Blur fade-in animation
|
|
56
|
+
- `BlurText` - Blur text effect
|
|
57
|
+
- `TypingAnimation` - Typewriter effect
|
|
58
|
+
- `TextType` - Text type animation
|
|
59
|
+
- `SplitText` - Text split animation
|
|
60
|
+
- `FlipText` - Text flip animation
|
|
61
|
+
- `GradientText` - Gradient text
|
|
62
|
+
- `HyperText` - Hyperlink text effect
|
|
63
|
+
- `MorphingText` - Text morphing animation
|
|
64
|
+
- `VariableProximity` - Variable proximity effect
|
|
65
|
+
- `ComicText` - Comic-style text
|
|
66
|
+
- `TextAnimate` - Generic text animation
|
|
67
|
+
- `SparklesText` - Sparkling text effect
|
|
68
|
+
- `ShinyText` - Shiny text
|
|
69
|
+
|
|
70
|
+
### Buttons
|
|
71
|
+
|
|
72
|
+
- `ShinyButton` - Shiny button
|
|
73
|
+
- `ShimmerButton` - Shimmer button
|
|
74
|
+
- `ConfettiButton` - Confetti celebration button
|
|
75
|
+
|
|
76
|
+
### Media
|
|
77
|
+
|
|
78
|
+
- `VideoSubtitlePlayer` - Video subtitle player
|
|
79
|
+
- `SubtitlePlayer` - Subtitle player
|
|
80
|
+
- `VideoDialog` - Video dialog
|
|
81
|
+
- `ImageViewer` - Image viewer
|
|
82
|
+
- `ImageCompare` - Image comparison
|
|
83
|
+
- `DomeGallery` - Dome gallery
|
|
84
|
+
|
|
85
|
+
### Interactions
|
|
86
|
+
|
|
87
|
+
- `ScratchToReveal` - Scratch card effect
|
|
88
|
+
- `Pointer` - Custom pointer
|
|
89
|
+
- `PinchContent` - Pinch to zoom
|
|
90
|
+
- `Dock` - macOS-style Dock
|
|
91
|
+
- `ReactForceGraph3D` - 3D force-directed graph
|
|
92
|
+
- `Message` - Message toast
|
|
93
|
+
|
|
94
|
+
### Editors
|
|
95
|
+
|
|
96
|
+
- `TxtEditor` - Text editor
|
|
97
|
+
- `TxtReader` - Text reader
|
|
98
|
+
|
|
99
|
+
## License
|
|
100
|
+
|
|
101
|
+
MIT
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.xiping-comic-text{-webkit-user-select:none
|
|
1
|
+
.xiping-comic-text{-webkit-user-select:none;user-select:none;text-align:center}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.xiping-dock{margin-left:auto;margin-right:auto;margin-top:2rem;display:flex;height:58px;width
|
|
1
|
+
.xiping-dock{margin-left:auto;margin-right:auto;margin-top:2rem;display:flex;height:58px;width:max-content;align-items:center;justify-content:center;gap:.5rem;border-radius:1rem;border:1px solid;padding:.5rem;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}@supports (backdrop-filter: blur(12px)){.xiping-dock{background-color:#ffffff1a}.dark .xiping-dock{background-color:#0000001a}}.xiping-dock--top{align-items:flex-start}.xiping-dock--middle{align-items:center}.xiping-dock--bottom{align-items:flex-end}.xiping-dock-icon{display:flex;aspect-ratio:1 / 1;cursor:pointer;align-items:center;justify-content:center;border-radius:9999px}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.xiping-gradient-text{position:relative;margin:0 auto;display:flex;max-width
|
|
1
|
+
.xiping-gradient-text{position:relative;margin:0 auto;display:flex;max-width:fit-content;flex-direction:row;align-items:center;justify-content:center;border-radius:1.25rem;font-weight:500;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);transition:box-shadow .5s ease-out;overflow:hidden;cursor:pointer}.xiping-gradient-text__overlay{position:absolute;inset:0;background-size:300% 100%;animation:xiping-gradient linear infinite;border-radius:inherit;z-index:0;pointer-events:none}.xiping-gradient-text__overlay:before{content:"";position:absolute;border-radius:inherit;width:calc(100% - 2px);height:calc(100% - 2px);left:50%;top:50%;transform:translate(-50%,-50%);background-color:#060010;z-index:-1}@keyframes xiping-gradient{0%{background-position:0% 50%}50%{background-position:100% 50%}to{background-position:0% 50%}}.xiping-gradient-text__content{display:inline-block;position:relative;z-index:2;background-size:300% 100%;background-clip:text;-webkit-background-clip:text;color:transparent;animation:xiping-gradient linear infinite}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('./index.css');const e=require("react/jsx-runtime"),o=require("clsx");;/* empty css */function d({children:i,className:a="",colors:n=["#40ffaa","#4079ff","#40ffaa","#4079ff","#40ffaa"],animationSpeed:r=8,showBorder:s=!1}){const t={backgroundImage:`linear-gradient(to right, ${n.join(", ")})`,animationDuration:`${r}s`};return e.jsxs("div",{className:o("xiping-gradient-text",a),children:[s&&e.jsx("div",{className:"xiping-gradient-text__overlay",style:t}),e.jsx("div",{className:"xiping-gradient-text__content",style:t,children:i})]})}exports.GradientText=d;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.xiping-image-compare-container{position:relative;-webkit-user-select:none
|
|
1
|
+
.xiping-image-compare-container{position:relative;-webkit-user-select:none;user-select:none;overflow:hidden;width:100%}.xiping-image-compare-label{position:absolute;top:1rem;padding:.25rem .5rem;background-color:#0009;color:#fff;font-size:.75rem;font-weight:500;border-radius:.25rem;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:10}.xiping-image-compare-label-original{right:1rem}.xiping-image-compare-label-modified{left:1rem}.xiping-image-compare-overlay{position:absolute;inset:0;height:100%;overflow:hidden}.xiping-image-compare-divider{position:absolute;top:0;bottom:0;background-color:#ffffffe6;cursor:ew-resize;box-shadow:0 0 0 1px #0000004d,0 0 0 1px #ffffff80 inset,0 0 8px #0003}.xiping-image-compare-divider-button{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:2rem;height:2rem;border-radius:50%;background-color:#fffffff2;border:2px solid rgba(0,0,0,.2);box-shadow:0 0 0 1px #fffc,0 4px 12px #0000004d,0 2px 4px #0003;display:flex;align-items:center;justify-content:center;transition:box-shadow .2s ease,transform .2s ease}.xiping-image-compare-divider-button:hover{box-shadow:0 0 0 1px #ffffffe6,0 6px 16px #0006,0 3px 6px #0000004d;transform:translate(-50%,-50%) scale(1.05)}.xiping-image-compare-divider-button:active{transform:translate(-50%,-50%) scale(.95)}.xiping-image-compare-divider-icon{width:1.5rem;height:1.5rem;color:#1f2937}.xiping-image-compare-divider-theme-dark{background-color:#000000e6;box-shadow:0 0 0 1px #ffffff4d,0 0 0 1px #00000080 inset,0 0 8px #fff3}.xiping-image-compare-divider-button-theme-dark{background-color:#000000f2;border:2px solid rgba(255,255,255,.2);box-shadow:0 0 0 1px #000c,0 4px 12px #ffffff4d,0 2px 4px #fff3}.xiping-image-compare-divider-button-theme-dark:hover{box-shadow:0 0 0 1px #000000e6,0 6px 16px #fff6,0 3px 6px #ffffff4d}.xiping-image-compare-divider-theme-dark .xiping-image-compare-divider-icon{color:#f3f4f6}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.xiping-thumbnails-wrapper{height:6rem;background-color:#00000080;flex-shrink:0;z-index:10;padding-bottom:env(safe-area-inset-bottom);padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right)}.xiping-thumbnails-wrapper--hidden{display:none}.xiping-thumbnails-scroll{height:6rem;width:100vw;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;scrollbar-width:none;-ms-overflow-style:none}.xiping-thumbnails-scroll::-webkit-scrollbar{display:none}.xiping-thumbnails-container{display:flex;gap:.5rem;padding:.5rem;height:6rem;min-width
|
|
1
|
+
.xiping-thumbnails-wrapper{height:6rem;background-color:#00000080;flex-shrink:0;z-index:10;padding-bottom:env(safe-area-inset-bottom);padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right)}.xiping-thumbnails-wrapper--hidden{display:none}.xiping-thumbnails-scroll{height:6rem;width:100vw;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;scrollbar-width:none;-ms-overflow-style:none}.xiping-thumbnails-scroll::-webkit-scrollbar{display:none}.xiping-thumbnails-container{display:flex;gap:.5rem;padding:.5rem;height:6rem;min-width:max-content}.xiping-thumbnail-item{height:100%;aspect-ratio:1 / 1;flex-shrink:0;cursor:pointer;border:2px solid transparent;transition:all .2s}.xiping-thumbnail-item--active{border-color:#fff}.xiping-thumbnail-image{width:100%;height:100%;object-fit:contain}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.xiping-wrapper{width:100vw;height:100vh;position:relative;display:flex;flex-direction:column;padding-top:env(safe-area-inset-top,0)}.xiping-tool-wrapper{position:absolute;top:16px;right:16px;display:flex;gap:16px;z-index:10}.xiping-close-icon,.xiping-download-icon{color:#fff;cursor:pointer}.xiping-main-content{flex:1;min-height:0;position:relative;display:flex;align-items:center;justify-content:center}.xiping-pinch-content{width:100%;height:100%}.xiping-image{width:100vw;height:100
|
|
1
|
+
.xiping-wrapper{width:100vw;height:100vh;position:relative;display:flex;flex-direction:column;padding-top:env(safe-area-inset-top,0)}.xiping-tool-wrapper{position:absolute;top:16px;right:16px;display:flex;gap:16px;z-index:10}.xiping-close-icon,.xiping-download-icon{color:#fff;cursor:pointer}.xiping-main-content{flex:1;min-height:0;position:relative;display:flex;align-items:center;justify-content:center}.xiping-pinch-content{width:100%;height:100%}.xiping-image{width:100vw;height:100%;object-fit:contain;pointer-events:none}.xiping-loading{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background-color:#00000080}.xiping-modal-content{overflow:hidden}.xiping-modal-overlay{background-color:#000000b3}.scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-hide::-webkit-scrollbar{display:none}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('./Message.css');const e=require("react/jsx-runtime"),f=require("react"),r=require("react-markdown"),l=require("clsx");;/* empty css */const I=({id:b,content:o,sender:i,timestamp:d,isThinking:c=!1,isLoading:y=!1,className:L="",style:M={},showTimestamp:g=!0,avatarUser:x,avatarAssistant:h,thinkingText:S="思考中...",customThinkingComponent:m,customUserMessageComponent:p,customAssistantMessageComponent:_,parseContent:V=!1,parsedContent:u,thinkContent:t,knowledgeSources:a})=>{const[n,j]=f.useState(!0),[q,k]=f.useState("idle");console.log(b,"id");const v=s=>s.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}),B=async()=>{try{await navigator.clipboard.writeText(o),k("copied"),setTimeout(()=>k("idle"),2e3)}catch(s){console.error("复制失败:",s)}},N=()=>m||e.jsxs("div",{className:"xiping-message__thinking",children:[e.jsxs("div",{className:"xiping-message__thinking-dots",children:[e.jsx("span",{}),e.jsx("span",{}),e.jsx("span",{})]}),e.jsx("span",{className:"xiping-message__thinking-text",children:S})]}),H=()=>e.jsx("div",{className:"xiping-message__loading",children:e.jsx("div",{className:"xiping-message__loading-spinner"})}),w=()=>!a||a.length===0?null:e.jsxs("div",{className:"xiping-message__knowledge-sources",children:[e.jsx("div",{className:"xiping-message__knowledge-sources-header",children:"知识来源:"}),e.jsx("ul",{className:"xiping-message__knowledge-sources-list",children:a.map((s,W)=>e.jsxs("li",{className:"xiping-message__knowledge-source-item",children:[s.url?e.jsx("a",{href:s.url,target:"_blank",rel:"noopener noreferrer",children:s.title}):e.jsx("span",{children:s.title}),s.description&&e.jsx("div",{className:"xiping-message__knowledge-source-description",children:s.description})]},W))})]}),C=()=>i==="user"?null:e.jsxs("button",{className:"xiping-message__copy-button",onClick:B,"aria-label":"Copy message",title:"Copy message",children:[e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[e.jsx("path",{d:"M13.3333 6H7.33333C6.59695 6 6 6.59695 6 7.33333V13.3333C6 14.0697 6.59695 14.6667 7.33333 14.6667H13.3333C14.0697 14.6667 14.6667 14.0697 14.6667 13.3333V7.33333C14.6667 6.59695 14.0697 6 13.3333 6Z",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("path",{d:"M3.33333 10H2.66667C2.31305 10 1.97391 9.85953 1.72386 9.60948C1.47381 9.35943 1.33334 9.02029 1.33334 8.66667V2.66667C1.33334 2.31305 1.47381 1.97391 1.72386 1.72386C1.97391 1.47381 2.31305 1.33334 2.66667 1.33334H8.66667C9.02029 1.33334 9.35943 1.47381 9.60948 1.72386C9.85953 1.97391 10 2.31305 10 2.66667V3.33334",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]}),q==="copied"&&e.jsx("span",{className:"xiping-message__copy-tooltip",children:"Copied"})]});return i==="user"&&p?p:i==="assistant"&&_?_:e.jsxs("div",{className:l("xiping-message",i==="user"?"user":"assistant",L),style:M,children:[i==="user"&&x||i==="assistant"&&h?e.jsx("div",{className:"xiping-message__avatar",children:i==="user"?x:h}):null,e.jsx("div",{className:"xiping-message__content",children:y?H():V&&i==="assistant"?e.jsxs(e.Fragment,{children:[t&&e.jsxs("div",{className:"xiping-message__think",children:[e.jsxs("div",{className:"xiping-message__think-header",children:["思考过程:",e.jsx("button",{className:"xiping-message__think-toggle",onClick:()=>j(!n),"aria-label":n?"隐藏思考过程":"显示思考过程",children:e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",xmlns:"http://www.w3.org/2000/svg",style:{transform:n?"rotate(180deg)":"rotate(0deg)",transition:"transform 0.3s ease"},children:e.jsx("path",{d:"M2 4L6 8L10 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})})]}),e.jsx("div",{className:l("xiping-message__think-content",n?"visible":"hidden"),children:e.jsx(r,{children:t})})]}),c&&N(),u&&e.jsxs("div",{className:"xiping-message__text-container",children:[e.jsx("div",{className:"xiping-message__text",children:e.jsx(r,{children:u})}),C()]}),w(),g&&e.jsx("div",{className:"xiping-message__timestamp",children:v(d)})]}):e.jsxs(e.Fragment,{children:[t&&e.jsxs("div",{className:"xiping-message__think",children:[e.jsxs("div",{className:"xiping-message__think-header",children:["思考过程:",e.jsx("button",{className:"xiping-message__think-toggle",onClick:()=>j(!n),"aria-label":n?"隐藏思考过程":"显示思考过程",children:e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",xmlns:"http://www.w3.org/2000/svg",style:{transform:n?"rotate(180deg)":"rotate(0deg)",transition:"transform 0.3s ease"},children:e.jsx("path",{d:"M2 4L6 8L10 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})})]}),e.jsx("div",{className:l("xiping-message__think-content",n?"visible":"hidden"),children:e.jsx(r,{children:t})})]}),e.jsxs("div",{className:"xiping-message__text-container",children:[e.jsx("div",{className:"xiping-message__text",children:e.jsx(r,{children:o})}),C()]}),c&&N(),w(),g&&e.jsx("div",{className:"xiping-message__timestamp",children:v(d)})]})})]})};exports.Message=I;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.xiping-scratch-to-reveal{position:relative;-webkit-user-select:none
|
|
1
|
+
.xiping-scratch-to-reveal{position:relative;-webkit-user-select:none;user-select:none}.xiping-scratch-canvas{position:absolute;left:0;top:0}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.xiping-subtitle-player__lyrics-time{font-size:.7rem;font-weight:500;color:#ffffff80;font-family:Monaco,Menlo,Ubuntu Mono,monospace;margin-bottom:.25rem;-webkit-user-select:none
|
|
1
|
+
.xiping-subtitle-player__lyrics-time{font-size:.7rem;font-weight:500;color:#ffffff80;font-family:Monaco,Menlo,Ubuntu Mono,monospace;margin-bottom:.25rem;-webkit-user-select:none;user-select:none}.xiping-subtitle-player__lyrics-item{display:flex;flex-direction:column;gap:.25rem;transition:all .2s ease}.xiping-subtitle-player__lyrics-item--active{color:#fbbf24;font-weight:600;transition:all .3s ease;position:relative}.xiping-subtitle-player__lyrics-item--active:before{content:"";position:absolute;left:-1rem;top:50%;transform:translateY(-50%);width:4px;height:92%;background:#fbbf24;border-radius:2px}.xiping-subtitle-player__lyrics-item--past{opacity:.5;color:#fff9}.xiping-subtitle-player__lyrics-label{font-size:.75rem;font-weight:600;color:#ffffffb3;text-transform:uppercase;letter-spacing:.05em;margin-bottom:.25rem}.xiping-subtitle-player__lyrics-text{font-size:1rem;font-weight:500;text-shadow:0 2px 4px rgba(0,0,0,.5)}.xiping-subtitle-player__lyrics-line{margin:.25rem 0}.xiping-subtitle-player__lyrics-line:first-child{margin-top:0}.xiping-subtitle-player__lyrics-line:last-child{margin-bottom:0}.xiping-subtitle-player__lyrics-hover-layer{position:absolute;inset:0;pointer-events:none}.xiping-subtitle-player--lyrics{max-height:600px;overflow-y:auto;gap:.5rem;scroll-behavior:smooth}.xiping-subtitle-player--lyrics::-webkit-scrollbar{width:8px}.xiping-subtitle-player--lyrics::-webkit-scrollbar-track{background:#ffffff1a;border-radius:4px}.xiping-subtitle-player--lyrics::-webkit-scrollbar-thumb{background:#ffffff4d;border-radius:4px}.xiping-subtitle-player--lyrics::-webkit-scrollbar-thumb:hover{background:#ffffff80}.xiping-subtitle-player__group{display:flex;flex-direction:column;gap:.5rem;width:100%;border-radius:.5rem;padding:.5rem;margin:-.5rem;transition:all .2s ease}.xiping-subtitle-player__group:hover{background-color:#ffffff1a}.xiping-subtitle-player__group:hover .xiping-subtitle-player__lyrics-item{transform:translate(4px)}.xiping-subtitle-player__group:hover .xiping-subtitle-player__lyrics-item--active{background-color:#fbbf2426}.xiping-subtitle-player__lyrics-item--active .xiping-subtitle-word{color:#fbbf24;font-weight:600}@media(max-width:768px){.xiping-subtitle-player__lyrics-text{font-size:.9rem}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('./SubtitlePlayer.css');const d=require("react/jsx-runtime"),o=require("react"),l=require("../../packages/subtitle/lib/src/parser.js"),O=require("../../packages/subtitle/lib/src/json-converter.js"),A=require("clsx"),W=require("./CurrentMode.js"),_=require("./LyricsMode.js"),b=require("./utils.js");;/* empty css */const z=({subtitles:g,currentTime:y,mode:T="current",textAlign:M="left",className:L="",style:N,onWordHoverChange:i,renderWordOverlay:f,onWordClick:m,onSubtitleClick:R})=>{const u=o.useMemo(()=>Array.isArray(g)?g:[g],[g]),p=o.useRef(null),[a,C]=o.useState(null),[S,v]=o.useState([]);o.useEffect(()=>{let r=!0;async function c(){try{const t=await Promise.all(u.map(async e=>{try{const n=e.language||"zh",s=e.type==="srt"?await O.srtToJson(e.content,n):await O.vttToJson(e.content,n);return{entries:JSON.parse(s),label:e.label}}catch(n){return console.error("字幕解析失败:",n),{entries:e.type==="srt"?l.parseSRT(e.content):l.parseVTT(e.content),label:e.label}}}));r&&v(t)}catch(t){if(console.error("加载字幕失败:",t),r){const e=u.map(n=>{try{return{entries:n.type==="srt"?l.parseSRT(n.content):l.parseVTT(n.content),label:n.label}}catch(s){return console.error("字幕解析失败:",s),{entries:[],label:n.label}}});v(e)}}}return c(),()=>{r=!1}},[u]);const h=o.useMemo(()=>S.length>0?S:u.map(r=>{try{return{entries:r.type==="srt"?l.parseSRT(r.content):l.parseVTT(r.content),label:r.label}}catch(c){return console.error("字幕解析失败:",c),{entries:[],label:r.label}}}),[S,u]),D=o.useMemo(()=>h.map(({entries:r,label:c})=>({entry:b.getCurrentSubtitleEntry(r,y),label:c,entries:r})),[h,y]),J=o.useMemo(()=>{const r=[];h.forEach(({entries:e,label:n})=>{e.forEach(s=>{r.push({entry:s,label:n,startTime:b.timeStringToSeconds(s.startTime),endTime:b.timeStringToSeconds(s.endTime)})})}),r.sort((e,n)=>e.startTime-n.startTime);const c=[];let t=[];for(const e of r)if(t.length===0)t.push(e);else{const n=t[t.length-1];e.startTime<=n.endTime?t.push(e):(c.push(t),t=[e])}return t.length>0&&c.push(t),c},[h]),w=o.useCallback((r,c)=>{const t=r.currentTarget.getBoundingClientRect(),e=p.current?.getBoundingClientRect(),n=e!==void 0?new DOMRect(t.left-e.left,t.top-e.top,t.width,t.height):t,s={...c,rect:n,element:r.currentTarget};C(s),i?.(s)},[i]),q=o.useCallback(()=>{C(null),i?.(null)},[i]),x=o.useCallback((r,c)=>{if(!m)return;r.stopPropagation();const t=r.currentTarget.getBoundingClientRect(),e=p.current?.getBoundingClientRect(),n=e!==void 0?new DOMRect(t.left-e.left,t.top-e.top,t.width,t.height):t,s={type:"word",...c,rect:n,element:r.currentTarget};m(s)},[m]),E=o.useCallback((r,c,t)=>{if(!R||r.target.closest(".xiping-subtitle-word"))return;const n=r.currentTarget.getBoundingClientRect(),s=p.current?.getBoundingClientRect(),P=s!==void 0?new DOMRect(n.left-s.left,n.top-s.top,n.width,n.height):n,V={type:"subtitle",entry:c,label:t,rect:P,element:r.currentTarget};R(V)},[R]),j=o.useCallback((r,c)=>(t,e,n)=>({onMouseEnter:s=>w(s,{word:t,wordIndex:e,lineIndex:n,entry:r,label:c}),onMouseLeave:q,onClick:s=>x(s,{word:t,wordIndex:e,lineIndex:n,entry:r,label:c})}),[w,q,x]),k=f&&a?d.jsx("div",{className:"xiping-subtitle-player__hover-overlay",style:{left:a.rect.x+a.rect.width/2,top:a.rect.y+a.rect.height},children:f(a)}):null,B=!!(f||i);return d.jsxs("div",{ref:p,className:A("xiping-subtitle-player",T==="lyrics"?"xiping-subtitle-player--lyrics":"xiping-subtitle-player--current",L),style:N,children:[T==="current"&&d.jsx(W.CurrentMode,{currentEntries:D,wordHoverFactory:j,enableWordHover:B,overlayNode:k,onSubtitleClick:E,textAlign:M}),T==="lyrics"&&d.jsx(_.LyricsMode,{groupedEntriesByTime:J,currentTime:y,wordHoverFactory:j,enableWordHover:B,overlayNode:k,containerRef:p,onSubtitleClick:E,textAlign:M})]})};exports.SubtitlePlayer=z;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),l=require("react"),r=require("clsx"),t=require("motion/react"),n=require("./index.module.css.js"),E=16,F=1.5,h="normal",S=({content:a,lineHeight:u=F,fontSize:d=E,fontWeight:x=h,className:g="",style:m={},onProgressChange:p,initialScrollPosition:q,cacheKey:v,showTopProgress:f=!0,topProgressClassName:T,showBottomProgress:N=!0,bottomProgressClassName:R})=>{const s=l.useRef(null),o=l.useRef(null),{scrollYProgress:i}=t.useScroll({container:s,target:o}),c=t.useTransform(()=>(i.get()*100).toFixed(2).replace(/\.0*$/,"")),_=t.useMotionTemplate`${c}%`;return c.on("change",j=>{p?.(Number(j))}),e.jsxs(e.Fragment,{children:[f&&e.jsx(t.motion.div,{id:"scroll-indicator",className:r(n.default["xiping-top-progress"],T),style:{scaleX:i,originX:0}}),e.jsx("div",{className:r(n.default["xiping-container"],n.default["xiping-text-content"]),ref:s,children:e.jsx("div",{ref:o,className:r(n.default["xiping-content"],g),style:{fontSize:`${d}px`,lineHeight:u,fontWeight:x,...m},children:a})}),N&&e.jsx(t.motion.div,{id:"scroll-present",className:r(n.default["xiping-bottom-progress"],R),children:_})]})};exports.TxtReader=S;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";"use strict";Object.
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('./index.css');const d=require("react/jsx-runtime"),v=require("motion/react"),n=require("react"),b=require("clsx");;/* empty css */function x({children:r,className:l,duration:o=100,delay:s=0,as:f="div",startOnView:c=!1,...m}){const g=v.motion.create(f,{forwardMotionProps:!0}),[p,T]=n.useState(""),[u,a]=n.useState(!1),i=n.useRef(null);return n.useEffect(()=>{if(!c){const t=setTimeout(()=>{a(!0)},s);return()=>clearTimeout(t)}const e=new IntersectionObserver(([t])=>{t.isIntersecting&&(setTimeout(()=>{a(!0)},s),e.disconnect())},{threshold:.1});return i.current&&e.observe(i.current),()=>e.disconnect()},[s,c]),n.useEffect(()=>{if(!u)return;let e=0;const t=setInterval(()=>{e<r.length?(T(r.substring(0,e+1)),e++):clearInterval(t)},o);return()=>{clearInterval(t)}},[r,o,u]),d.jsx(g,{ref:i,className:b("xiping-typing-animation",l),...m,children:p})}exports.TypingAnimation=x;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.xiping-variable-proximity{font-family:Roboto Flex,Noto Sans SC,PingFang SC,Microsoft YaHei,SimHei,sans-serif}.
|
|
1
|
+
.xiping-variable-proximity{font-family:Roboto Flex,Noto Sans SC,PingFang SC,Microsoft YaHei,SimHei,sans-serif}.xiping-variable-proximity__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('./index.css');const w=require("react/jsx-runtime"),f=require("react"),D=require("motion/react"),O=require("clsx");;/* empty css */const c={robotoFlex:!1,notoSansSC:!1,loading:!1};function q(n){if(typeof document>"u")return!1;try{return document.fonts.check(`1em "${n}"`)}catch{return!0}}function U(){if(c.loading||c.robotoFlex&&c.notoSansSC)return;c.loading=!0;const n=q("Roboto Flex"),r=q("Noto Sans SC");if(n&&(c.robotoFlex=!0),r&&(c.notoSansSC=!0),n&&r){c.loading=!1;return}const i=(t,s)=>{if(document.querySelector(`link[href="${t}"]`)){s?.();return}const l=document.createElement("link");l.rel="stylesheet",l.href=t,l.onload=()=>s?.(),document.head.appendChild(l)},d=[{roboto:"https://fonts.loli.net/css2?family=Roboto+Flex:opsz,wght@8..144,100..1000&display=swap",noto:"https://fonts.loli.net/css2?family=Noto+Sans+SC:wght@100..900&display=swap"},{roboto:"https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,wght@8..144,100..1000&display=swap",noto:"https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@100..900&display=swap"}],m=t=>{if(t>=d.length){c.loading=!1;return}const s=d[t];let p=0;const l=()=>{p++,p===2&&(c.loading=!1)};n?l():i(s.roboto,()=>{c.robotoFlex=!0,l()}),r?l():i(s.noto,()=>{c.notoSansSC=!0,l()}),setTimeout(()=>{(!c.robotoFlex||!c.notoSansSC)&&m(t+1)},3e3)};m(0)}function G(n=!0){f.useEffect(()=>{n&&typeof document<"u"&&U()},[n])}function H(n){f.useEffect(()=>{let r;const i=()=>{n(),r=requestAnimationFrame(i)};return r=requestAnimationFrame(i),()=>cancelAnimationFrame(r)},[n])}function J(n){const r=f.useRef({x:0,y:0});return f.useEffect(()=>{const i=(t,s)=>{if(n?.current){const p=n.current.getBoundingClientRect();r.current={x:t-p.left,y:s-p.top}}else r.current={x:t,y:s}},d=t=>i(t.clientX,t.clientY),m=t=>{const s=t.touches[0];i(s.clientX,s.clientY)};return window.addEventListener("mousemove",d),window.addEventListener("touchmove",m),()=>{window.removeEventListener("mousemove",d),window.removeEventListener("touchmove",m)}},[n]),r}const E=f.forwardRef((n,r)=>{const{label:i,fromFontVariationSettings:d,toFontVariationSettings:m,containerRef:t,radius:s=50,falloff:p="linear",className:l="",onClick:P,style:b,fontFamily:y,autoLoadFonts:V=!0,...k}=n;G(V&&!y);const C=f.useRef([]),R=f.useRef([]),S=J(t),x=f.useRef({x:null,y:null}),N=f.useMemo(()=>{const e=o=>new Map(o.split(",").map(g=>g.trim()).map(g=>{const[h,F]=g.split(" ");return[h.replace(/['"]/g,""),parseFloat(F)]})),a=e(d),u=e(m);return Array.from(a.entries()).map(([o,g])=>({axis:o,fromValue:g,toValue:u.get(o)??g}))},[d,m]),j=(e,a,u,o)=>Math.sqrt((u-e)**2+(o-a)**2),A=e=>{const a=Math.min(Math.max(1-e/s,0),1);switch(p){case"exponential":return a**2;case"gaussian":return Math.exp(-((e/(s/2))**2)/2);default:return a}};H(()=>{if(!t?.current)return;const{x:e,y:a}=S.current;if(x.current.x===e&&x.current.y===a)return;x.current={x:e,y:a};const u=t.current.getBoundingClientRect();C.current.forEach((o,g)=>{if(!o)return;const h=o.getBoundingClientRect(),F=h.left+h.width/2-u.left,T=h.top+h.height/2-u.top,v=j(S.current.x,S.current.y,F,T);if(v>=s){o.style.fontVariationSettings=d;return}const X=A(v),L=N.map(({axis:Y,fromValue:M,toValue:z})=>{const _=M+(z-M)*X;return`'${Y}' ${_}`}).join(", ");R.current[g]=L,o.style.fontVariationSettings=L})});const I=/[\u4e00-\u9fa5]/.test(i)?i.split(""):i.split(" ").flatMap((e,a,u)=>{const o=e.split("");return a<u.length-1?[...o," "]:o});let $=0;const B=f.useMemo(()=>{const e={display:"inline",...b};return y&&(e.fontFamily=y),e},[y,b]);return w.jsxs("span",{ref:r,className:O("xiping-variable-proximity",l),onClick:P,style:B,...k,children:[I.map((e,a)=>{const u=$++;return w.jsx(D.motion.span,{ref:o=>{C.current[u]=o},style:{display:e===" "?"inline":"inline-block",fontVariationSettings:R.current[u]},"aria-hidden":"true",children:e},a)}),w.jsx("span",{className:"xiping-variable-proximity__sr-only",children:i})]})});E.displayName="VariableProximity";exports.VariableProximity=E;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.xiping-video-subtitle-player{width:100%;height:100%;background:#1a1a1a;border-radius:8px;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.xiping-video-subtitle-player__video-wrapper{width:100%;height:100%;background:#000;overflow:hidden}.xiping-video-subtitle-player__video-container{position:relative;width:100%;height:100%;background:#000;overflow:hidden}.xiping-video-subtitle-player__video{position:absolute;top:0;left:0;width:100%;height:100%;padding:0}.xiping-video-subtitle-player__video-container .xgplayer{width:100%!important;height:100%!important}.xiping-video-subtitle-player__video-container .xgplayer video{
|
|
1
|
+
.xiping-video-subtitle-player{width:100%;height:100%;background:#1a1a1a;border-radius:8px;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.xiping-video-subtitle-player__video-wrapper{width:100%;height:100%;background:#000;overflow:hidden}.xiping-video-subtitle-player__video-container{position:relative;width:100%;height:100%;background:#000;overflow:hidden}.xiping-video-subtitle-player__video{position:absolute;top:0;left:0;width:100%;height:100%;padding:0}.xiping-video-subtitle-player__video-container .xgplayer{width:100%!important;height:100%!important}.xiping-video-subtitle-player__video-container .xgplayer video{object-fit:fill!important}.xiping-video-subtitle-player__subtitle-container{width:100%;height:100%;padding:20px;overflow-y:auto;background:#0000004d}.xiping-video-subtitle-player__right{width:100%;height:100%;background:#00000080;display:flex;flex-direction:column}.xiping-video-subtitle-player__detail{flex:1;padding:24px;overflow-y:auto;color:#fff}.xiping-video-subtitle-player__detail-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:16px;color:#ffffffb3}.xiping-video-subtitle-player__detail-loading-spinner{width:40px;height:40px;border:3px solid rgba(255,255,255,.1);border-top-color:#fbbf24;border-radius:50%;animation:xiping-vsp-spin 1s linear infinite}@keyframes xiping-vsp-spin{to{transform:rotate(360deg)}}.xiping-video-subtitle-player__detail-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:16px;color:#ffffff80;text-align:center}.xiping-video-subtitle-player__detail-empty-icon{font-size:48px;opacity:.5}.xiping-video-subtitle-player__detail-empty-text{font-size:14px;line-height:1.6}.xiping-video-subtitle-player__detail-content{display:flex;flex-direction:column;gap:20px}.xiping-video-subtitle-player__detail-word{font-size:32px;font-weight:700;color:#fbbf24;line-height:1.2;margin-bottom:8px}.xiping-video-subtitle-player__detail-pronunciation{font-size:18px;color:#ffffffb3;font-style:italic;margin-bottom:4px}.xiping-video-subtitle-player__detail-pos{display:inline-block;padding:4px 12px;background:#fbbf2433;color:#fbbf24;border-radius:4px;font-size:12px;font-weight:600;text-transform:uppercase;width:fit-content;margin-bottom:8px}.xiping-video-subtitle-player__detail-label{font-size:12px;font-weight:600;color:#ffffff80;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px}.xiping-video-subtitle-player__detail-text{font-size:16px;line-height:1.6;color:#ffffffe6}.xiping-video-subtitle-player__detail-translation,.xiping-video-subtitle-player__detail-definition{padding-bottom:16px;border-bottom:1px solid rgba(255,255,255,.1)}.xiping-video-subtitle-player__detail-definition{border-bottom:none}.xiping-video-subtitle-player__detail-examples{display:flex;flex-direction:column;gap:16px}.xiping-video-subtitle-player__detail-example{padding:16px;background:#ffffff0d;border-radius:8px;border-left:3px solid #fbbf24}.xiping-video-subtitle-player__detail-example-en{font-size:15px;line-height:1.6;color:#fffffff2;margin-bottom:8px}.xiping-video-subtitle-player__detail-example-zh{font-size:14px;line-height:1.6;color:#ffffffb3;padding-left:12px;border-left:2px solid rgba(255,255,255,.2)}.xiping-video-subtitle-player__subtitle-container::-webkit-scrollbar,.xiping-video-subtitle-player__detail::-webkit-scrollbar{width:8px}.xiping-video-subtitle-player__subtitle-container::-webkit-scrollbar-track,.xiping-video-subtitle-player__detail::-webkit-scrollbar-track{background:#ffffff0d;border-radius:4px}.xiping-video-subtitle-player__subtitle-container::-webkit-scrollbar-thumb,.xiping-video-subtitle-player__detail::-webkit-scrollbar-thumb{background:#fff3;border-radius:4px}.xiping-video-subtitle-player__subtitle-container::-webkit-scrollbar-thumb:hover,.xiping-video-subtitle-player__detail::-webkit-scrollbar-thumb:hover{background:#ffffff4d}
|
|
@@ -13,11 +13,11 @@ export interface VideoSubtitlePlayerProps {
|
|
|
13
13
|
style?: React.CSSProperties;
|
|
14
14
|
/** 自定义详情获取函数,用于调用大模型API */
|
|
15
15
|
onFetchDetail?: (target: HoverTarget | null) => Promise<void>;
|
|
16
|
+
/** 强制使用布局:传入则不再做设备检测,直接使用对应布局 */
|
|
17
|
+
forceLayout?: "mobile" | "pc";
|
|
16
18
|
}
|
|
17
19
|
/**
|
|
18
|
-
*
|
|
19
|
-
* 左侧:上部分视频播放器(填充模式),下部分字幕显示
|
|
20
|
-
* 右侧:字幕详情(单词/短语的发音、解释等)
|
|
20
|
+
* 视频字幕播放器:根据设备或 forceLayout 选择 PC 或移动端视图,二者完全分离
|
|
21
21
|
*/
|
|
22
22
|
export declare const VideoSubtitlePlayer: React.FC<VideoSubtitlePlayerProps>;
|
|
23
23
|
export default VideoSubtitlePlayer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('./VideoSubtitlePlayer.css');const b=require("react/jsx-runtime"),o=require("react"),y=require("react-device-detect"),M=require("./useVideoSubtitleStore.js"),W=require("./useXGPlayer.js"),j=require("./VideoSubtitlePlayerPC.js"),k=require("./VideoSubtitlePlayerMobile.js");;/* empty css */const m=({videoUrl:S,subtitles:r,poster:P,className:s="",style:a,onFetchDetail:e,forceLayout:n})=>{const l=o.useRef(null),C=n!==void 0?n==="mobile":y.isMobile||y.isTablet,{currentTime:u,setCurrentTime:f,setIsPlaying:q,setSubtitles:c,currentDetail:V,isLoadingDetail:v,fetchDetail:t}=M.useVideoSubtitleStore();o.useEffect(()=>{c(r)},[r,c]),W.useXGPlayer(l,S,P,{setCurrentTime:f,setIsPlaying:q},u);const d=o.useCallback(async i=>{e?await e(i):await t(i)},[e,t]),g=o.useCallback(async i=>{e?await e(i):await t(i)},[e,t]);return C?b.jsx(k.VideoSubtitlePlayerMobile,{playerRef:l,subtitles:r,currentTime:u,onWordHoverChange:d,onWordClick:g,className:s,style:a}):b.jsx(j.VideoSubtitlePlayerPC,{playerRef:l,subtitles:r,currentTime:u,currentDetail:V,isLoadingDetail:v,onWordHoverChange:d,className:s,style:a})};exports.VideoSubtitlePlayer=m;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.xiping-video-subtitle-player--mobile{display:flex;flex-direction:column;min-height:0;height:100%}.xiping-video-subtitle-player__mobile-video{flex:0 0 auto;width:100%;aspect-ratio:16 / 9;background:#000}.xiping-video-subtitle-player__mobile-video-wrapper{width:100%;height:100%;background:#000;overflow:hidden}.xiping-video-subtitle-player__mobile-video-container{position:relative;width:100%;height:100%;background-color:#a62c2c;overflow:hidden}.xiping-video-subtitle-player__mobile-video-container .xgplayer{width:100%!important;height:100%!important}.xiping-video-subtitle-player__mobile-video-container .xgplayer video{object-fit:fill!important}.xiping-video-subtitle-player__mobile-subtitle{flex:1;min-height:0;padding:12px 16px;overflow-y:auto;background:#0000004d;-webkit-overflow-scrolling:touch}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.xiping-video-subtitle-player--pc .xiping-video-subtitle-player__panel-group,.xiping-video-subtitle-player--pc .xiping-video-subtitle-player__panel-group-inner{width:100%;height:100%}.xiping-video-subtitle-player--pc .xiping-video-subtitle-player__right{border-left:1px solid rgba(255,255,255,.1)}.xiping-video-subtitle-player__resize-handle--horizontal{position:relative;width:2px;background:#ffffff1a;cursor:col-resize;transition:background .2s ease;flex-shrink:0}.xiping-video-subtitle-player__resize-handle--horizontal:hover{background:#fbbf2480}.xiping-video-subtitle-player__resize-handle--horizontal:active{background:#fbbf24cc}.xiping-video-subtitle-player__resize-handle--horizontal:before{content:"";position:absolute;inset:0 -4px;cursor:col-resize}.xiping-video-subtitle-player__resize-handle--vertical{position:relative;height:2px;background:#ffffff1a;cursor:row-resize;transition:background .2s ease;flex-shrink:0}.xiping-video-subtitle-player__resize-handle--vertical:hover{background:#fbbf2480}.xiping-video-subtitle-player__resize-handle--vertical:active{background:#fbbf24cc}.xiping-video-subtitle-player__resize-handle--vertical:before{content:"";position:absolute;inset:-4px 0;cursor:row-resize}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { default as React, RefObject } from 'react';
|
|
2
|
+
import { SubtitleData, HoverTarget, WordClickTarget } from '../subtitle-player/SubtitlePlayer';
|
|
3
|
+
export interface VideoSubtitlePlayerMobileProps {
|
|
4
|
+
/** 播放器挂载的容器 ref */
|
|
5
|
+
playerRef: RefObject<HTMLDivElement | null>;
|
|
6
|
+
/** 字幕数据 */
|
|
7
|
+
subtitles: SubtitleData[];
|
|
8
|
+
/** 当前播放时间(秒) */
|
|
9
|
+
currentTime: number;
|
|
10
|
+
/** 单词 hover 变化时拉取/展示详情(可为弹窗等) */
|
|
11
|
+
onWordHoverChange: (target: HoverTarget | null) => void | Promise<void>;
|
|
12
|
+
/** 单词点击时拉取/展示详情(移动端主要交互) */
|
|
13
|
+
onWordClick: (target: WordClickTarget) => void | Promise<void>;
|
|
14
|
+
className?: string;
|
|
15
|
+
style?: React.CSSProperties;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 移动端视图:上下两栏(视频 + 字幕),无右侧详情区,详情后续以弹窗等形式实现
|
|
19
|
+
*/
|
|
20
|
+
export declare const VideoSubtitlePlayerMobile: React.FC<VideoSubtitlePlayerMobileProps>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),o=require("react"),S=require("clsx"),P=require("../subtitle-player/SubtitlePlayer.js"),v=require("./layouts/VideoSubtitlePlayerLayoutMobile.js"),x=({playerRef:a,subtitles:r,currentTime:s,onWordHoverChange:i,onWordClick:l,className:c="",style:u})=>{const n=o.useCallback(async e=>{await i(e)},[i]),b=o.useCallback(async e=>{await l(e)},[l]),d=t.jsx("div",{ref:a,className:"xiping-video-subtitle-player__video"}),y=t.jsx(P.SubtitlePlayer,{subtitles:r,currentTime:s,mode:"lyrics",onWordHoverChange:n,onWordClick:b});return t.jsx(v.VideoSubtitlePlayerLayoutMobile,{className:S(c),style:u,videoSlot:d,subtitleSlot:y})};exports.VideoSubtitlePlayerMobile=x;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { default as React, RefObject } from 'react';
|
|
2
|
+
import { SubtitleData, HoverTarget } from '../subtitle-player/SubtitlePlayer';
|
|
3
|
+
import { SubtitleDetail } from './useVideoSubtitleStore';
|
|
4
|
+
export interface VideoSubtitlePlayerPCProps {
|
|
5
|
+
/** 播放器挂载的容器 ref */
|
|
6
|
+
playerRef: RefObject<HTMLDivElement | null>;
|
|
7
|
+
/** 字幕数据 */
|
|
8
|
+
subtitles: SubtitleData[];
|
|
9
|
+
/** 当前播放时间(秒) */
|
|
10
|
+
currentTime: number;
|
|
11
|
+
/** 当前悬停单词的详情 */
|
|
12
|
+
currentDetail: SubtitleDetail | null;
|
|
13
|
+
/** 是否正在加载详情 */
|
|
14
|
+
isLoadingDetail: boolean;
|
|
15
|
+
/** 单词 hover 变化时拉取/展示详情 */
|
|
16
|
+
onWordHoverChange: (target: HoverTarget | null) => void | Promise<void>;
|
|
17
|
+
className?: string;
|
|
18
|
+
style?: React.CSSProperties;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* PC 端视图:可拖拽分栏 + 右侧详情区,所有 PC 专属 UI 集中在此
|
|
22
|
+
*/
|
|
23
|
+
export declare const VideoSubtitlePlayerPC: React.FC<VideoSubtitlePlayerPCProps>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),y=require("react"),m=require("clsx"),b=require("../subtitle-player/SubtitlePlayer.js"),u=require("./layouts/VideoSubtitlePlayerLayoutPC.js"),g=({playerRef:a,subtitles:t,currentTime:d,currentDetail:i,isLoadingDetail:n,onWordHoverChange:s,className:o="",style:p})=>{const x=y.useCallback(async l=>{await s(l)},[s]),c=e.jsx("div",{ref:a,className:"xiping-video-subtitle-player__video"}),r=e.jsx(b.SubtitlePlayer,{subtitles:t,currentTime:d,mode:"lyrics",onWordHoverChange:x}),v=e.jsx("div",{className:"xiping-video-subtitle-player__detail",children:n?e.jsxs("div",{className:"xiping-video-subtitle-player__detail-loading",children:[e.jsx("div",{className:"xiping-video-subtitle-player__detail-loading-spinner"}),e.jsx("span",{children:"加载中..."})]}):i?e.jsxs("div",{className:"xiping-video-subtitle-player__detail-content",children:[e.jsx("div",{className:"xiping-video-subtitle-player__detail-word",children:i.word}),i.pronunciation&&e.jsx("div",{className:"xiping-video-subtitle-player__detail-pronunciation",children:i.pronunciation}),i.partOfSpeech&&e.jsx("div",{className:"xiping-video-subtitle-player__detail-pos",children:i.partOfSpeech}),i.translation&&e.jsxs("div",{className:"xiping-video-subtitle-player__detail-translation",children:[e.jsx("div",{className:"xiping-video-subtitle-player__detail-label",children:"中文翻译"}),e.jsx("div",{className:"xiping-video-subtitle-player__detail-text",children:i.translation})]}),i.definition&&e.jsxs("div",{className:"xiping-video-subtitle-player__detail-definition",children:[e.jsx("div",{className:"xiping-video-subtitle-player__detail-label",children:"英文解释"}),e.jsx("div",{className:"xiping-video-subtitle-player__detail-text",children:i.definition})]}),i.examples&&i.examples.length>0&&e.jsxs("div",{className:"xiping-video-subtitle-player__detail-examples",children:[e.jsx("div",{className:"xiping-video-subtitle-player__detail-label",children:"例句"}),i.examples.map((l,_)=>e.jsxs("div",{className:"xiping-video-subtitle-player__detail-example",children:[e.jsx("div",{className:"xiping-video-subtitle-player__detail-example-en",children:l.sentence}),e.jsx("div",{className:"xiping-video-subtitle-player__detail-example-zh",children:l.translation})]},_))]})]}):e.jsxs("div",{className:"xiping-video-subtitle-player__detail-empty",children:[e.jsx("div",{className:"xiping-video-subtitle-player__detail-empty-icon",children:"📖"}),e.jsx("div",{className:"xiping-video-subtitle-player__detail-empty-text",children:"将鼠标悬停在字幕单词上查看详情"})]})});return e.jsx(u.VideoSubtitlePlayerLayoutPC,{className:m(o),style:p,videoSlot:c,subtitleSlot:r,detailSlot:v})};exports.VideoSubtitlePlayerPC=g;
|
package/dist/cjs/components/video-subtitle-player/layouts/VideoSubtitlePlayerLayoutMobile.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { VideoSubtitlePlayerLayoutMobileProps } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* 移动端布局:上下两栏,无拖拽
|
|
5
|
+
* - 上:视频区域(100vw 宽,16:9 占位)
|
|
6
|
+
* - 下:仅字幕区域(单词详情后续以弹窗等形式实现,此处不展示)
|
|
7
|
+
*/
|
|
8
|
+
export declare const VideoSubtitlePlayerLayoutMobile: React.FC<VideoSubtitlePlayerLayoutMobileProps>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('../VideoSubtitlePlayer.mobile.css');const e=require("react/jsx-runtime"),o=require("clsx");;/* empty css */const r=({className:i="",style:l,videoSlot:t,subtitleSlot:s})=>e.jsxs("div",{className:o("xiping-video-subtitle-player","xiping-video-subtitle-player--mobile",i),style:l,children:[e.jsx("div",{className:"xiping-video-subtitle-player__mobile-video",children:e.jsx("div",{className:"xiping-video-subtitle-player__mobile-video-wrapper",children:e.jsx("div",{className:"xiping-video-subtitle-player__mobile-video-container",children:t})})}),e.jsx("div",{className:"xiping-video-subtitle-player__mobile-subtitle",children:s})]});exports.VideoSubtitlePlayerLayoutMobile=r;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('../VideoSubtitlePlayer.pc.css');const e=require("react/jsx-runtime"),i=require("react-resizable-panels"),l=require("clsx");;/* empty css */const d=({className:a="",style:r,videoSlot:t,subtitleSlot:s,detailSlot:n})=>e.jsx("div",{className:l("xiping-video-subtitle-player","xiping-video-subtitle-player--pc",a),style:r,children:e.jsxs(i.Group,{orientation:"horizontal",className:"xiping-video-subtitle-player__panel-group",children:[e.jsx(i.Panel,{defaultSize:"65",minSize:"40",children:e.jsxs(i.Group,{orientation:"vertical",className:"xiping-video-subtitle-player__panel-group-inner",children:[e.jsx(i.Panel,{defaultSize:"60",minSize:"30",children:e.jsx("div",{className:"xiping-video-subtitle-player__video-wrapper",children:e.jsx("div",{className:"xiping-video-subtitle-player__video-container",children:t})})}),e.jsx(i.Separator,{className:l("xiping-video-subtitle-player__resize-handle","xiping-video-subtitle-player__resize-handle--vertical")}),e.jsx(i.Panel,{defaultSize:"40",minSize:"20",children:e.jsx("div",{className:"xiping-video-subtitle-player__subtitle-container",children:s})})]})}),e.jsx(i.Separator,{className:l("xiping-video-subtitle-player__resize-handle","xiping-video-subtitle-player__resize-handle--horizontal")}),e.jsx(i.Panel,{defaultSize:"35",minSize:"25",maxSize:"50",children:e.jsx("div",{className:"xiping-video-subtitle-player__right",children:n})})]})});exports.VideoSubtitlePlayerLayoutPC=d;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
/** 移动端布局 props:仅视频 + 字幕,无详情区(详情后续弹窗等单独实现) */
|
|
3
|
+
export interface VideoSubtitlePlayerLayoutMobileProps {
|
|
4
|
+
className?: string;
|
|
5
|
+
style?: React.CSSProperties;
|
|
6
|
+
videoSlot: ReactNode;
|
|
7
|
+
subtitleSlot: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
/** PC 端布局 props:视频 + 字幕 + 右侧详情区 */
|
|
10
|
+
export interface VideoSubtitlePlayerLayoutPCProps {
|
|
11
|
+
className?: string;
|
|
12
|
+
style?: React.CSSProperties;
|
|
13
|
+
videoSlot: ReactNode;
|
|
14
|
+
subtitleSlot: ReactNode;
|
|
15
|
+
/** 右侧详情区域 */
|
|
16
|
+
detailSlot: ReactNode;
|
|
17
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
export interface UseXGPlayerCallbacks {
|
|
3
|
+
setCurrentTime: (time: number) => void;
|
|
4
|
+
setIsPlaying: (playing: boolean) => void;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* 封装 xgplayer 的创建、事件绑定与销毁,以及外部 currentTime 同步
|
|
8
|
+
* 调用方需渲染一个 div 并传入其 ref,播放器会挂载到该节点
|
|
9
|
+
*/
|
|
10
|
+
export declare function useXGPlayer(containerRef: RefObject<HTMLDivElement | null>, videoUrl: string, poster: string | undefined, callbacks: UseXGPlayerCallbacks, currentTime: number): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('../../node_modules/.pnpm/xgplayer@3.0.23_core-js@3.47.0/node_modules/xgplayer/dist/index.min.css');const a=require("react"),P=require("xgplayer");;/* empty css */function m(s,l,o,p,r){const u=a.useRef(null),{setCurrentTime:c,setIsPlaying:n}=p;a.useEffect(()=>{if(!s.current)return;const t=`xiping-video-subtitle-player-${Date.now()}`;s.current.id=t;const e=new P({id:t,url:l,poster:o,autoplay:!1,fluid:!1,width:"100%",height:"100%",controls:!0});u.current=e;const f=()=>{const h=e.currentTime??0;c(h)},i=()=>n(!0),d=()=>n(!1),y=()=>n(!1);return e.on("timeupdate",f),e.on("play",i),e.on("pause",d),e.on("ended",y),()=>{e.off("timeupdate",f),e.off("play",i),e.off("pause",d),e.off("ended",y),e.destroy(),u.current=null}},[l,o,c,n]),a.useEffect(()=>{const t=u.current;if(!t)return;Math.abs(t.currentTime-r)>.5&&(t.currentTime=r)},[r])}exports.useXGPlayer=m;
|
package/dist/cjs/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./components/button/Button.js"),i=require("./components/txt-reader/TxtReader.js"),o=require("./components/hyper-text/index.js"),n=require("./components/typing-animation/index.js"),e=require("./components/confetti-button/index.js"),u=require("./components/gradient-text/index.js"),a=require("./components/variable-proximity/index.js"),c=require("./hooks/useStayTimeReport.js"),s=require("./components/
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./components/button/Button.js"),i=require("./components/txt-reader/TxtReader.js"),o=require("./components/hyper-text/index.js"),n=require("./components/typing-animation/index.js"),e=require("./components/confetti-button/index.js"),u=require("./components/gradient-text/index.js"),a=require("./components/variable-proximity/index.js"),c=require("./hooks/useStayTimeReport.js"),s=require("./components/blur-text/BlurText.js"),l=require("./components/image-compare/ImageCompare.js"),T=require("./components/image-viewer/ImageViewer.js"),x=require("./components/pinch-content/PinchContent.js"),S=require("./components/shimmer-button/ShimmerButton.js"),d=require("./components/shiny-text/ShinyText.js"),q=require("./components/text-type/TextType.js"),m=require("./components/blur-fade/BlurFade.js"),y=require("./components/comic-text/ComicText.js"),t=require("./components/dock/Duck.js"),p=require("./components/flip-text/FlipText.js"),B=require("react-force-graph-3d"),h=require("./components/message/Message.js"),g=require("./components/pointer/Pointer.js"),P=require("./components/scratch-to-reveal/ScratchToReveal.js"),b=require("./components/shiny-button/ShinyButton.js"),f=require("./components/sparkles-text/SparklesText.js"),V=require("./components/split-text/SplitText.js"),C=require("./components/subtitle-player/SubtitlePlayer.js"),D=require("./components/text-animate/TextAnimate.js"),R=require("./components/txt-editor/TxtEditor.js"),k=require("./components/video-dialog/VideoDialog.js"),F=require("./components/video-subtitle-player/VideoSubtitlePlayer.js"),I=require("canvas-confetti"),A=require("./components/video-subtitle-player/useVideoSubtitleStore.js");exports.Button=r.Button;exports.TxtReader=i.TxtReader;exports.HyperText=o.HyperText;exports.TypingAnimation=n.TypingAnimation;exports.Confetti=e.Confetti;exports.ConfettiButton=e.ConfettiButton;exports.GradientText=u.GradientText;exports.VariableProximity=a.VariableProximity;exports.useStayTimeReport=c.useStayTimeReport;exports.BlurText=s.default;exports.ImageCompare=l.default;exports.ImageViewer=T.default;exports.PinchContent=x.default;exports.ShimmerButton=S.ShimmerButton;exports.ShinyText=d.default;exports.TextType=q.default;exports.BlurFade=m.BlurFade;exports.ComicText=y.ComicText;exports.Dock=t.Dock;exports.DockIcon=t.DockIcon;exports.FlipText=p.FlipText;exports.ForceGraph3D=B;exports.Message=h.Message;exports.Pointer=g.Pointer;exports.ScratchToReveal=P.ScratchToReveal;exports.ShinyButton=b.ShinyButton;exports.SparklesText=f.SparklesText;exports.SplitText=V.SplitText;exports.SubtitlePlayer=C.SubtitlePlayer;exports.TextAnimate=D.TextAnimate;exports.TxtEditor=R.TxtEditor;exports.VideoDialog=k.VideoDialog;exports.VideoSubtitlePlayer=F.VideoSubtitlePlayer;exports.confetti=I;exports.useVideoSubtitleStore=A.useVideoSubtitleStore;
|