mirror of
https://github.com/scratchfoundation/scratchjr.git
synced 2025-07-29 07:18:51 -04:00
357 lines
12 KiB
JavaScript
357 lines
12 KiB
JavaScript
import ScratchAudio from '../utils/ScratchAudio';
|
|
import {gn, getUrlVars, isAndroid, isiOS} from '../utils/lib';
|
|
import OS from '../tablet/OS';
|
|
import UI from '../editor/ui/UI';
|
|
import Localization from '../utils/Localization';
|
|
import InitialOptions from '../utils/InitialOptions';
|
|
|
|
/*
|
|
When this code starts up, there are several scenarios:
|
|
* the app was already running: "AlreadyRunning"
|
|
* the app was not already running, but has been opened before: "NewSession"
|
|
* the app has never been opened before: "FirstTimeEver"
|
|
|
|
*/
|
|
|
|
let alreadyStartedQuestions = false;
|
|
|
|
export function indexMain () {
|
|
gn('gettings').onclick = indexGettingstarted;
|
|
gn('startcode').onclick = indexGohome;
|
|
ScratchAudio.init();
|
|
var urlvars = getUrlVars();
|
|
if (urlvars.back && InitialOptions.allQuestionsAnswered()) {
|
|
indexLoadStart();
|
|
} else {
|
|
indexNewSession();
|
|
}
|
|
|
|
if (window.Settings.edition == 'PBS') {
|
|
gn('topbar-moreapps').textContent = Localization.localize('PBS_MORE_APPS');
|
|
gn('startButton').textContent = Localization.localize('PBS_START');
|
|
gn('gettings').textContent = Localization.localize('PBS_HOW_TO');
|
|
|
|
gn('startButton').onclick = indexGohome;
|
|
gn('pbschars').onclick = indexGohome;
|
|
|
|
gn('topbar-moreapps').onclick = indexMoreApps;
|
|
gn('topbar-settings').onclick = indexGoSettings;
|
|
gn('topbar-info').onclick = indexInfo;
|
|
} else {
|
|
gn('gear').onclick = indexGoSettings;
|
|
}
|
|
|
|
setTimeout(function () {
|
|
gn('rays').className = 'rays spinme';
|
|
}, 250);
|
|
}
|
|
|
|
function startQuestionsIfNotAlreadyStarted () {
|
|
if (!alreadyStartedQuestions) {
|
|
alreadyStartedQuestions = true;
|
|
indexAskRemainingQuestions();
|
|
}
|
|
window.removeEventListener('touchend', startQuestionsIfNotAlreadyStarted, false);
|
|
}
|
|
|
|
function indexNewSession () {
|
|
showSplash();
|
|
OS.askpermission(); // ask for sound recording
|
|
setTimeout(function () {
|
|
OS.hidesplash(addTouchListener);
|
|
}, 500);
|
|
// may be necessary to wait for a touch in some environments
|
|
function addTouchListener () {
|
|
window.addEventListener('touchend', startQuestionsIfNotAlreadyStarted, false);
|
|
}
|
|
setTimeout(startQuestionsIfNotAlreadyStarted, 2000);
|
|
}
|
|
|
|
function showSplash () {
|
|
gn('authors').className = 'credits show';
|
|
gn('authorsText').className = 'creditsText show';
|
|
if (window.Settings.edition == 'PBS') {
|
|
gn('pbschars').className = 'characters hide';
|
|
gn('startcode').className = 'catlogo show';
|
|
gn('topbar').className = 'topbar hide';
|
|
gn('startButton').className = 'startButton hide';
|
|
} else {
|
|
gn('purpleguy').className = 'purple show';
|
|
gn('blueguy').className = 'blue show';
|
|
gn('redguy').className = 'red show';
|
|
}
|
|
}
|
|
|
|
function indexHideSplash () {
|
|
gn('authors').className = 'credits hide';
|
|
gn('authorsText').className = 'creditsText hide';
|
|
|
|
if (window.Settings.edition == 'PBS') {
|
|
gn('pbschars').className = 'characters show';
|
|
gn('topbar').className = 'topbar show';
|
|
gn('startButton').className = 'startButton show';
|
|
} else {
|
|
gn('purpleguy').className = 'purple hide';
|
|
gn('blueguy').className = 'blue hide';
|
|
gn('redguy').className = 'red hide';
|
|
gn('gear').className = 'gear show';
|
|
}
|
|
}
|
|
|
|
// set analytics prefs for all initial options, whether set in this session
|
|
// or before
|
|
function indexSetAnalyticsPrefs () {
|
|
var prefs = InitialOptions.getCurrentVals();
|
|
if (!prefs) return;
|
|
Object.keys(prefs).map(function (key) {
|
|
OS.setAnalyticsPref(key, prefs[key]);
|
|
});
|
|
}
|
|
|
|
function indexLoadStart () {
|
|
indexHideSplash();
|
|
showLogo();
|
|
showGear();
|
|
gn('gettings').className = 'gettings show';
|
|
gn('startcode').className = 'startcode show';
|
|
|
|
indexSetAnalyticsPrefs();
|
|
|
|
document.ontouchmove = function (e) {
|
|
e.preventDefault();
|
|
};
|
|
document.onmousemove = function (e) {
|
|
e.preventDefault();
|
|
};
|
|
if (isAndroid) {
|
|
AndroidInterface.notifySplashDone();
|
|
}
|
|
}
|
|
|
|
function indexAskRemainingQuestions () {
|
|
var nextQuestionKey = InitialOptions.nextUnansweredQuestion();
|
|
if (nextQuestionKey) {
|
|
indexShowQuestion(nextQuestionKey);
|
|
} else { // done with questions
|
|
indexLoadStart();
|
|
}
|
|
}
|
|
|
|
function hideLogo () {
|
|
gn('catface').className = 'catface hide';
|
|
gn('jrlogo').className = 'jrlogo hide';
|
|
}
|
|
|
|
function showLogo () {
|
|
gn('catface').className = 'catface show';
|
|
gn('jrlogo').className = 'jrlogo show';
|
|
}
|
|
|
|
function hideGear () {
|
|
gn('gear').className = 'gear hide';
|
|
}
|
|
|
|
function showGear () {
|
|
gn('gear').className = 'gear show';
|
|
}
|
|
|
|
function indexAskPlace () {
|
|
gn('authors').className = 'credits show';
|
|
gn('authorsText').className = 'creditsText hide';
|
|
gn('purpleguy').className = 'purple hide';
|
|
gn('blueguy').className = 'blue hide';
|
|
gn('redguy').className = 'red hide';
|
|
|
|
gn('usageQuestion').textContent = Localization.localize('USAGE_QUESTION');
|
|
gn('useSchoolText').textContent = Localization.localize('USAGE_SCHOOL');
|
|
gn('useHomeText').textContent = Localization.localize('USAGE_HOME');
|
|
gn('useOtherText').textContent = Localization.localize('USAGE_OTHER');
|
|
gn('usageNoanswerText').textContent = Localization.localize('USAGE_NONE');
|
|
|
|
gn('usageQuestion').className = 'usageQuestion show';
|
|
gn('usageSchool').className = 'usageSchool show';
|
|
gn('usageHome').className = 'usageHome show';
|
|
gn('usageOther').className = 'usageOther show';
|
|
gn('usageNoanswer').className = 'usageNoanswer show';
|
|
gn('usageSchool').onclick = indexSetPlace;
|
|
gn('usageHome').onclick = indexSetPlace;
|
|
gn('usageOther').onclick = indexSetPlace;
|
|
gn('usageNoanswer').onclick = indexSetPlace;
|
|
}
|
|
|
|
function indexSetPlace (e) {
|
|
var usageText = '';
|
|
|
|
switch (e.target.parentElement.id) {
|
|
case 'usageSchool':
|
|
usageText = 'school';
|
|
break;
|
|
case 'usageHome':
|
|
usageText = 'home';
|
|
break;
|
|
case 'usageOther':
|
|
usageText = 'other';
|
|
break;
|
|
case 'usageNoanswer':
|
|
default:
|
|
usageText = 'noanswer';
|
|
break;
|
|
}
|
|
// Send one-time analytics event about usage
|
|
OS.analyticsEvent('lobby', 'scratchjr_usage', usageText);
|
|
InitialOptions.setValue('place_preference', usageText);
|
|
ScratchAudio.sndFX('tap.wav');
|
|
indexHidePlaceQuestion();
|
|
indexAskRemainingQuestions();
|
|
}
|
|
|
|
function indexHidePlaceQuestion () {
|
|
gn('catface').className = 'catface show';
|
|
gn('jrlogo').className = 'jrlogo show';
|
|
gn('usageQuestion').className = 'usageQuestion hide';
|
|
gn('usageSchool').className = 'usageSchool hide';
|
|
gn('usageHome').className = 'usageHome hide';
|
|
gn('usageOther').className = 'usageOther hide';
|
|
gn('usageNoanswer').className = 'usageNoanswer hide';
|
|
}
|
|
|
|
function optionSelected (elem) {
|
|
var key = elem.target.getAttribute('data-key');
|
|
var value = elem.target.getAttribute('data-value');
|
|
// sometimes a touch is registered by a child of the relevant parent
|
|
if (!key && !value) {
|
|
var parent = elem.target.parentNode;
|
|
key = parent.getAttribute('data-key');
|
|
value = parent.getAttribute('data-value');
|
|
}
|
|
// if we still don't have a key and value, something is wrong -- just go
|
|
// to lobby
|
|
if (!key && !value) {
|
|
indexLoadStart();
|
|
return;
|
|
}
|
|
// elem.target.style.backgroundColor = 'purple';
|
|
// if everything is good, register the selection and advance to next screen
|
|
indexSelectOption(key, value);
|
|
}
|
|
|
|
// show the question for a given settings option key
|
|
function indexShowQuestion (key) {
|
|
indexHideSplash();
|
|
hideLogo();
|
|
hideGear();
|
|
var optionType = InitialOptions.optionTypeForKey(key);
|
|
if (optionType === 'place_preference') {
|
|
indexAskPlace();
|
|
} else { // custom question
|
|
var options = InitialOptions.optionsForKey(key);
|
|
// if we could not find any options, choose 'n/a'
|
|
if (!options || !options.length) {
|
|
indexSelectOption(key, 'none');
|
|
return;
|
|
}
|
|
// if there's only one option, don't bother asking, just choose it!
|
|
if (options.length === 1) {
|
|
indexSelectOption(key, options[0]);
|
|
return;
|
|
}
|
|
// if we got here, there is more than one option...
|
|
var instructionText = Localization.localizeOptional(InitialOptions.instructionForKey(key));
|
|
var instructionElem = document.getElementById('optionsInstruction');
|
|
instructionElem.appendChild(document.createTextNode(instructionText));
|
|
gn('optionsInstruction').className = 'optionsInstruction show';
|
|
|
|
var optionsListElem = document.getElementById('optionsList');
|
|
var optionNum = 0;
|
|
options.forEach(function (option) {
|
|
var optionElem = document.createElement('div');
|
|
optionElem.setAttribute('data-key', key);
|
|
optionElem.setAttribute('data-value', option);
|
|
optionElem.setAttribute('id', 'option-' + key + '-' + optionNum);
|
|
optionElem.onclick = optionSelected;
|
|
optionsListElem.appendChild(optionElem);
|
|
|
|
switch (optionType) {
|
|
case 'image':
|
|
var imgElem = document.createElement('img');
|
|
imgElem.setAttribute('src', 'svglibrary/' + option);
|
|
imgElem.setAttribute('style', 'max-width: 150px; max-height: 90px');
|
|
optionElem.appendChild(imgElem);
|
|
break;
|
|
case 'text':
|
|
default:
|
|
var translatedOption = Localization.localizeOptional(option);
|
|
optionElem.appendChild(document.createTextNode(translatedOption));
|
|
break;
|
|
}
|
|
optionNum = optionNum + 1;
|
|
});
|
|
// iPad mini has the minimum screen size, it can show 13 items in one column
|
|
// and we use 3 columns as default
|
|
if (optionNum > 13 * 5) {
|
|
gn('optionsList').style['column-count'] = 8;
|
|
} else if (optionNum > 13 * 3) {
|
|
gn('optionsList').style['column-count'] = 5;
|
|
} else {
|
|
gn('optionsList').style['column-count'] = 3;
|
|
}
|
|
gn('optionsList').className = 'optionsList show';
|
|
}
|
|
}
|
|
|
|
// store user selection, and show next question
|
|
function indexSelectOption (key, val) {
|
|
InitialOptions.setValue(key, val);
|
|
ScratchAudio.sndFX('tap.wav');
|
|
|
|
// clear out old options instruction
|
|
var instructionElem = document.getElementById('optionsInstruction');
|
|
instructionElem.innerHTML = '';
|
|
gn('optionsInstruction').className = 'optionsInstruction hide';
|
|
// clear out old options content
|
|
var optionsListElem = document.getElementById('optionsList');
|
|
optionsListElem.innerHTML = '';
|
|
gn('optionsList').className = 'optionsList hide';
|
|
|
|
// show next question, or advance to start screen
|
|
indexAskRemainingQuestions();
|
|
}
|
|
|
|
function indexGohome () {
|
|
OS.setfile('homescroll.sjr', 0, function () {
|
|
doNext();
|
|
});
|
|
function doNext () {
|
|
window.location.href = 'home.html';
|
|
}
|
|
}
|
|
|
|
function indexGoSettings () {
|
|
// Switch to the settings selection page
|
|
// Triggered by tapping the gear icon in the top right
|
|
ScratchAudio.sndFX('tap.wav');
|
|
window.location.href = 'home.html?place=gear';
|
|
}
|
|
|
|
function indexGettingstarted () {
|
|
ScratchAudio.sndFX('tap.wav');
|
|
window.location.href = 'gettingstarted.html?place=home';
|
|
}
|
|
|
|
// For PBS KIDS edition only
|
|
function indexInfo () {
|
|
ScratchAudio.sndFX('tap.wav');
|
|
window.location.href = 'home.html?place=book';
|
|
}
|
|
|
|
function indexMoreApps () {
|
|
ScratchAudio.sndFX('tap.wav');
|
|
|
|
UI.parentalGate(null, function () {
|
|
if (isiOS) {
|
|
window.location.href = 'https://itunes.apple.com/us/developer/pbs-kids/id324323339?mt=8';
|
|
} else {
|
|
window.location.href = 'http://to.pbs.org/ScJr_GPlay';
|
|
}
|
|
});
|
|
}
|