55 |
56 | setPlaying(false)}
59 | />
60 |
61 |
62 | setPlaying(true)}
67 | onEnded={() => {
68 | onDone(data.current, getDimensions());
69 | }}
70 | onProgress={({ playedSeconds }) => {
71 | onProgress && onProgress(playedSeconds);
72 | if (playedSeconds - lastSavedAt > 10) {
73 | savePartialData(data.current, getDimensions());
74 | setLastSavedAt(playedSeconds);
75 | }
76 | }}
77 | playing={playing}
78 | width="100%"
79 | height="100%"
80 | config={{
81 | vimeo: {
82 | playerOptions: {
83 | controls: false,
84 | },
85 | },
86 | }}
87 | />
88 |
89 |
{renderQuestions(onSubmit)}
90 |
91 | );
92 | }
93 |
94 | // Simple component for overlayed help panel
95 | interface OverlayInstructionProps {
96 | instructionsOverlay: string;
97 | onOpen: () => void;
98 | }
99 | export function OverlayInstruction({
100 | instructionsOverlay,
101 | onOpen,
102 | }: OverlayInstructionProps) {
103 | const [show, setShow] = useState(false);
104 | return (
105 | <>
106 | {
126 | setShow(true);
127 | onOpen();
128 | }}
129 | >
130 | Help
131 |
132 | >
133 | );
134 | }
135 |
--------------------------------------------------------------------------------
/src/components/TrialBlock.tsx:
--------------------------------------------------------------------------------
1 | import { useState, useRef } from "react";
2 | import {
3 | TrialBlockConfig,
4 | AnswerSetWithMetadata,
5 | VideoToAnswerSet,
6 | } from "lib/types";
7 | import Instructions from "./Instructions";
8 | import { zipObject, shuffle } from "lodash";
9 | import ConsensusVideoTask from "./videoTask/ConsensusVideoTask";
10 | import ContinuousVideoTask from "./videoTask/ContinuousVideoTask";
11 | import SelfVideoTask from "./videoTask/SelfVideoTask";
12 | import { useShuffled } from "lib/useShuffled";
13 | import { SavePartialData } from "./videoTask/taskTypes";
14 | import TimestampVideoTask from "./videoTask/TimestampVideoTask";
15 |
16 | enum StageEnum {
17 | instructions,
18 | showingVid,
19 | betweenVids,
20 | }
21 |
22 | export interface TrialResult {
23 | answers: VideoToAnswerSet;
24 | videoWidth: number;
25 | videoHeight: number;
26 | }
27 |
28 | interface TrialBlockProps {
29 | config: TrialBlockConfig;
30 | onDone: (data: TrialResult) => void;
31 | onPartialSave: (data: TrialResult) => void;
32 | skipInstructions?: boolean;
33 | }
34 | export default function TrialBlock({
35 | config,
36 | onDone,
37 | onPartialSave,
38 | skipInstructions = false,
39 | }: TrialBlockProps) {
40 | const [stage, setStage] = useState(
41 | skipInstructions ? StageEnum.showingVid : StageEnum.instructions
42 | );
43 | const [vidIndex, setVidIndex] = useState(0);
44 | const videos = useShuffled(config.videos, config.shuffleVideos);
45 | const questions = useShuffled(config?.questions || [], config?.shuffleVideos);
46 | const data = useRef