From 51eb4ee84327e05baf1577b64f58fdf8f197fcaf Mon Sep 17 00:00:00 2001 From: YUUU23 Date: Fri, 9 Aug 2024 11:53:51 -0500 Subject: [PATCH 1/4] ref: change all func taking in jspsych to const syntax / trials to const trials --- src/experiment/honeycomb.js | 7 +- src/experiment/procedures/endProcedure.js | 7 +- .../procedures/honeycombProcedure.js | 7 +- src/experiment/procedures/startProcedure.js | 7 +- src/experiment/trials/camera.js | 168 +++++++++--------- src/experiment/trials/fixation.js | 70 ++++---- src/experiment/trials/honeycombTrials.js | 50 +++--- 7 files changed, 151 insertions(+), 165 deletions(-) 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 090dc3ca..dba2e5c5 100644 --- a/src/experiment/procedures/endProcedure.js +++ b/src/experiment/procedures/endProcedure.js @@ -8,15 +8,14 @@ import { exitFullscreenTrial } from "../trials/fullscreen"; * 1) Trial used to complete the user's camera recording is displayed * 2) The experiment exits fullscreen * - * @param {Object} jsPsych The jsPsych instance being used to run the task * @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 @@ -24,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 a2fd0f33..5201a335 100644 --- a/src/experiment/procedures/honeycombProcedure.js +++ b/src/experiment/procedures/honeycombProcedure.js @@ -12,12 +12,11 @@ import { buildFixationTrial } from "../trials/fixation"; * * Note that the block is conditionally rendered and repeated based on the task settings * - * @param {Object} jsPsych The jsPsych instance being used to run the task * @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 +67,4 @@ export function buildHoneycombProcedure() { timeline: [fixationTrial, taskTrial], }; return honeycombBlock; -} +}; diff --git a/src/experiment/procedures/startProcedure.js b/src/experiment/procedures/startProcedure.js index c6decf26..b929eee1 100644 --- a/src/experiment/procedures/startProcedure.js +++ b/src/experiment/procedures/startProcedure.js @@ -15,10 +15,9 @@ import { introductionTrial } from "../trials/introduction"; * 4) Trials used to set up a photodiode and trigger box are displayed (if applicable) * 5) Trials used to set up the user's camera are displayed (if applicable) * - * @param {Object} jsPsych The jsPsych instance being used to run the task * @returns {Object} A jsPsych (nested) timeline object */ -export function buildStartProcedure() { +export const buildStartProcedure = () => { const procedure = [nameTrial, enterFullscreenTrial, introductionTrial]; // Conditionally add the photodiode setup trials @@ -29,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 5d95aaca..638a9cec 100644 --- a/src/experiment/trials/camera.js +++ b/src/experiment/trials/camera.js @@ -9,111 +9,105 @@ 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 */ // TODO @brown-ccv #301: Use jsPsych extension, deprecate this function // 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 = window.jsPsych.pluginAPI.getCameraRecorder(); - if (!cameraRecorder) { - console.error("Camera is not initialized, no data will be recorded."); - return; - } - const cameraChunks = []; + const cameraRecorder = window.jsPsych.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