mumuki-laboratory 8.2.1 → 8.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +19 -8
- data/app/assets/javascripts/mumuki_laboratory/application/bridge.js +2 -1
- data/app/assets/javascripts/mumuki_laboratory/application/button.js +0 -2
- data/app/assets/javascripts/mumuki_laboratory/application/i18n.js +73 -0
- data/app/assets/javascripts/mumuki_laboratory/application/kids.js +22 -1
- data/app/assets/javascripts/mumuki_laboratory/application/kindergarten.js +6 -1
- data/app/assets/javascripts/mumuki_laboratory/application/primary.js +5 -3
- data/app/assets/javascripts/mumuki_laboratory/application/results-renderer.js +28 -1
- data/app/assets/javascripts/mumuki_laboratory/application/submission.js +72 -48
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_kids.scss +4 -0
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_kids_results.scss +1 -0
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_terms.scss +4 -0
- data/app/controllers/chapters_controller.rb +9 -5
- data/app/controllers/guide_container_controller.rb +2 -7
- data/app/helpers/contextualization_result_helper.rb +0 -8
- data/app/helpers/discussions_helper.rb +8 -0
- data/app/helpers/menu_bar_helper.rb +4 -0
- data/app/views/book_discussions/index.html.erb +3 -1
- data/app/views/chapters/show.html.erb +21 -9
- data/app/views/complements/show.html.erb +1 -1
- data/app/views/discussions/index.html.erb +11 -4
- data/app/views/exams/show.html.erb +1 -1
- data/app/views/exercises/show.html.erb +1 -1
- data/app/views/layouts/_discussions.html.erb +0 -4
- data/app/views/layouts/_guide.html.erb +1 -30
- data/app/views/layouts/_guide_container.html.erb +28 -0
- data/app/views/layouts/_guide_title_icons.html.erb +9 -0
- data/app/views/layouts/_social_media.html.erb +2 -2
- data/app/views/layouts/application.html.erb +3 -1
- data/app/views/layouts/exercise_inputs/layouts/_input_kindergarten.html.erb +1 -1
- data/app/views/layouts/modals/_kindergarten_results_aborted.html.erb +1 -1
- data/app/views/lessons/show.html.erb +1 -1
- data/app/views/users/_term.html.erb +1 -1
- data/lib/mumuki/laboratory/controllers/results_rendering.rb +2 -1
- data/lib/mumuki/laboratory/locales/en.yml +2 -7
- data/lib/mumuki/laboratory/locales/es-CL.yml +2 -2
- data/lib/mumuki/laboratory/locales/es.yml +4 -9
- data/lib/mumuki/laboratory/locales/pt.yml +2 -7
- data/lib/mumuki/laboratory/version.rb +1 -1
- data/spec/controllers/exercise_solutions_controller_spec.rb +3 -2
- data/spec/dummy/db/schema.rb +49 -1
- data/spec/dummy/public/character/animations.json +1 -0
- data/{public → spec/dummy/public}/character/kibi/context.svg +0 -0
- data/{public → spec/dummy/public}/character/kibi/failure.svg +0 -0
- data/{public → spec/dummy/public}/character/kibi/jump.svg +0 -0
- data/spec/dummy/public/character/kibi/passed_with_warnings.svg +4 -0
- data/{public → spec/dummy/public}/character/kibi/success2_l.svg +0 -0
- data/{public → spec/dummy/public}/character/kibi/success_l.svg +0 -0
- data/{public → spec/dummy/public}/character/magnifying_glass/apparition.svg +0 -0
- data/{public → spec/dummy/public}/character/magnifying_glass/loop.svg +0 -0
- data/spec/features/chapters_flow_spec.rb +112 -0
- data/spec/features/login_flow_spec.rb +1 -1
- data/spec/features/topic_flow_spec.rb +0 -1
- data/spec/javascripts/i18n-spec.js +79 -0
- data/spec/javascripts/kids-button-spec.js +36 -0
- metadata +29 -13
- data/spec/features/chapter_spec.rb +0 -70
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 222bd258be2916956f315e5195ed53f60ff730f176852e7d52ae17194e789f06
|
4
|
+
data.tar.gz: d3e1701ba286cdfa8d7b44ad529c85df6b9b6fdbe3912fa77dfafab35f9a4545
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb75e14d8e9da062677b7cfb5595ece2717f9b226f085c3432379c87a63acf80e905fda9d890a85bc3afd970d623029d729c86ffff35781fe5b6f1fc938ff92e
|
7
|
+
data.tar.gz: 531e671791fec8e27fb3694a7315eb444d1e3d790ba3186789616562b2b7d6ad609bb7bc1221c94a741c207f2a573aeae9427a1e68aa3d4e3d272ae6f3ce3480
|
data/README.md
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
|
1
|
+
![Build status](https://github.com/mumuki/mumuki-laboratory/workflows/Test%20and%20deploy/badge.svg?branch=master)
|
2
2
|
[![Code Climate](https://codeclimate.com/github/mumuki/mumuki-laboratory/badges/gpa.svg)](https://codeclimate.com/github/mumuki/mumuki-laboratory)
|
3
|
-
[![Issue Count](https://codeclimate.com/github/mumuki/mumuki-laboratory/badges/issue_count.svg)](https://codeclimate.com/github/mumuki/mumuki-laboratory)
|
4
3
|
|
5
4
|
<img width="60%" src="https://raw.githubusercontent.com/mumuki/mumuki-laboratory/master/laboratory-screenshot.png"></img>
|
6
5
|
|
@@ -286,6 +285,7 @@ which are granted to be safe and stable.
|
|
286
285
|
* `updateButtonsVisibility`
|
287
286
|
* `mumuki.submission`
|
288
287
|
* `processSolution`
|
288
|
+
* `sendSolution`
|
289
289
|
* `registerContentSyncer`
|
290
290
|
* `mumuki.version`
|
291
291
|
|
@@ -482,16 +482,27 @@ mumuki.editors.addCustomSource({
|
|
482
482
|
});
|
483
483
|
```
|
484
484
|
|
485
|
-
#### 2.5 Optional:
|
485
|
+
#### 2.5 Optional: Triggering submission processing programmatically
|
486
486
|
|
487
|
-
Your solution will be automatically sent to the client when the submit button is pressed.
|
488
|
-
if you need to trigger submission process programmatically,
|
487
|
+
Your solution will be automatically sent to the client and processed when the submit button is pressed.
|
488
|
+
However, if you need to trigger the whole submission process programmatically,
|
489
|
+
call `mumuki.submission.processSolution`:
|
489
490
|
|
490
491
|
```javascript
|
491
492
|
mumuki.submission.processSolution({solution: {content: /* ... */}});
|
492
493
|
```
|
493
494
|
|
494
|
-
#### 2.6 Optional:
|
495
|
+
#### 2.6 Optional: Sending your solution to the server programmatically
|
496
|
+
|
497
|
+
Your solution will be automatically sent to the client when the submit button is pressed, as part of the
|
498
|
+
solution processing. However, if you just need to send your submission to the server programmatically,
|
499
|
+
call `mumuki.submission.sendSolution`:
|
500
|
+
|
501
|
+
```javascript
|
502
|
+
mumuki.submission.sendSolution({solution: {content: /* ... */}});
|
503
|
+
```
|
504
|
+
|
505
|
+
#### 2.7 Optional: customizing your submit button
|
495
506
|
|
496
507
|
You can alternatively override the default submit button UI and behaviour, by replacing it with a custom component. In order to
|
497
508
|
do that, override the `.mu-submit-button` or the kids-specific `.mu-kids-submit-button`:
|
@@ -506,7 +517,7 @@ However, doing this is tricky, since you will need to manually update the UI and
|
|
506
517
|
* `mumuki.bridge.Laboratory.runTests`
|
507
518
|
* `mumuki.updateProgressBarAndShowModal`
|
508
519
|
|
509
|
-
#### 2.
|
520
|
+
#### 2.8 Register kids scalers
|
510
521
|
|
511
522
|
Kids layouts have some special areas:
|
512
523
|
|
@@ -525,7 +536,7 @@ mumuki.kids.registerBlocksAreaScaler(($blocks) => {
|
|
525
536
|
});
|
526
537
|
```
|
527
538
|
|
528
|
-
#### 2.
|
539
|
+
#### 2.9 Notify when your assets have been loaded
|
529
540
|
|
530
541
|
In order to remove loading spinners, you will need to call `mumuki.assetsLoadedFor` when your code is ready.
|
531
542
|
|
@@ -113,7 +113,8 @@ mumuki.bridge = (() => {
|
|
113
113
|
* @returns {SubmissionResult}
|
114
114
|
*/
|
115
115
|
_preRenderResult(result) {
|
116
|
-
result.class_for_progress_list_item = mumuki.renderers.progressListItemClassForStatus(result.status, true);
|
116
|
+
result.class_for_progress_list_item = mumuki.renderers.results.progressListItemClassForStatus(result.status, true);
|
117
|
+
result.title_html = mumuki.renderers.results.translatedTitleHtml(result.status, result.in_gamified_context);
|
117
118
|
return result;
|
118
119
|
}
|
119
120
|
}
|
@@ -49,7 +49,6 @@ mumuki.Button = class {
|
|
49
49
|
*/
|
50
50
|
wait() {
|
51
51
|
this.$button.off('click');
|
52
|
-
|
53
52
|
this.setWaiting();
|
54
53
|
}
|
55
54
|
|
@@ -77,7 +76,6 @@ mumuki.Button = class {
|
|
77
76
|
*/
|
78
77
|
continue() {
|
79
78
|
this.$button.off('click');
|
80
|
-
|
81
79
|
this.enable();
|
82
80
|
|
83
81
|
this.$button.on('click', this.main);
|
@@ -0,0 +1,73 @@
|
|
1
|
+
mumuki.I18n = (() => {
|
2
|
+
|
3
|
+
const translations = {
|
4
|
+
'es': {
|
5
|
+
aborted: () => "Ups, no pudimos evaluar tu solución",
|
6
|
+
errored: () => "¡Ups! Tu solución no se puede ejecutar",
|
7
|
+
failed: () => "Tu solución no pasó las pruebas",
|
8
|
+
passed: () => "¡Muy bien! Tu solución pasó todas las pruebas",
|
9
|
+
passed_with_warnings: () => "Tu solución funcionó, pero hay cosas que mejorar",
|
10
|
+
pending: () => "Pendiente",
|
11
|
+
skipped: () => "Venís aprendiendo muy bien, por lo que aprobaste este ejercicio",
|
12
|
+
},
|
13
|
+
'es-CL': {
|
14
|
+
aborted: () => "Ups, no pudimos evaluar tu solución",
|
15
|
+
errored: () => "¡Ups! Tu solución no se puede ejecutar",
|
16
|
+
failed: () => "Tu solución no pasó las pruebas",
|
17
|
+
passed: () => "¡Muy bien! Tu solución pasó todas las pruebas",
|
18
|
+
passed_with_warnings: () => "Tu solución funcionó, pero hay cosas que mejorar",
|
19
|
+
pending: () => "Pendiente",
|
20
|
+
skipped: () => "Vienes aprendiendo muy bien, por lo que aprobaste este ejercicio",
|
21
|
+
},
|
22
|
+
'en': {
|
23
|
+
aborted: () => "Oops, we couldn't evaluate your solution",
|
24
|
+
errored: () => "Oops, your solution didn't work",
|
25
|
+
failed: () => "Oops, something went wrong",
|
26
|
+
passed: () => "Everything is in order! Your solution passed all our tests!",
|
27
|
+
passed_with_warnings: () => "It worked, but you can do better",
|
28
|
+
pending: () => "Pending",
|
29
|
+
skipped: () => "You are doing very well, so you've passed this exercise",
|
30
|
+
},
|
31
|
+
'pt': {
|
32
|
+
aborted: () => "Opa, não pudemos avaliar sua solução",
|
33
|
+
errored: () => "Opa! Sua solução não pode ser executada",
|
34
|
+
failed: () => "Sua solução não passou as provas",
|
35
|
+
passed: () => "Muito bem! Sua solução passou todos os testes",
|
36
|
+
passed_with_warnings: () => "Sua solução funcionou, mas há coisas para melhorar",
|
37
|
+
pending: () => "Pendente",
|
38
|
+
skipped: () => "Você está aprendendo muito bem e passou neste exercício",
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
return new class {
|
43
|
+
|
44
|
+
translate(key, data = {}) {
|
45
|
+
const translationValue = this._translationValue(key);
|
46
|
+
switch (typeof(translationValue)) {
|
47
|
+
case 'string': return translationValue;
|
48
|
+
case 'function': return translationValue(data);
|
49
|
+
default: return `Translation missing: ${mumuki.locale}, \`${key}\``;
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
t(key, data = {}) {
|
54
|
+
return mumuki.I18n.translate(key, data);
|
55
|
+
}
|
56
|
+
|
57
|
+
register(translationsToOverride) {
|
58
|
+
const locales = Object.keys(translations);
|
59
|
+
locales.forEach((it) => translations[it] = Object.assign(translations[it], translationsToOverride[it]));
|
60
|
+
}
|
61
|
+
|
62
|
+
_prefixTranslationKey(key) {
|
63
|
+
this._prefix = $('[data-i18n-prefix]');
|
64
|
+
return this._prefix.get(0) ? `${this._prefix.data('i18n-prefix')}_${key}` : key;
|
65
|
+
}
|
66
|
+
|
67
|
+
_translationValue(key) {
|
68
|
+
let translationLocale = translations[mumuki.locale];
|
69
|
+
return translationLocale && (translationLocale[this._prefixTranslationKey(key)] || translationLocale[key]);
|
70
|
+
}
|
71
|
+
|
72
|
+
}
|
73
|
+
})();
|
@@ -1,3 +1,7 @@
|
|
1
|
+
mumuki.load(() => {
|
2
|
+
mumuki.isKidsExercise = () => $('.mu-kids-exercise').length > 0;
|
3
|
+
})
|
4
|
+
|
1
5
|
mumuki.Kids = class {
|
2
6
|
|
3
7
|
constructor() {
|
@@ -11,8 +15,9 @@ mumuki.Kids = class {
|
|
11
15
|
// ================
|
12
16
|
|
13
17
|
initialize() {
|
14
|
-
this.submitButton = new mumuki.submission.
|
18
|
+
this.submitButton = new mumuki.submission.KidsSubmitButton($('#kids-btn-retry'), $('.submission_control'));
|
15
19
|
this.resultActions = {};
|
20
|
+
this.$overlay = $('.mu-kids-overlay');
|
16
21
|
this.$states = $('.mu-kids-states');
|
17
22
|
this.$state = $('.mu-kids-state');
|
18
23
|
this.$blocks = $('.mu-kids-blocks');
|
@@ -27,6 +32,14 @@ mumuki.Kids = class {
|
|
27
32
|
this.$submissionResult = $('.submission-results');
|
28
33
|
mumuki.gamification.currentLevelProgression.registerLevelUpAction(this.levelUpAction);
|
29
34
|
mumuki.gamification.currentLevelProgression.registerGainedExperienceAction(this.gainedExperienceAction);
|
35
|
+
this.$resultsModal.on('hidden.bs.modal', this.resetExerciseIfSubmitless);
|
36
|
+
this.$resultsAbortedModal.on('hidden.bs.modal', this.resetExerciseIfSubmitless);
|
37
|
+
}
|
38
|
+
|
39
|
+
resetExerciseIfSubmitless() {
|
40
|
+
if ($('.mu-submitless-exercise').get(0)) {
|
41
|
+
mumuki.kids.submitButton.continue();
|
42
|
+
}
|
30
43
|
}
|
31
44
|
|
32
45
|
gainedExperienceAction() {
|
@@ -56,6 +69,14 @@ mumuki.Kids = class {
|
|
56
69
|
this.$resultsAbortedModal.modal();
|
57
70
|
}
|
58
71
|
|
72
|
+
showOverlay() {
|
73
|
+
this.$overlay.show();
|
74
|
+
}
|
75
|
+
|
76
|
+
hideOverlay() {
|
77
|
+
this.$overlay.hide();
|
78
|
+
}
|
79
|
+
|
59
80
|
// ==================
|
60
81
|
// == Hook Methods ==
|
61
82
|
// ==================
|
@@ -13,7 +13,7 @@ mumuki.load(() => {
|
|
13
13
|
this.$contextModalButton = new mumuki.Button($('#mu-kids-context .mu-kids-modal-button.mu-close'));
|
14
14
|
|
15
15
|
this.resultActions.passed = this._showSuccessPopup.bind(this);
|
16
|
-
this.resultActions.passed_with_warnings = this.
|
16
|
+
this.resultActions.passed_with_warnings = this._showPassedWithWarnings.bind(this);
|
17
17
|
this.resultActions.failed = this._showFailurePopup.bind(this);
|
18
18
|
this.resultActions.errored = this._showFailurePopup.bind(this);
|
19
19
|
this.resultActions.pending = this._showFailurePopup.bind(this);
|
@@ -50,6 +50,10 @@ mumuki.load(() => {
|
|
50
50
|
this.showNonAbortedPopup(data, 'success2_l');
|
51
51
|
}
|
52
52
|
|
53
|
+
_showPassedWithWarnings(data) {
|
54
|
+
this.showNonAbortedPopup(data, 'passed_with_warnings');
|
55
|
+
}
|
56
|
+
|
53
57
|
_showFailurePopup(data) {
|
54
58
|
this.showNonAbortedPopup(data, 'failure');
|
55
59
|
}
|
@@ -78,6 +82,7 @@ mumuki.load(() => {
|
|
78
82
|
|
79
83
|
restart() {
|
80
84
|
mumuki.presenterCharacter.playAnimation('talk', this.$bubbleCharacterAnimation);
|
85
|
+
this.hideOverlay();
|
81
86
|
}
|
82
87
|
|
83
88
|
// =======================
|
@@ -16,7 +16,6 @@ mumuki.load(() => {
|
|
16
16
|
super.initialize();
|
17
17
|
this.$characterSpeechBubble = $('.mu-kids-character-speech-bubble');
|
18
18
|
this.$characterSpeechBubbleNormal = this.$characterSpeechBubble.children('.mu-kids-character-speech-bubble-normal');
|
19
|
-
this.$overlay = $('.mu-kids-overlay');
|
20
19
|
this.$contextModalButton = new mumuki.Button($('.mu-kids-context .modal-footer button'));
|
21
20
|
|
22
21
|
this._paragraphHeight = undefined;
|
@@ -58,6 +57,10 @@ mumuki.load(() => {
|
|
58
57
|
this.showNonAbortedPopup(data, 'success2_l', 4000);
|
59
58
|
}
|
60
59
|
|
60
|
+
_showPassedWithWarnings(data) {
|
61
|
+
this.showNonAbortedPopup(data, 'passed_with_warnings', 4000);
|
62
|
+
}
|
63
|
+
|
61
64
|
_showFailurePopup(data) {
|
62
65
|
this._showOnCharacterBubble(data);
|
63
66
|
}
|
@@ -137,6 +140,7 @@ mumuki.load(() => {
|
|
137
140
|
const $bubble = this.$characterSpeechBubble;
|
138
141
|
Object.keys(this.resultActions).forEach($bubble.removeClass.bind($bubble));
|
139
142
|
mumuki.presenterCharacter.playAnimation('talk', this.$bubbleCharacterAnimation);
|
143
|
+
this.hideOverlay();
|
140
144
|
}
|
141
145
|
|
142
146
|
// =======================
|
@@ -150,7 +154,6 @@ mumuki.load(() => {
|
|
150
154
|
$bubble.find('.mu-kids-character-speech-bubble-failed').hide();
|
151
155
|
$bubble.find('.mu-kids-discussion-link').remove();
|
152
156
|
Object.keys(this.resultActions).forEach($bubble.removeClass.bind($bubble));
|
153
|
-
this.$overlay.hide();
|
154
157
|
}
|
155
158
|
|
156
159
|
_showMessageOnCharacterBubble(data) {
|
@@ -158,7 +161,6 @@ mumuki.load(() => {
|
|
158
161
|
renderer.setDiscussionsLinkHtml($('#mu-kids-discussion-link-html').html());
|
159
162
|
renderer.setResponseData(data);
|
160
163
|
renderer.render();
|
161
|
-
this.$overlay.show();
|
162
164
|
}
|
163
165
|
|
164
166
|
_showOnCharacterBubble(data) {
|
@@ -35,6 +35,32 @@ mumuki.renderers.results = (() => {
|
|
35
35
|
}
|
36
36
|
}
|
37
37
|
|
38
|
+
/**
|
39
|
+
* @param {SubmissionStatus} status
|
40
|
+
* @param {Boolean} isGamifiedContext
|
41
|
+
* @returns {string}
|
42
|
+
*/
|
43
|
+
function translatedTitleHtml(status, isGamifiedContext) {
|
44
|
+
return `
|
45
|
+
<h4 class="text-${classForStatus(status)} %>">
|
46
|
+
<strong><i class="fa-fw fas ${iconForStatus(status)}"></i> ${mumuki.I18n.t(status)}</strong>
|
47
|
+
${gamifiedContextHtml(isGamifiedContext)}
|
48
|
+
</h4>
|
49
|
+
`
|
50
|
+
}
|
51
|
+
|
52
|
+
/**
|
53
|
+
* @param {Boolean} isGamifiedContext
|
54
|
+
* @returns {string}
|
55
|
+
*/
|
56
|
+
function gamifiedContextHtml(isGamifiedContext) {
|
57
|
+
return (!isGamifiedContext) ? '' : `
|
58
|
+
<strong><small class="text-success">
|
59
|
+
<span class="mu-experience"></span>
|
60
|
+
</small></strong>
|
61
|
+
`
|
62
|
+
}
|
63
|
+
|
38
64
|
|
39
65
|
/**
|
40
66
|
* @param {SubmissionStatus} status
|
@@ -48,7 +74,8 @@ mumuki.renderers.results = (() => {
|
|
48
74
|
return {
|
49
75
|
classForStatus,
|
50
76
|
iconForStatus,
|
51
|
-
progressListItemClassForStatus
|
77
|
+
progressListItemClassForStatus,
|
78
|
+
translatedTitleHtml
|
52
79
|
};
|
53
80
|
})();
|
54
81
|
|
@@ -55,8 +55,50 @@ mumuki.submission = (() => {
|
|
55
55
|
this.preventClick();
|
56
56
|
}
|
57
57
|
}
|
58
|
+
|
59
|
+
solutionSender(bridge, solution) {
|
60
|
+
return bridge._submitSolution(solution);
|
61
|
+
}
|
62
|
+
|
63
|
+
solutionProcessor(bridge, $submissionsResults, solution) {
|
64
|
+
const resultsBox = new ResultsBox($submissionsResults);
|
65
|
+
this.disable();
|
66
|
+
this.setWaitingText();
|
67
|
+
resultsBox.waiting();
|
68
|
+
return this.solutionSender(bridge, solution)
|
69
|
+
.done((data) => resultsBox.success(data, this))
|
70
|
+
.fail(() => resultsBox.error(this))
|
71
|
+
.always((data) => {
|
72
|
+
$(document).renderMuComponents();
|
73
|
+
resultsBox.done(data, this);
|
74
|
+
});
|
75
|
+
}
|
58
76
|
}
|
59
77
|
|
78
|
+
class KidsSubmitButton extends SubmitButton {
|
79
|
+
|
80
|
+
wait() {
|
81
|
+
mumuki.kids.showOverlay();
|
82
|
+
super.wait();
|
83
|
+
}
|
84
|
+
|
85
|
+
continue() {
|
86
|
+
mumuki.kids.hideOverlay();
|
87
|
+
super.continue();
|
88
|
+
}
|
89
|
+
|
90
|
+
solutionProcessor(bridge, $submissionsResults, solution) {
|
91
|
+
this.wait();
|
92
|
+
return this.solutionSender(bridge, solution)
|
93
|
+
.then((data) => mumuki.kids.showResult(data))
|
94
|
+
.always((data) => {
|
95
|
+
this.ready(() => {
|
96
|
+
mumuki.kids.restart();
|
97
|
+
this.continue();
|
98
|
+
});
|
99
|
+
});
|
100
|
+
}
|
101
|
+
}
|
60
102
|
|
61
103
|
// ==========
|
62
104
|
// Processing
|
@@ -67,14 +109,28 @@ mumuki.submission = (() => {
|
|
67
109
|
* restoring buttons state.
|
68
110
|
*
|
69
111
|
* The actual implementation of this method depends on contextual {@link _solutionProcessor}, which can
|
70
|
-
* be configured using {@link _registerSolutionProcessor}. Currently there are only two available processors
|
71
|
-
*
|
72
|
-
* on the exercise DOM.
|
112
|
+
* be configured using {@link _registerSolutionProcessor}. Currently there are only two available processors
|
113
|
+
* which are automatically choosen depending on the exercise DOM.
|
73
114
|
*
|
74
115
|
* @param {Submission} solution
|
75
116
|
*/
|
76
117
|
function processSolution(solution) {
|
77
|
-
mumuki.submission._solutionProcessor(solution);
|
118
|
+
return mumuki.submission._solutionProcessor(solution);
|
119
|
+
}
|
120
|
+
|
121
|
+
/**
|
122
|
+
* Just sends solution to the server without any further processing afterwards.
|
123
|
+
*
|
124
|
+
* Consider using {@link processSolution} instead if you want the whole functionality (making buttons wait, sending to server, rendering results,
|
125
|
+
* restoring buttons state).
|
126
|
+
* The implementation of this method isn't contextual, it always sends the solution using bridge module.
|
127
|
+
*
|
128
|
+
* @see mumuki.bridge
|
129
|
+
*
|
130
|
+
* @param {Submission} solution
|
131
|
+
*/
|
132
|
+
function sendSolution(solution) {
|
133
|
+
return mumuki.submission._solutionSender(solution);
|
78
134
|
}
|
79
135
|
|
80
136
|
/**
|
@@ -84,53 +140,19 @@ mumuki.submission = (() => {
|
|
84
140
|
* and should normally not be called by runners editor, but is exposed
|
85
141
|
* for further non-standard customizations.
|
86
142
|
*
|
87
|
-
* @param {
|
143
|
+
* @param {SubmitButton} submitButton
|
144
|
+
* @param {$ElementType} $submissionsResults
|
145
|
+
* @param {mumuki.bridge} bridge
|
88
146
|
*/
|
89
|
-
function _registerSolutionProcessor(
|
90
|
-
mumuki.submission.
|
91
|
-
|
92
|
-
|
93
|
-
/** Processor for kids layouts */
|
94
|
-
function _kidsSolutionProcessor(bridge, submitButton) {
|
95
|
-
return (solution) => {
|
96
|
-
submitButton.wait();
|
97
|
-
bridge._submitSolution(solution).always(function (data) {
|
98
|
-
submitButton.ready(() => {
|
99
|
-
mumuki.kids.restart();
|
100
|
-
submitButton.continue();
|
101
|
-
});
|
102
|
-
mumuki.kids.showResult(data);
|
103
|
-
});
|
104
|
-
};
|
105
|
-
}
|
106
|
-
|
107
|
-
/** Processor for non-kids layouts */
|
108
|
-
function _classicSolutionProcessor(bridge, submitButton, resultsBox) {
|
109
|
-
return (solution) => {
|
110
|
-
submitButton.disable();
|
111
|
-
submitButton.setWaitingText();
|
112
|
-
resultsBox.waiting();
|
113
|
-
bridge._submitSolution(solution).done(function (data) {
|
114
|
-
resultsBox.success(data, submitButton);
|
115
|
-
}).fail(function () {
|
116
|
-
resultsBox.error(submitButton);
|
117
|
-
}).always(function (data) {
|
118
|
-
$(document).renderMuComponents();
|
119
|
-
resultsBox.done(data, submitButton);
|
120
|
-
});
|
121
|
-
};
|
147
|
+
function _registerSolutionProcessor(submitButton, $submissionsResults, bridge) {
|
148
|
+
mumuki.submission._solutionSender = submitButton.solutionSender.bind(submitButton, bridge);
|
149
|
+
mumuki.submission._solutionProcessor = submitButton.solutionProcessor.bind(submitButton, bridge, $submissionsResults);
|
122
150
|
}
|
123
151
|
|
124
152
|
/** Selects the most appropriate solution processor */
|
125
153
|
function _selectSolutionProcessor(submitButton, $submissionsResults) {
|
126
154
|
const bridge = new mumuki.bridge.Laboratory();
|
127
|
-
|
128
|
-
if ($('.mu-kids-exercise').length) {
|
129
|
-
processor = _kidsSolutionProcessor(bridge, submitButton);
|
130
|
-
} else {
|
131
|
-
processor = _classicSolutionProcessor(bridge, submitButton, new ResultsBox($submissionsResults));
|
132
|
-
}
|
133
|
-
mumuki.submission._registerSolutionProcessor(processor);
|
155
|
+
mumuki.submission._registerSolutionProcessor(submitButton, $submissionsResults, bridge);
|
134
156
|
}
|
135
157
|
|
136
158
|
|
@@ -143,8 +165,8 @@ mumuki.submission = (() => {
|
|
143
165
|
if (!$submissionsResults) return;
|
144
166
|
|
145
167
|
const $btnSubmit = $('.btn-submit');
|
146
|
-
const
|
147
|
-
|
168
|
+
const buttonClass = mumuki.isKidsExercise() ? KidsSubmitButton : SubmitButton;
|
169
|
+
const submitButton = new buttonClass($btnSubmit, $('.submission_control'));
|
148
170
|
mumuki.submission._selectSolutionProcessor(submitButton, $submissionsResults);
|
149
171
|
|
150
172
|
submitButton.start(() => {
|
@@ -154,7 +176,6 @@ mumuki.submission = (() => {
|
|
154
176
|
submitButton.checkAttemptsLeft();
|
155
177
|
});
|
156
178
|
|
157
|
-
|
158
179
|
/**
|
159
180
|
* This module contains methods for submitting solution in at high level, dealing with network communication,
|
160
181
|
* and layout-sensitive UI updates. It is intended to be both used internally by standard editors and by runners
|
@@ -171,10 +192,13 @@ mumuki.submission = (() => {
|
|
171
192
|
*/
|
172
193
|
return {
|
173
194
|
processSolution,
|
195
|
+
sendSolution,
|
196
|
+
|
174
197
|
_registerSolutionProcessor,
|
175
198
|
_selectSolutionProcessor,
|
176
199
|
|
177
200
|
animateTimeoutError,
|
178
201
|
SubmitButton,
|
202
|
+
KidsSubmitButton,
|
179
203
|
};
|
180
204
|
})();
|