diff --git a/src/experiment/honeycomb.js b/src/experiment/honeycomb.js index f177640b..24249d62 100644 --- a/src/experiment/honeycomb.js +++ b/src/experiment/honeycomb.js @@ -31,10 +31,9 @@ export const honeycombOptions = { * Take a look at how the code here compares to the jsPsych documentation! * See the jsPsych documentation for more: https://www.jspsych.org/7.3/tutorials/rt-task/ * - * @param {Object} jsPsych The jsPsych instance being used to run the task * @returns {Object} A jsPsych timeline object */ -export function buildHoneycombTimeline() { +export const buildHoneycombTimeline = () => { // Build the trials that make up the start procedure const startProcedure = buildStartProcedure(); @@ -42,7 +41,7 @@ export function buildHoneycombTimeline() { const honeycombProcedure = buildHoneycombProcedure(); // Builds the trial needed to debrief the participant on their performance - const debriefTrial = buildDebriefTrial(); + const debriefTrial = buildDebriefTrial; // Builds the trials that make up the end procedure const endProcedure = buildEndProcedure(); @@ -56,4 +55,4 @@ export function buildHoneycombTimeline() { endProcedure, ]; return timeline; -} +}; diff --git a/src/experiment/procedures/endProcedure.js b/src/experiment/procedures/endProcedure.js index 29b7b5ca..dba2e5c5 100644 --- a/src/experiment/procedures/endProcedure.js +++ b/src/experiment/procedures/endProcedure.js @@ -10,12 +10,12 @@ import { exitFullscreenTrial } from "../trials/fullscreen"; * * @returns {Object} A jsPsych (nested) timeline object */ -export function buildEndProcedure() { +export const buildEndProcedure = () => { const procedure = []; // Conditionally add the camera breakdown trials if (ENV.USE_CAMERA) { - procedure.push(buildCameraEndTrial()); + procedure.push(buildCameraEndTrial); } // Add the other trials needed to end the experiment @@ -23,4 +23,4 @@ export function buildEndProcedure() { // Return the block as a nested timeline return { timeline: procedure }; -} +}; diff --git a/src/experiment/procedures/honeycombProcedure.js b/src/experiment/procedures/honeycombProcedure.js index b941443e..eb8bbfa5 100644 --- a/src/experiment/procedures/honeycombProcedure.js +++ b/src/experiment/procedures/honeycombProcedure.js @@ -15,9 +15,9 @@ import { getJsPsych } from "../../lib/utils"; * * @returns {Object} A jsPsych (nested) timeline object */ -export function buildHoneycombProcedure() { +export const buildHoneycombProcedure = () => { const honeycombSettings = SETTINGS.honeycomb; - const fixationTrial = buildFixationTrial(); + const fixationTrial = buildFixationTrial; /** * Displays a colored circle and waits for participant to response with a keyboard press * @@ -68,4 +68,4 @@ export function buildHoneycombProcedure() { timeline: [fixationTrial, taskTrial], }; return honeycombBlock; -} +}; diff --git a/src/experiment/procedures/startProcedure.js b/src/experiment/procedures/startProcedure.js index ebe4bc45..b929eee1 100644 --- a/src/experiment/procedures/startProcedure.js +++ b/src/experiment/procedures/startProcedure.js @@ -17,7 +17,7 @@ import { introductionTrial } from "../trials/introduction"; * * @returns {Object} A jsPsych (nested) timeline object */ -export function buildStartProcedure() { +export const buildStartProcedure = () => { const procedure = [nameTrial, enterFullscreenTrial, introductionTrial]; // Conditionally add the photodiode setup trials @@ -28,9 +28,9 @@ export function buildStartProcedure() { // Conditionally add the camera setup trials if (ENV.USE_CAMERA) { - procedure.push(buildCameraStartTrial()); + procedure.push(buildCameraStartTrial); } // Return the block as a nested timeline return { timeline: procedure }; -} +}; diff --git a/src/experiment/trials/camera.js b/src/experiment/trials/camera.js index d338d439..d253b1ae 100644 --- a/src/experiment/trials/camera.js +++ b/src/experiment/trials/camera.js @@ -10,111 +10,106 @@ const WEBCAM_ID = "webcam"; /** * A trial that begins recording the participant using their computer's default camera - * @param {Object} jsPsych The jsPsych instance being used to run the task - * @returns {Object} A jsPsych trial object + * + * @type {Object} A jsPsych trial object */ -// TODO @brown-ccv #301: Use jsPsych extension, deprecate this function +// TODO @brown-ccv #301: Use jsPsych extension, deprecate this variable // TODO @brown-ccv #343: We should be able to make this work on both electron and browser? // TODO @brown-ccv #301: Rolling save to the deployment (webm is a subset of mkv) -export function buildCameraStartTrial() { - return { - timeline: [ - { - // Prompts user permission for camera device - type: initializeCamera, - include_audio: true, - mime_type: "video/webm", +export const buildCameraStartTrial = { + timeline: [ + { + // Prompts user permission for camera device + type: initializeCamera, + include_audio: true, + mime_type: "video/webm", + }, + { + // Helps participant center themselves inside the camera + type: htmlButtonResponse, + stimulus: function () { + const videoMarkup = tag("video", "", { + id: WEBCAM_ID, + width: 640, + height: 480, + autoplay: true, + }); + const cameraStartMarkup = p(LANGUAGE.trials.camera.start); + const trialMarkup = div(cameraStartMarkup + videoMarkup, { + class: "align-items-center-col", + }); + return div(trialMarkup); }, - { - // Helps participant center themselves inside the camera - type: htmlButtonResponse, - stimulus: function () { - const videoMarkup = tag("video", "", { - id: WEBCAM_ID, - width: 640, - height: 480, - autoplay: true, - }); - const cameraStartMarkup = p(LANGUAGE.trials.camera.start); - const trialMarkup = div(cameraStartMarkup + videoMarkup, { - class: "align-items-center-col", - }); - return div(trialMarkup); - }, - choices: [LANGUAGE.prompts.continue.button], - response_ends_trial: true, - on_start: function () { - // Initialize and store the camera feed - if (!ENV.USE_ELECTRON) { - throw new Error("video recording is only available when running inside Electron"); - } + choices: [LANGUAGE.prompts.continue.button], + response_ends_trial: true, + on_start: function () { + // Initialize and store the camera feed + if (!ENV.USE_ELECTRON) { + throw new Error("video recording is only available when running inside Electron"); + } - const cameraRecorder = getJsPsych().pluginAPI.getCameraRecorder(); - if (!cameraRecorder) { - console.error("Camera is not initialized, no data will be recorded."); - return; - } - const cameraChunks = []; + const cameraRecorder = getJsPsych().pluginAPI.getCameraRecorder(); + if (!cameraRecorder) { + console.error("Camera is not initialized, no data will be recorded."); + return; + } + const cameraChunks = []; - // Push data whenever available - cameraRecorder.addEventListener("dataavailable", (event) => { - if (event.data.size > 0) cameraChunks.push(event.data); - }); + // Push data whenever available + cameraRecorder.addEventListener("dataavailable", (event) => { + if (event.data.size > 0) cameraChunks.push(event.data); + }); - // Saves the raw data feed from the participants camera (executed on cameraRecorder.stop()). - cameraRecorder.addEventListener("stop", () => { - const blob = new Blob(cameraChunks, { type: cameraRecorder.mimeType }); + // Saves the raw data feed from the participants camera (executed on cameraRecorder.stop()). + cameraRecorder.addEventListener("stop", () => { + const blob = new Blob(cameraChunks, { type: cameraRecorder.mimeType }); - // Pass video data to Electron as a base64 encoded string - const reader = new FileReader(); - reader.readAsDataURL(blob); - reader.onloadend = () => { - window.electronAPI.saveVideo(reader.result); - }; - }); - }, - on_load: function () { - // Assign camera feed to the