179 lines
5.1 KiB
JavaScript
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;
|
|
|
|
|
|
|