diff --git a/frontend/src/components/FeedbackForm/FeedbackForm.tsx b/frontend/src/components/FeedbackForm/FeedbackForm.tsx index 869dc92e5..35a8018b4 100644 --- a/frontend/src/components/FeedbackForm/FeedbackForm.tsx +++ b/frontend/src/components/FeedbackForm/FeedbackForm.tsx @@ -3,6 +3,7 @@ import { useState, useRef } from "react"; import Question from "../Question/Question"; import Button from "../Button/Button"; import IQuestion from "@/types/Question"; +import { OnResultType } from "@/hooks/useResultHandler"; interface FeedbackFormProps { formActive: boolean; @@ -10,7 +11,7 @@ interface FeedbackFormProps { buttonLabel: string; skipLabel: string; isSkippable: boolean; - onResult: (result: any) => void; + onResult: OnResultType emphasizeTitle?: boolean; } diff --git a/frontend/src/components/MatchingPairs/MatchingPairs.tsx b/frontend/src/components/MatchingPairs/MatchingPairs.tsx index 5b8405196..61f2e62ca 100644 --- a/frontend/src/components/MatchingPairs/MatchingPairs.tsx +++ b/frontend/src/components/MatchingPairs/MatchingPairs.tsx @@ -1,4 +1,4 @@ -import React, { useRef, useState } from "react"; +import { useRef, useState } from "react"; import classNames from "classnames"; import { scoreIntermediateResult } from "../../API"; diff --git a/frontend/src/components/Trial/Trial.tsx b/frontend/src/components/Trial/Trial.tsx index 853e76d17..9d07551cd 100644 --- a/frontend/src/components/Trial/Trial.tsx +++ b/frontend/src/components/Trial/Trial.tsx @@ -1,4 +1,4 @@ -import React, { useState, useRef, useCallback } from "react"; +import { useState, useRef, useCallback } from "react"; import classNames from "classnames"; import { getCurrentTime, getTimeSince } from "../../util/time"; @@ -6,6 +6,26 @@ import FeedbackForm from "../FeedbackForm/FeedbackForm"; import HTML from "../HTML/HTML"; import Playback from "../Playback/Playback"; import Button from "../Button/Button"; +import Question from "@/types/Question"; +import { OnResultType } from "@/hooks/useResultHandler"; +import { TrialConfig } from "@/types/Trial"; + +interface IFeedbackForm { + form: Question[]; + submit_label: string; + skip_label: string; + is_skippable: boolean; +} + +interface TrialProps { + playback: any; + html: { body: string | TrustedHTML }; + feedback_form: IFeedbackForm; + config: TrialConfig; + result_id: string; + onNext: (breakRound?: boolean) => void; + onResult: OnResultType; +} /** * Trial is an block view to present information to the user and/or collect user feedback @@ -13,7 +33,7 @@ import Button from "../Button/Button"; * If "html" is provided, it will show html content * If "feedback_form" is provided, it will present a form of questions to the user */ -const Trial = (props) => { +const Trial = (props: TrialProps) => { const { playback, @@ -41,13 +61,15 @@ const Trial = (props) => { // Create result data const makeResult = useCallback( - async (result) => { + async (result: { type: 'time_passed' }) => { // Prevent multiple submissions if (submitted.current) { return; } submitted.current = true; + // TODO: Check if we can find another solution for + // the default value of form than [{}] const form = feedback_form ? feedback_form.form : [{}]; if (result.type === "time_passed") { @@ -97,7 +119,8 @@ const Trial = (props) => { const checkBreakRound = (values, breakConditions) => { switch (Object.keys(breakConditions)[0]) { case 'EQUALS': - return values.some(val => breakConditions['EQUALS'].includes(val)); + return values.some(val => breakConditions['EQUALS'] + .includes(val)); case 'NOT': return !values.some(val => breakConditions['NOT'].includes(val)); default: diff --git a/frontend/src/hooks/useResultHandler.ts b/frontend/src/hooks/useResultHandler.ts index 17e0f5dbd..b4c16aff9 100644 --- a/frontend/src/hooks/useResultHandler.ts +++ b/frontend/src/hooks/useResultHandler.ts @@ -2,6 +2,8 @@ import { useRef, useCallback } from "react"; import { scoreResult } from "@/API"; import Session from "@/types/Session"; import Participant from "@/types/Participant"; +import Question from "@/types/Question"; +import { TrialConfig } from "@/types/Trial"; interface ResultData { session: Session; @@ -10,18 +12,31 @@ interface ResultData { section?: unknown; } +interface UseResultHandlerParams { + session: Session; + participant: Participant; + onNext: () => void; + state: any; +} + +interface OnResultParams { + form: Question[]; + decision_time?: number; + config?: TrialConfig +} + /** * useResult provides a reusable function to handle block view data * - collect results in a buffer * - handles advancing to next round * - finally submits the data to the API and loads the new state */ -const useResultHandler = ({ session, participant, onNext, state }) => { +const useResultHandler = ({ session, participant, onNext, state }: UseResultHandlerParams) => { const resultBuffer = useRef([]); const onResult = useCallback( async ( - result: unknown, + result: OnResultParams, forceSubmit = false, goToNextAction = true ) => { @@ -74,4 +89,6 @@ const useResultHandler = ({ session, participant, onNext, state }) => { return onResult; }; +export type OnResultType = ReturnType; + export default useResultHandler; diff --git a/frontend/src/util/audio.ts b/frontend/src/util/audio.ts index 3358828ac..a68d7a62d 100644 --- a/frontend/src/util/audio.ts +++ b/frontend/src/util/audio.ts @@ -6,7 +6,7 @@ import Timer from "./timer"; //