Skip to content

Commit

Permalink
Merge pull request #249 from lookit/release/v3.0.0
Browse files Browse the repository at this point in the history
Release/v3.0.0
  • Loading branch information
Kim Scott committed Apr 23, 2021
2 parents f1e34c1 + ba507a5 commit f871c02
Show file tree
Hide file tree
Showing 21 changed files with 777 additions and 273 deletions.
18 changes: 15 additions & 3 deletions app/components/exp-frame-base/doc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ Parameters
------------------

All frames (with the exception of ``exp-lookit-mood-questionnaire``) support basic translation, although availability of
particular languages is subject to someone having handled translations for that language.
particular languages is subject to someone having handled translations for that language. If the language you want to
test in isn't available, you can add it!

.. _translation:

Expand All @@ -24,8 +25,19 @@ language [String]
study to set the language for all frames.

Current options are 'en-US' (English, US) and 'nl' (Dutch). To add another language option, please contact Lookit
staff. You will need to make a copy of the `English translation file<https://github.com/lookit/ember-lookit-frameplayer/blob/develop/translations/en-us.yaml>`__ and fill in the translations. We will add this to the codebase and have you take a look at an example
study to confirm everything looks good.
staff. You will need to make a copy of the `English translation file <https://github.com/lookit/ember-lookit-frameplayer/blob/develop/translations/en-us.yaml>`__ and translate the text after the colon
on each line, leaving everything else the same. You can see an example `here <https://github.com/lookit/ember-lookit-frameplayer/blob/develop/translations/nl.yaml>`__. There are three special cases:

* If there's HTML formatting, leave it be (just edit the text). E.g. ``<strong>Private</strong>`` became
``<strong>Privé:</strong>`` in Dutch.

* If there are values inside ``{}``, don’t translate them, just use them as placeholders: e.g.,
``private-option-list-with-databrary: de Lookit projectstaf, onderzoekers die werken met {contact} ...``

* When you see something starting ``{variable_name, select, true {X} other {Y}}``, translate X and Y only. These
correspond to what text to show in two different scenarios: when ``variable_name`` is true and when it's false.
The primary way we use this is to edit the consent form (template 5+ only) when it's intended to be used by an
adult only, rather than parent and child.

There are several parameters that ALL frames accept to allow you to customize the study "flow," which are:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Infant-controlled version of the :ref:`exp-lookit-images-audio` frame. This work

- end the trial by pressing the ``endTrialKey`` key
- hold down the ``lookawayKey`` (or the mouse button) to indicate that the child is not looking; the trial will automatically end
after the lookaway criterion is met. If the 'lookawayTone' is not 'none' a noise is played while the child is looking
after the lookaway criterion is met. If a 'lookawayTone' is provided, a noise is played while the child is looking
away to help the parent know the looking coding is working.

You can disable either of these behaviors by setting the corresponding key to ``''``.
Expand Down Expand Up @@ -67,7 +67,10 @@ than 2 s total, as coded by the parent holding down the P key, it will proceed.
"position": "fill"
}
],
"baseDir": "https://www.mit.edu/~kimscott/placeholderstimuli/",
"audioTypes": ["ogg", "mp3"],
"autoProceed": true,
"doRecording": true,
"durationSeconds": 30,
Expand Down
5 changes: 5 additions & 0 deletions app/components/exp-lookit-stimuli-preview/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ export default ExpFrameBaseComponent.extend(VideoRecord, ExpandAssets, {
default: true
},

requirePreview: {
type: 'boolean',
default: false
},

blocks: {
type: 'array',
items: {
Expand Down
4 changes: 4 additions & 0 deletions app/components/exp-lookit-stimuli-preview/doc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Example
"kind": "exp-lookit-stimuli-preview",
"doRecording": true,
"skipButtonText": "Skip preview",
"requirePreview": false,
"previewButtonText": "I'd like to preview the videos",
"blocks": [
{
Expand Down Expand Up @@ -103,6 +104,9 @@ blocks [Array]
previewButtonText [String | ``'I\'d like to preview the videos'``
Text on the preview button user clicks to proceed to stimuli/images

requirePreview [Boolean | ``false``]
Whether to require previewing the stimuli. If true, no button to skip preview is provided.

skipButtonText [String | ``'Skip preview'``]
Text to display on the button to skip the next frame

Expand Down
10 changes: 6 additions & 4 deletions app/components/exp-lookit-stimuli-preview/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,15 @@
{{#if prompt}}

<div class="row exp-controls col-md-12">
{{#if showPreviousButton}}
<button type="button" class="btn btn-default pull-left" {{ action "previous" }} > {{t "Previous" }}</button>
{{/if}}
<button type="button" class="btn btn-primary pull-right" {{ action "next" }} > {{skipButtonText}} </button>
{{#unless requirePreview}}
<button type="button" class="btn btn-primary pull-right" {{ action "next" }} > {{skipButtonText}} </button>
{{/unless}}
</div>

<div class="exp-controls col-md-12 row">
{{#if showPreviousButton}}
<button type="button" class="btn btn-default pull-left" {{ action "previous" }} > {{t "Previous" }}</button>
{{/if}}
<button type="button" class="btn btn-success pull-right" disabled={{recorderSettingUp}} {{action "accept"}}>
{{previewButtonText}}
{{#if recorderSettingUp}} ({{t "please wait, setting up" }}...){{/if}}
Expand Down
40 changes: 22 additions & 18 deletions app/components/exp-lookit-video-assent/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -425,24 +425,7 @@ export default ExpFrameBaseComponent.extend(VideoRecord, ExpandAssets, {
},

didInsertElement() {
this._super(...arguments);
this.set('assentFormText', $('#consent-form-full-text').text());

var hasCompletedEachPageAudio = [];
for (let iPage = 0; iPage < this.get('pages_parsed').length; iPage++) {
hasCompletedEachPageAudio[iPage] = !this.get('pages_parsed')[iPage].audio; // count as completed if no audio
}
this.set('hasCompletedEachPageAudio', hasCompletedEachPageAudio);

var hasCompletedEachPageVideo = [];
for (let iPage = 0; iPage < this.get('pages_parsed').length; iPage++) {
hasCompletedEachPageVideo[iPage] = !this.get('pages_parsed')[iPage].video; // count as completed if no video
}
this.set('hasCompletedEachPageVideo', hasCompletedEachPageVideo);

this.set('pageIndex', -1);
this.send('nextVideo');

// Decide whether to skip based on age - do this BEFORE _super() to avoid setting up camera but immediately moving on
if (this.get('session').get('child') && this.get('session').get('child').get('birthday')) { // always show frame in preview mode
var dob = this.get('session').get('child').get('birthday');

Expand All @@ -464,9 +447,30 @@ export default ExpFrameBaseComponent.extend(VideoRecord, ExpandAssets, {
* @event skipAssentDueToParticipantAge
*/
this.send('setTimeEvent', 'skipAssentDueToParticipantAge');
this.set('doUseCamera', false);
this.send('next');
return;
}
}

this._super(...arguments);
this.set('assentFormText', $('#consent-form-full-text').text());

var hasCompletedEachPageAudio = [];
for (let iPage = 0; iPage < this.get('pages_parsed').length; iPage++) {
hasCompletedEachPageAudio[iPage] = !this.get('pages_parsed')[iPage].audio; // count as completed if no audio
}
this.set('hasCompletedEachPageAudio', hasCompletedEachPageAudio);

var hasCompletedEachPageVideo = [];
for (let iPage = 0; iPage < this.get('pages_parsed').length; iPage++) {
hasCompletedEachPageVideo[iPage] = !this.get('pages_parsed')[iPage].video; // count as completed if no video
}
this.set('hasCompletedEachPageVideo', hasCompletedEachPageVideo);

this.set('pageIndex', -1);
this.send('nextVideo');

}

});
2 changes: 1 addition & 1 deletion app/components/exp-lookit-video-consent/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@
{{/if}}
</span>
<span class="video-consent-direction">
Click to
{{ t "exp-lookit-video-consent.click-to"}}
<button type="button" id="stopbutton" disabled="disabled" class="btn btn-primary pull-right" {{ action "stop" }}>{{ t "exp-lookit-video-consent.stop-recording" }} <i class="fa fa-stop"></i></button>
</span>
</div>
Expand Down
2 changes: 1 addition & 1 deletion app/components/exp-lookit-video-infant-control/doc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Infant-controlled version of the :ref:`exp-lookit-video` frame. This works the s

- end the trial by pressing the ``endTrialKey`` key
- hold down the ``lookawayKey`` (or the mouse button) to indicate that the child is not looking; the trial will automatically end
after the lookaway criterion is met. If the 'lookawayTone' is not 'none' a noise is played while the child is looking
after the lookaway criterion is met. If a 'lookawayTone' is provided, a noise is played while the child is looking
away to help the parent know the looking coding is working.

You can disable either of these behaviors by setting the corresponding key to ``''``.
Expand Down
2 changes: 1 addition & 1 deletion app/components/exp-player/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export default Ember.Component.extend(FullScreen, {
$(window).on('beforeunload', this.beforeUnload.bind(this));
var _this = this;
Ember.$(window).on('keydown', (e) => {
if ((e.which === 112) || (e.ctrlKey && e.which == 88)) { // F1 key or ctrl-x
if ((e.which === 112) || (e.which === 27) || (e.ctrlKey && e.which == 88)) { // F1 key, Esc, or ctrl-x
_this.exitFullscreen();
_this.showConfirmationDialog();
}
Expand Down
38 changes: 20 additions & 18 deletions app/mixins/infant-controlled-timing.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import Ember from 'ember';
import {audioAssetOptions} from "./expand-assets";
import {mergeObjectOfArrays} from "../utils/replace-values";

let {
$
Expand Down Expand Up @@ -115,17 +117,9 @@ var infantControlledTimingMixin = Ember.Mixin.create({
default: 'q'
},

/**
Type of audio to play during parent-coded lookaways - 'tone' (A 220), 'noise' (pink noise), or 'none'. These
tones are available at https://www.mit.edu/~kimscott/placeholderstimuli/ if you want to use them in
instructions.
@property {string} lookawayTone
@default 'noise'
*/
lookawayTone: {
type: 'string',
enum: ['tone', 'noise', 'none'],
default: 'noise',
anyOf: audioAssetOptions,
default: '',
description: 'Type of audio to play during parent-coded lookaways'
},

Expand Down Expand Up @@ -353,6 +347,16 @@ var infantControlledTimingMixin = Ember.Mixin.create({
$(document).off('keyup.parentEndTrial');
},

// Expand lookawayTone based on baseDir if appropriate
didReceiveAttrs() {
let assets = this.get('assetsToExpand') ? this.get('assetsToExpand') : {};
let additionalAssetsToExpand = {
audio: ['lookawayTone']
};
this.set('assetsToExpand', mergeObjectOfArrays(assets, additionalAssetsToExpand));
this._super(...arguments);
},

didInsertElement() {
this.set('_isLooking', true); // Default assumption is child is looking; hold down key for lookaway.
this.set('_totalLookaway', 0);
Expand All @@ -377,15 +381,13 @@ var infantControlledTimingMixin = Ember.Mixin.create({
});

try {
let useLookawayTone = this.get('lookawayTone') !== 'none';
if (useLookawayTone) {
const baseDir = 'https://www.mit.edu/~kimscott/placeholderstimuli/';
let audioElement = $('<audio id="lookawayTone" loop></audio>');
$(`<source src='${baseDir}mp3/${this.get('lookawayTone')}.mp3' type='audio/mp3'>`).appendTo(audioElement);
$(`<source src='${baseDir}ogg/${this.get('lookawayTone')}.ogg' type='audio/ogg'>`).appendTo(audioElement);
$('#experiment-player > div > div').append(audioElement);
$('audio#lookawayTone')[0].volume = this.get('lookawayToneVolume');
let lookawayTones = this.get('lookawayTone_parsed') ? this.get('lookawayTone_parsed') : [];
let audioElement = $('<audio id="lookawayTone" loop></audio>');
for (let i = 0; i < lookawayTones.length; i++) {
$(`<source src='${lookawayTones[i].src}' type='${lookawayTones[i].type}'>`).appendTo(audioElement);
}
$('#experiment-player > div > div').append(audioElement);
$('audio#lookawayTone')[0].volume = this.get('lookawayToneVolume');
} catch (e) {
console.error(`Error setting lookaway tone: ${e}`);
}
Expand Down
6 changes: 3 additions & 3 deletions app/mixins/infant-controlled-timing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ endTrialKey [String | ``'q'``]
for this trial. You can look up the names of keys at https://keycode.info. Default is 'q'.

lookawayTone [String | ``'noise'``]
Type of audio to play during parent-coded lookaways - 'tone' (A 220), 'noise' (pink noise), or 'none'. These
tones are available at https://www.mit.edu/~kimscott/placeholderstimuli/ if you want to use them in
instructions.
Audio file to play during parent-coded lookaways play during parent-coded lookaways, e.g. tone or noise. This can
be either an array of ``{src: 'url', type: 'MIMEtype'}`` objects or a single string relative to ``baseDir/<EXT>``.
Sample tones are available at https://www.mit.edu/~kimscott/placeholderstimuli/.

lookawayToneVolume [Number | ``0.25``]
Volume of lookaway tone, as fraction of full volume (1 = full volume, 0 = silent)
Expand Down
16 changes: 9 additions & 7 deletions app/styles/components/exp-lookit-instruction-video.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@
border: medium solid #aaa;
padding: 1em;
padding-top: 1.5em; // make space for overlapping title

img {
max-width: 75%;
border: thin solid black;
display: block;
margin: auto;
clear: both;
}

}

.transcript-title {
Expand All @@ -44,13 +53,6 @@

li {
margin-bottom: 20px;

img.text-block-img {
float: right;
max-height: 180px;
border-radius: 10%;
border: thin solid black;
}
}

.media-warning {
Expand Down
7 changes: 3 additions & 4 deletions app/utils/is-color.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@ const colorSpecToRgbaArray = function(color) {
* color_convert.to_rgb_array('garbagey') # [0, 0, 0, 0]
*/
context.fillStyle = 'rgba(0, 0, 0, 0)';
// We're reusing the canvas, so fill it with something predictable
context.clearRect(0, 0, 1, 1);
context.fillStyle = color;
context.fillRect(0, 0, 1, 1);
return context.getImageData(0, 0, 1, 1).data;
// Make the fillRect larger than one pixel needed because colors of borders are sometimes slightly lighter
context.fillRect(0, 0, 8, 8);
return Uint8ClampedArray.from(context.getImageData(4, 4, 1, 1).data);
};

// Return either 'black' or 'white' depending on whether background color (RGB(A) array) is dark or light)
Expand Down
6 changes: 3 additions & 3 deletions app/utils/protocol-generator.rst
Original file line number Diff line number Diff line change
Expand Up @@ -385,11 +385,11 @@ On each test trial, the infant sees two images, one on the right and one on the
// Returns a random element of an array, and removes that element from the array
function pop_random(array) {
var randIndex = Math.floor(Math.random() * array.length);
if (array.length) {
return array.pop(randIndex);
let randIndex = Math.floor(Math.random() * array.length);
return array.splice(randIndex, 1)[0];
}
return null
return null;
}
// -------- End helper functions -------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ember-lookit-frameplayer",
"version": "v2.3.2",
"version": "v3.0.0",
"description": "Ember Frame Player",
"private": true,
"directories": {
Expand Down

0 comments on commit f871c02

Please sign in to comment.