Files
suspicion-checks-experiment-3/scripts/plugin-lobby.js
Shaheed Azaad 34239413b1 init
2025-07-01 16:53:07 +02:00

179 lines
5.1 KiB
JavaScript

import { ParameterType } from 'jspsych';
import { html } from './text-stimuli';
import getColourMap from './colours';
const info = {
name: 'lobby',
version: "1.0",
parameters: {
user_names: {
type: ParameterType.STRING,
pretty_name: 'User names',
default: [],
array: true,
},
start_text: {
type: ParameterType.STRING,
pretty_name: 'Start text',
},
end_text: {
type: ParameterType.STRING,
pretty_name: 'End text',
},
start_number: {
type: ParameterType.INT,
pretty_name: 'Start number',
default: null,
},
end_number: {
type: ParameterType.INT,
pretty_name: 'End number',
default: 3,
},
join_interval: {
type: ParameterType.INT,
pretty_name: 'Join interval',
default: 5000,
},
user_object: {
type: ParameterType.OBJECT,
pretty_name: 'User object',
default: {},
},
show_avatars: {
type: ParameterType.BOOL,
pretty_name: 'Show avatar',
default: false,
},
data: {
type: ParameterType.OBJECT,
pretty_name: 'Data',
default: {},
},
},
// prettier-ignore
citations: '__CITATIONS__'
};
class jsPsychLobby {
constructor(jsPsych) {
this.jsPsych = jsPsych;
}
static {
this.info = info;
}
trial(display_element, trial) {
let current_participants;
if (!trial.start_number) {
current_participants = Math.floor(Math.random() * trial.end_number) + 1;
} else {
current_participants = trial.start_number;
}
const colourMap = getColourMap(' ');
display_element.innerHTML = html`<div id="search-text" class="mb-4"></div>
<div id="participants-list"></div>
<div id="loading-animation" class="loading"></div>
<div id="refresh-warning" class="mt-4"></div>`;
const search_text_div = document.getElementById('search-text');
const participants_list_div = document.getElementById('participants-list');
const refresh_warning_div = document.getElementById('refresh-warning');
const loading_animation_div = document.getElementById('loading-animation');
search_text_div.innerHTML =
'<p class="text-lg font-semibold" id="search-text-p">' +
trial.start_text +
' (<span id="current-participants">' +
current_participants +
'</span>/' +
trial.end_number +
') ' +
'</p>';
refresh_warning_div.innerHTML =
`<p class="text-sm font-semibold ${colourMap.get('warning')}">Please do not refresh or close this page unless you are not connected to your partner within 5 minutes</p>`;
const current_participants_span = document.getElementById('current-participants');
let participants_list = trial.user_names.slice(1, current_participants);
let ended = false;
const avatar_svg_template = colour => html`
<svg
xmlns="http://www.w3.org/2000/svg"
fill="${colour}"
viewBox="0 0 24 24"
stroke-width="0.5"
stroke="currentColor"
class="size-6"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z"
/>
</svg>
`;
const createParticipantsHtml = () => {
let html = '';
for (let i = 0; i < participants_list.length; i++) {
/* if (trial.show_avatars) {
html += `<div style="width: 24px; height: 24px;">${avatar_svg_template(
trial.user_object[participants_list[i]]
)}</div>`;
} */
if (participants_list[i] === trial.user_names[0]) {
html += `<p class="text-base ${colourMap.get('self-username')}">` + participants_list[i] + ` (you)</p>`;
} else {
html += `<p class="text-base">` + participants_list[i] + ` </p>`;
}
}
return (html);
};
participants_list_div.innerHTML = createParticipantsHtml();
setTimeout(() => {
participants_list.push(trial.user_names[0]);
participants_list_div.innerHTML = createParticipantsHtml();
}, 100);
const updateParticipants = () => {
if (current_participants >= trial.end_number && !ended) {
ended = true;
clearInterval(participants_interval);
setTimeout(this.foundParticipants, 1500);
} else {
participants_list.push(trial.user_names[current_participants]);
participants_list_div.innerHTML = createParticipantsHtml();
current_participants++;
if (current_participants <= trial.end_number && !ended) {
current_participants_span.innerHTML = current_participants;
}
}
};
this.foundParticipants = () => {
participants_list_div.innerHTML = html`<span class="${colourMap.get('success')} font-semibold">${trial.end_text}</span>`;
loading_animation_div.classList.remove('loading');
setTimeout(() => {
this.jsPsych.finishTrial();
}, 2000);
};
const participants_interval = setInterval(
updateParticipants,
trial.join_interval
);
}
}
export default jsPsychLobby;