|
1 | 1 | import React from "react"
|
2 |
| -import s from "./index.module.css" |
3 |
| -import { MiniEditor } from "@code-hike/mini-editor" |
4 |
| -import { MiniBrowser } from "@code-hike/mini-browser" |
5 |
| -import { Range, getTrackBackground } from "react-range" |
6 |
| -import { Video, useTimeData } from "@code-hike/player" |
7 |
| -import { useSpring } from "use-spring" |
8 |
| -import { sim } from "@code-hike/sim-user" |
9 | 2 | import { MDXProvider } from "@mdx-js/react"
|
10 | 3 | import Content from "../demo/cake.mdx"
|
| 4 | +import { CakeLayout } from "../src/cake-layout" |
11 | 5 | import Head from "next/head"
|
12 | 6 |
|
| 7 | +export default function Page() { |
| 8 | + return ( |
| 9 | + <MDXProvider components={components}> |
| 10 | + <Head> |
| 11 | + <title>The X in MDX</title> |
| 12 | + </Head> |
| 13 | + <Content /> |
| 14 | + </MDXProvider> |
| 15 | + ) |
| 16 | +} |
| 17 | + |
| 18 | +function Wrapper({ children }) { |
| 19 | + const { |
| 20 | + videoSteps, |
| 21 | + browserSteps, |
| 22 | + editorSteps, |
| 23 | + captionSteps, |
| 24 | + } = getStepsFromMDX(children) |
| 25 | + return ( |
| 26 | + <CakeLayout |
| 27 | + videoSteps={videoSteps} |
| 28 | + browserSteps={browserSteps} |
| 29 | + editorSteps={editorSteps} |
| 30 | + captionSteps={captionSteps} |
| 31 | + /> |
| 32 | + ) |
| 33 | +} |
13 | 34 | const components = {
|
14 | 35 | wrapper: Wrapper,
|
15 | 36 | }
|
@@ -73,309 +94,20 @@ function getStepsFromMDX(children) {
|
73 | 94 | return parseSrt(pre.props.children.props.children)
|
74 | 95 | })
|
75 | 96 |
|
76 |
| - console.log(splits[0]) |
77 |
| - console.log(captionSteps) |
78 |
| - |
79 | 97 | return {
|
80 | 98 | videoSteps,
|
81 | 99 | browserSteps,
|
82 | 100 | editorSteps,
|
| 101 | + captionSteps, |
83 | 102 | }
|
84 | 103 | }
|
85 | 104 |
|
86 | 105 | function parseSrt(srt) {
|
87 | 106 | const regex = /^[\d\.\:]+\s+[–\-]>\s+[\d\.\:]+$/gm
|
88 | 107 | const times = srt.match(regex)
|
89 | 108 | const [, ...texts] = srt.split(regex)
|
90 |
| - return times.map((time, i) => ({ time, text: texts[i] })) |
91 |
| -} |
92 |
| - |
93 |
| -export default function Page() { |
94 |
| - return ( |
95 |
| - <MDXProvider components={components}> |
96 |
| - <Head> |
97 |
| - <title>The X in MDX</title> |
98 |
| - </Head> |
99 |
| - <Content /> |
100 |
| - </MDXProvider> |
101 |
| - ) |
102 |
| -} |
103 |
| - |
104 |
| -function Wrapper({ children }) { |
105 |
| - const { |
106 |
| - videoSteps, |
107 |
| - browserSteps, |
108 |
| - editorSteps, |
109 |
| - } = getStepsFromMDX(children) |
110 |
| - return ( |
111 |
| - <Talk |
112 |
| - videoSteps={videoSteps} |
113 |
| - browserSteps={browserSteps} |
114 |
| - editorSteps={editorSteps} |
115 |
| - /> |
116 |
| - ) |
117 |
| -} |
118 |
| - |
119 |
| -function Talk({ videoSteps, browserSteps, editorSteps }) { |
120 |
| - const [stepIndex, changeStep] = React.useState(0) |
121 |
| - const playerRef = React.useRef() |
122 |
| - const browserRef = React.useRef() |
123 |
| - const [videoTime, setVideoTime] = React.useState( |
124 |
| - videoSteps[0].start |
125 |
| - ) |
126 |
| - const [isPlaying, setIsPlaying] = React.useState(false) |
127 |
| - const [progress] = useSpring(stepIndex, { |
128 |
| - decimals: 3, |
129 |
| - stiffness: 80, |
130 |
| - damping: 48, |
131 |
| - mass: 8, |
132 |
| - }) |
133 |
| - const backward = stepIndex < progress |
134 |
| - |
135 |
| - const seek = ({ stepIndex, videoTime }) => { |
136 |
| - playerRef.current.seek(stepIndex, videoTime) |
137 |
| - } |
138 |
| - const play = () => { |
139 |
| - playerRef.current.play() |
140 |
| - setIsPlaying(true) |
141 |
| - } |
142 |
| - const pause = () => { |
143 |
| - playerRef.current.pause() |
144 |
| - setIsPlaying(false) |
145 |
| - } |
146 |
| - |
147 |
| - const onTimeChange = (newTime, oldTime) => { |
148 |
| - // currentStep.actions |
149 |
| - const browserStep = browserSteps[stepIndex] |
150 |
| - const actions = browserStep.actions || [] |
151 |
| - const action = actions.find( |
152 |
| - a => oldTime < a.on && a.on <= newTime |
153 |
| - ) |
154 |
| - |
155 |
| - if (action) { |
156 |
| - const document = |
157 |
| - browserRef.current.contentWindow.document |
158 |
| - sim(action, document) |
159 |
| - } |
160 |
| - |
161 |
| - setVideoTime(newTime) |
162 |
| - } |
163 |
| - |
164 |
| - return ( |
165 |
| - <div className={s.page}> |
166 |
| - <style global jsx>{` |
167 |
| - html, |
168 |
| - body, |
169 |
| - div#__next { |
170 |
| - height: 100%; |
171 |
| - margin: 0; |
172 |
| - } |
173 |
| - .ch-frame .ch-editor-body { |
174 |
| - padding: 0; |
175 |
| - } |
176 |
| - `}</style> |
177 |
| - <main className={s.main}> |
178 |
| - <div className={s.grid}> |
179 |
| - <div className={s.div1}> |
180 |
| - <MiniEditor |
181 |
| - style={{ height: "100%" }} |
182 |
| - steps={editorSteps} |
183 |
| - progress={progress} |
184 |
| - backward={backward} |
185 |
| - /> |
186 |
| - </div> |
187 |
| - <div className={s.div2}> |
188 |
| - <MiniBrowser |
189 |
| - style={{ height: "100%" }} |
190 |
| - steps={browserSteps} |
191 |
| - progress={progress} |
192 |
| - backward={backward} |
193 |
| - ref={browserRef} |
194 |
| - /> |
195 |
| - </div> |
196 |
| - <div className={s.div4}> |
197 |
| - <pre className={s.captions}> |
198 |
| - there's a reason why it's so popular, <br /> |
199 |
| - the syntax is so clean |
200 |
| - </pre> |
201 |
| - </div> |
202 |
| - <div className={s.div3}> |
203 |
| - <div className={s.video}> |
204 |
| - <div |
205 |
| - style={{ |
206 |
| - height: "100%", |
207 |
| - float: "right", |
208 |
| - }} |
209 |
| - > |
210 |
| - <Video |
211 |
| - steps={videoSteps} |
212 |
| - containerStyle={{ |
213 |
| - height: "100%", |
214 |
| - }} |
215 |
| - style={{ |
216 |
| - height: "100%", |
217 |
| - }} |
218 |
| - onStepChange={changeStep} |
219 |
| - onTimeChange={onTimeChange} |
220 |
| - ref={playerRef} |
221 |
| - /> |
222 |
| - </div> |
223 |
| - <div |
224 |
| - className={s.details} |
225 |
| - style={{ |
226 |
| - top: 0, |
227 |
| - bottom: 0, |
228 |
| - left: 0, |
229 |
| - right: 0, |
230 |
| - }} |
231 |
| - > |
232 |
| - <div> |
233 |
| - <a |
234 |
| - style={{ |
235 |
| - fontSize: "1.2em", |
236 |
| - color: "#F19A38", |
237 |
| - }} |
238 |
| - href="https://twitter.com/pomber" |
239 |
| - > |
240 |
| - @pomber |
241 |
| - </a> |
242 |
| - <div style={{ height: 5 }} /> |
243 |
| - <span style={{ fontSize: "1.8em" }}> |
244 |
| - Rodrigo |
245 |
| - </span> |
246 |
| - <br /> |
247 |
| - <span style={{ fontSize: "2em" }}> |
248 |
| - Pombo |
249 |
| - </span> |
250 |
| - <div style={{ height: 10 }} /> |
251 |
| - <a |
252 |
| - style={{ fontSize: "1.3em", margin: 0 }} |
253 |
| - href="https://mdxjs.com/conf/" |
254 |
| - > |
255 |
| - <span |
256 |
| - children="<" |
257 |
| - style={{ |
258 |
| - color: "#F19A38", |
259 |
| - fontSize: "1.2em", |
260 |
| - }} |
261 |
| - /> |
262 |
| - MDXConf |
263 |
| - <span |
264 |
| - children=" />" |
265 |
| - style={{ color: "#F19A38" }} |
266 |
| - /> |
267 |
| - </a> |
268 |
| - </div> |
269 |
| - </div> |
270 |
| - </div> |
271 |
| - </div> |
272 |
| - </div> |
273 |
| - <VideoControls |
274 |
| - steps={videoSteps} |
275 |
| - videoTime={videoTime} |
276 |
| - stepIndex={stepIndex} |
277 |
| - onChange={seek} |
278 |
| - play={play} |
279 |
| - pause={pause} |
280 |
| - isPlaying={isPlaying} |
281 |
| - /> |
282 |
| - </main> |
283 |
| - </div> |
284 |
| - ) |
285 |
| -} |
286 |
| - |
287 |
| -function VideoControls({ |
288 |
| - steps, |
289 |
| - stepIndex, |
290 |
| - videoTime, |
291 |
| - onChange, |
292 |
| - isPlaying, |
293 |
| - play, |
294 |
| - pause, |
295 |
| -}) { |
296 |
| - const { |
297 |
| - currentSeconds, |
298 |
| - getStepAndTime, |
299 |
| - totalSeconds, |
300 |
| - } = useTimeData({ |
301 |
| - steps, |
302 |
| - stepIndex, |
303 |
| - videoTime, |
| 109 | + return times.map((time, i) => { |
| 110 | + const [start, end] = time.match(/[\d\.]+/g).map(t => +t) |
| 111 | + return { start, end, text: texts[i].trim() } |
304 | 112 | })
|
305 |
| - |
306 |
| - const value = currentSeconds |
307 |
| - |
308 |
| - const handleChange = values => { |
309 |
| - const value = values[0] |
310 |
| - const { stepIndex, videoTime } = getStepAndTime(value) |
311 |
| - onChange({ stepIndex, videoTime }) |
312 |
| - } |
313 |
| - |
314 |
| - return ( |
315 |
| - <> |
316 |
| - <Range |
317 |
| - step={0.1} |
318 |
| - min={0} |
319 |
| - max={totalSeconds} |
320 |
| - values={[value]} |
321 |
| - onChange={handleChange} |
322 |
| - renderTrack={({ props, children }) => ( |
323 |
| - <div |
324 |
| - {...props} |
325 |
| - style={{ |
326 |
| - ...props.style, |
327 |
| - height: "5px", |
328 |
| - width: "100%", |
329 |
| - background: getTrackBackground({ |
330 |
| - values: [value], |
331 |
| - colors: ["red", "#ccc"], |
332 |
| - min: 0, |
333 |
| - max: totalSeconds, |
334 |
| - }), |
335 |
| - }} |
336 |
| - > |
337 |
| - {children} |
338 |
| - </div> |
339 |
| - )} |
340 |
| - renderThumb={({ props }) => ( |
341 |
| - <div |
342 |
| - {...props} |
343 |
| - style={{ |
344 |
| - ...props.style, |
345 |
| - height: "12px", |
346 |
| - width: "12px", |
347 |
| - borderRadius: "50%", |
348 |
| - backgroundColor: "red", |
349 |
| - }} |
350 |
| - /> |
351 |
| - )} |
352 |
| - /> |
353 |
| - <button |
354 |
| - onClick={() => |
355 |
| - onChange({ |
356 |
| - stepIndex: stepIndex - 1, |
357 |
| - videoTime: 0, |
358 |
| - }) |
359 |
| - } |
360 |
| - > |
361 |
| - Prev |
362 |
| - </button> |
363 |
| - {isPlaying ? ( |
364 |
| - <button onClick={pause}>Pause</button> |
365 |
| - ) : ( |
366 |
| - <button onClick={play}>Play</button> |
367 |
| - )} |
368 |
| - <button |
369 |
| - onClick={() => |
370 |
| - onChange({ |
371 |
| - stepIndex: stepIndex + 1, |
372 |
| - videoTime: 0, |
373 |
| - }) |
374 |
| - } |
375 |
| - > |
376 |
| - Next |
377 |
| - </button> |
378 |
| - <div style={{ color: "white" }}>{videoTime}</div> |
379 |
| - </> |
380 |
| - ) |
381 | 113 | }
|
0 commit comments