402 lines
10 KiB
JavaScript
402 lines
10 KiB
JavaScript
import { initJsPsych } from 'jspsych';
|
|
import 'jspsych/css/jspsych.css';
|
|
import jsPsychHtmlKeyboardResponse from '@jspsych/plugin-html-keyboard-response';
|
|
import generateUniqueUsernames from './scripts/name-gen.js';
|
|
import jsPsychFullscreen from '@jspsych/plugin-fullscreen';
|
|
import jsPsychHtmlButtonResponse from '@jspsych/plugin-html-button-response';
|
|
import jsPsychLobby from './scripts/plugin-lobby.js';
|
|
import jsPsychSurvey from '@jspsych/plugin-survey';
|
|
import '@jspsych/plugin-survey/css/survey.css';
|
|
import './styles.css';
|
|
import { getStimulusMap } from './scripts/text-stimuli.js';
|
|
import jsPsychObjectMoving from './scripts/plugin-object-moving.js';
|
|
import { textStimuli } from './scripts/text-stimuli.js';
|
|
|
|
const total_participants = import.meta.env.VITE_TOTAL_PARTICIPANTS || 2;
|
|
const uniqueUsernames = generateUniqueUsernames(total_participants);
|
|
const experiment_name = import.meta.env.VITE_EXPERIMENT_NAME;
|
|
|
|
|
|
let prolific_id;
|
|
let probe_condition; // P in the params, O = open, S = suspicion mentioned
|
|
let debug = false;
|
|
|
|
const short_version = true; // just using the short version of the task
|
|
|
|
function delayed_redirect(url) {
|
|
setTimeout(() => {
|
|
window.location = url;
|
|
}, 5000);
|
|
}
|
|
|
|
const jsPsych = initJsPsych({
|
|
on_finish: function () {
|
|
jsPsych.getDisplayElement().innerHTML = textStimuli.complete;
|
|
},
|
|
on_close: function () {
|
|
delayed_redirect(import.meta.env.VITE_CLOSED_URL);
|
|
},
|
|
on_data_update: function () {
|
|
if (debug) {
|
|
console.log(jsPsych.data.get().json());
|
|
}
|
|
},
|
|
});
|
|
|
|
debug = jsPsych.data.getURLVariable('debug') === 'true';
|
|
|
|
prolific_id = jsPsych.data.getURLVariable('PROLIFIC_PID');
|
|
|
|
const COND = Number(jsPsych.data.getURLVariable('C'));
|
|
|
|
const probe_text_direct = 'Did you have any thoughts, observations, or suspicions about the experiment?'
|
|
const probe_text_indirect = 'Did you have any thoughts or observations about the experiment?';
|
|
|
|
let together_colour;
|
|
let probe_text;
|
|
|
|
|
|
switch (COND) {
|
|
case 0:
|
|
probe_condition = 'direct';
|
|
together_colour = 'blue';
|
|
break;
|
|
case 1:
|
|
probe_condition = 'direct';
|
|
together_colour = 'red';
|
|
break;
|
|
case 2:
|
|
probe_condition = 'indirect';
|
|
together_colour = 'blue';
|
|
break;
|
|
case 3:
|
|
probe_condition = 'indirect';
|
|
together_colour = 'red';
|
|
break;
|
|
}
|
|
|
|
probe_text = probe_condition === 'direct' ? probe_text_direct : probe_text_indirect;
|
|
|
|
const stimulusMap = getStimulusMap(together_colour);
|
|
|
|
const props = {
|
|
condition: probe_condition,
|
|
together_colour: together_colour,
|
|
prolific_id: prolific_id,
|
|
experiment_name: experiment_name,
|
|
probe_text: probe_text,
|
|
}
|
|
|
|
if (debug) {
|
|
console.log(props);
|
|
}
|
|
|
|
jsPsych.data.addProperties(props);
|
|
|
|
const timeline = [];
|
|
|
|
const pre_consent_info = {
|
|
type: jsPsychHtmlKeyboardResponse,
|
|
choices: [' '],
|
|
stimulus: stimulusMap.get('pre_consent_info'),
|
|
};
|
|
|
|
const enter_fullscreen = {
|
|
type: jsPsychFullscreen,
|
|
fullscreen_mode: true,
|
|
};
|
|
|
|
const consent_form = {
|
|
type: jsPsychHtmlButtonResponse,
|
|
stimulus: stimulusMap.get('consent'),
|
|
choices: ['Exit', 'Continue'],
|
|
on_finish: function (data) {
|
|
if (data.response === 0) {
|
|
jsPsych.abortExperiment(stimulusMap.get('no_consent'));
|
|
}
|
|
},
|
|
};
|
|
|
|
const initial_lobby = {
|
|
type: jsPsychLobby,
|
|
user_names: uniqueUsernames,
|
|
end_number: total_participants,
|
|
start_text: 'Searching for a partner',
|
|
end_text: 'Partner found, the experiment will begin shortly.',
|
|
join_interval: 5000,
|
|
show_avatars: false,
|
|
};
|
|
|
|
const lobby_slow = {
|
|
type: jsPsychLobby,
|
|
user_names: uniqueUsernames,
|
|
end_number: total_participants,
|
|
start_text: 'Waiting for your partner',
|
|
end_text: 'Your partner is ready, the experiment will continue shortly.',
|
|
show_avatars: false,
|
|
join_interval: 7000,
|
|
};
|
|
|
|
const lobby_fast = {
|
|
type: jsPsychLobby,
|
|
user_names: uniqueUsernames,
|
|
end_number: total_participants,
|
|
start_text: 'Waiting for your partner',
|
|
end_text: 'Your partner is ready, the experiment will continue shortly.',
|
|
show_avatars: false,
|
|
join_interval: 500,
|
|
};
|
|
|
|
const multi_user_instructions = {
|
|
type: jsPsychHtmlKeyboardResponse,
|
|
choices: [' '],
|
|
stimulus: stimulusMap.get('multi_user_instructions'),
|
|
};
|
|
|
|
const instructions_1 = {
|
|
type: jsPsychHtmlKeyboardResponse,
|
|
choices: [' '],
|
|
stimulus: stimulusMap.get('instructions_1'),
|
|
};
|
|
|
|
const instructions_2 = {
|
|
type: jsPsychHtmlKeyboardResponse,
|
|
choices: [' '],
|
|
stimulus: stimulusMap.get('instructions_2'),
|
|
};
|
|
|
|
const instructions_3 = {
|
|
type: jsPsychHtmlKeyboardResponse,
|
|
choices: [' '],
|
|
stimulus: stimulusMap.get('instructions_3'),
|
|
};
|
|
|
|
const instructions_4 = {
|
|
type: jsPsychHtmlKeyboardResponse,
|
|
choices: [' '],
|
|
stimulus: stimulusMap.get('instructions_4'),
|
|
};
|
|
|
|
const pre_practice_instructions = {
|
|
type: jsPsychHtmlKeyboardResponse,
|
|
choices: [' '],
|
|
stimulus: stimulusMap.get('pre_practice_instructions'),
|
|
};
|
|
|
|
const pre_task_instructions = {
|
|
type: jsPsychHtmlKeyboardResponse,
|
|
choices: [' '],
|
|
stimulus: stimulusMap.get('pre_task_instructions'),
|
|
};
|
|
|
|
const debrief = {
|
|
type: jsPsychHtmlKeyboardResponse,
|
|
choices: [' '],
|
|
stimulus: stimulusMap.get('debrief'),
|
|
};
|
|
|
|
const pre_survey_info = {
|
|
type: jsPsychHtmlKeyboardResponse,
|
|
choices: [' '],
|
|
stimulus: stimulusMap.get('pre_survey_info'),
|
|
};
|
|
|
|
const survey_function = (survey) => {
|
|
survey.onAfterRenderPage.add(function (sender, options) {
|
|
if (survey.activePage.name === 'page1') {
|
|
const nextButton = document.querySelector('#sv-nav-next > div > input');
|
|
if (nextButton) {
|
|
let seconds = 30;
|
|
const originalText = nextButton.value.replace(/\s*\(\d+\)$/, '') || 'Continue';
|
|
nextButton.disabled = true;
|
|
nextButton.value = `${originalText} (${seconds})`;
|
|
const interval = setInterval(() => {
|
|
seconds--;
|
|
nextButton.value = `${originalText} (${seconds})`;
|
|
if (seconds <= 0) {
|
|
clearInterval(interval);
|
|
nextButton.disabled = false;
|
|
nextButton.value = originalText;
|
|
}
|
|
}, 1000);
|
|
}
|
|
console.log('Survey page rendered:', sender.currentPage);
|
|
}
|
|
});
|
|
}
|
|
|
|
const survey = {
|
|
type: jsPsychSurvey,
|
|
survey_function: survey_function,
|
|
survey_json: {
|
|
showQuestionNumbers: false,
|
|
completeText: 'Done!',
|
|
pageNextText: 'Continue',
|
|
pagePrevText: 'Previous',
|
|
showPrevButton: false,
|
|
pages: [
|
|
{
|
|
name: 'page1',
|
|
elements: [
|
|
{
|
|
type: 'comment',
|
|
title: probe_text,
|
|
description: 'You may continue to the next page after 30 seconds.',
|
|
name: 'probe',
|
|
isRequired: debug ? false : true,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'page2',
|
|
elements: [
|
|
{
|
|
type: 'matrix',
|
|
name:
|
|
'To what extent do you agree with the following statements about your partner?',
|
|
alternateRows: true,
|
|
isAllRowRequired: debug ? false : true,
|
|
rows: [
|
|
{
|
|
text: 'I did not believe that my partner was a real person.',
|
|
value: 'SuspicionPartner',
|
|
},
|
|
{
|
|
text: 'I believed that my partner was a real person.',
|
|
value: 'ConfidencePartner',
|
|
},
|
|
],
|
|
columns: [
|
|
{
|
|
value: 5,
|
|
text: 'Strongly agree',
|
|
},
|
|
{
|
|
value: 4,
|
|
text: 'Agree',
|
|
},
|
|
{
|
|
value: 3,
|
|
text: 'Neutral',
|
|
},
|
|
{
|
|
value: 2,
|
|
text: 'Disagree',
|
|
},
|
|
{
|
|
value: 1,
|
|
text: 'Strongly disagree',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'page1',
|
|
elements: [
|
|
{
|
|
type: 'radiogroup',
|
|
title: 'Please indicate your gender',
|
|
choices: ['Male', 'Female', 'Other'],
|
|
isRequired: debug ? false : true,
|
|
colCount: 0,
|
|
name: 'gender',
|
|
},
|
|
{
|
|
type: 'radiogroup',
|
|
title: 'Please indicate your handedness',
|
|
choices: ['Right', 'Left', 'Ambidextrous/Other'],
|
|
isRequired: debug ? false : true,
|
|
colCount: 0,
|
|
name: 'handedness',
|
|
},
|
|
{
|
|
type: 'text',
|
|
title: 'How old are you?',
|
|
name: 'age',
|
|
isRequired: debug ? false : false,
|
|
inputType: 'number',
|
|
min: 18,
|
|
max: 100,
|
|
defaultValue: 18,
|
|
},
|
|
],
|
|
}
|
|
],
|
|
},
|
|
};
|
|
|
|
const factors = {
|
|
selector: ['partner', 'participant'],
|
|
together_side: ['left', 'right'],
|
|
location: short_version ? [33, 50, 66] : [32, 33, 34, 49, 50, 51, 65, 66, 67],
|
|
};
|
|
|
|
const practice_factors = {
|
|
selector: ['partner', 'participant'],
|
|
together_side: ['left', 'right'],
|
|
location: [50],
|
|
};
|
|
|
|
const trials = jsPsych.randomization.factorial(factors, 1);
|
|
|
|
if (debug) {
|
|
console.log(factors);
|
|
console.log(trials);
|
|
}
|
|
|
|
const practice_trials = jsPsych.randomization.factorial(practice_factors, 1);
|
|
|
|
const object_moving_trials = {
|
|
timeline: [
|
|
{
|
|
type: jsPsychObjectMoving,
|
|
selector: jsPsych.timelineVariable('selector'),
|
|
together_side: jsPsych.timelineVariable('together_side'),
|
|
location: jsPsych.timelineVariable('location'),
|
|
together_colour: together_colour,
|
|
},
|
|
],
|
|
timeline_variables: trials,
|
|
};
|
|
|
|
const object_moving_practice = {
|
|
timeline: [
|
|
{
|
|
type: jsPsychObjectMoving,
|
|
selector: jsPsych.timelineVariable('selector'),
|
|
together_side: jsPsych.timelineVariable('together_side'),
|
|
location: jsPsych.timelineVariable('location'),
|
|
together_colour: together_colour,
|
|
},
|
|
],
|
|
timeline_variables: practice_trials,
|
|
};
|
|
|
|
if (debug) {
|
|
timeline.push(debrief);
|
|
|
|
}
|
|
|
|
if (!debug) {
|
|
timeline.push(pre_consent_info);
|
|
timeline.push(consent_form);
|
|
timeline.push(enter_fullscreen);
|
|
timeline.push(multi_user_instructions);
|
|
timeline.push(initial_lobby);
|
|
timeline.push(instructions_1);
|
|
timeline.push(instructions_2);
|
|
timeline.push(instructions_3);
|
|
timeline.push(instructions_4);
|
|
timeline.push(pre_practice_instructions);
|
|
timeline.push(lobby_slow);
|
|
timeline.push(object_moving_practice);
|
|
timeline.push(pre_task_instructions);
|
|
timeline.push(lobby_fast);
|
|
timeline.push(object_moving_trials);
|
|
timeline.push(pre_survey_info);
|
|
timeline.push(survey);
|
|
timeline.push(debrief);
|
|
}
|
|
jsPsych.run(timeline);
|