init
This commit is contained in:
179
scripts/plugin-lobby.js
Normal file
179
scripts/plugin-lobby.js
Normal file
@@ -0,0 +1,179 @@
|
||||
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;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user