@windward/games 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/content/DatableEditor.vue +0 -3
- package/components/content/blocks/crosswordPuzzle/Crossword.ts +553 -0
- package/components/content/blocks/crosswordPuzzle/CrosswordClues.vue +91 -0
- package/components/content/blocks/crosswordPuzzle/CrosswordElements.ts +38 -0
- package/components/content/blocks/crosswordPuzzle/CrosswordPuzzle.vue +673 -0
- package/components/content/blocks/multipleChoice/MultipleChoice.vue +187 -127
- package/components/content/blocks/multipleChoice/QuestionDialog.vue +37 -13
- package/components/content/blocks/sevenStrikes/SevenStikes.vue +368 -0
- package/components/content/blocks/sevenStrikes/keyboard.vue +71 -0
- package/components/content/blocks/wordJumble/Jumble.vue +2 -10
- package/components/content/blocks/wordJumble/WordJumble.vue +22 -10
- package/components/settings/CrosswordPuzzleSettingsManager.vue +271 -0
- package/components/settings/MultipleChoiceSettingsManager.vue +21 -7
- package/components/settings/SevenStrikesSettingsManager.vue +288 -0
- package/components/settings/WordJumbleSettingsManager.vue +4 -1
- package/i18n/en-US/components/content/blocks/crossword.ts +22 -0
- package/i18n/en-US/components/content/blocks/index.ts +4 -0
- package/i18n/en-US/components/content/blocks/multiple_choice.ts +2 -4
- package/i18n/en-US/components/content/blocks/seven_strikes.ts +6 -0
- package/i18n/en-US/components/settings/crossword.ts +7 -0
- package/i18n/en-US/components/settings/index.ts +4 -0
- package/i18n/en-US/components/settings/multiple_choice.ts +1 -1
- package/i18n/en-US/components/settings/seven_strikes.ts +8 -0
- package/i18n/en-US/components/settings/word_jumble.ts +1 -1
- package/i18n/en-US/shared/content_blocks.ts +2 -0
- package/i18n/en-US/shared/settings.ts +2 -0
- package/package.json +2 -1
- package/plugin.js +43 -1
- package/test/blocks/crossword/CrosswordPuzzle.spec.js +49 -0
- package/test/blocks/sevenStrikes/sevenStrikes.spec.js +24 -0
- package/test/settings/BucketGameManager.spec.js +1 -1
- package/test/settings/CrosswordPuzzleManager.spec.js +103 -0
- package/test/settings/SevenStrikesManager.spec.js +53 -0
- package/test/settings/WordJumbleManager.spec.js +2 -2
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<v-col class="pa-0">
|
|
4
|
+
<h3>
|
|
5
|
+
{{
|
|
6
|
+
block.metadata.config.title
|
|
7
|
+
? block.metadata.config.title
|
|
8
|
+
: $t(
|
|
9
|
+
'plugin.games.components.content.blocks.seven_strikes.title'
|
|
10
|
+
)
|
|
11
|
+
}}
|
|
12
|
+
</h3>
|
|
13
|
+
<p>{{ block.metadata.config.instructions }}</p>
|
|
14
|
+
</v-col>
|
|
15
|
+
<v-col class="pa-0">
|
|
16
|
+
<template>
|
|
17
|
+
<v-carousel
|
|
18
|
+
v-model="carouselIndex"
|
|
19
|
+
@change="onSlideChanged($event)"
|
|
20
|
+
>
|
|
21
|
+
<v-carousel-item
|
|
22
|
+
v-for="(word, index) in block.metadata.config.words"
|
|
23
|
+
:key="index"
|
|
24
|
+
>
|
|
25
|
+
<v-row class="d-flex justify-center ma-2">
|
|
26
|
+
<p class="pa-3 mb-0 clueAndJumble">
|
|
27
|
+
{{ word.hint }}
|
|
28
|
+
</p>
|
|
29
|
+
</v-row>
|
|
30
|
+
<v-container
|
|
31
|
+
v-if="showFeedback"
|
|
32
|
+
:key="'feedback'"
|
|
33
|
+
:class="feedbackStatus"
|
|
34
|
+
class="mb-8"
|
|
35
|
+
>
|
|
36
|
+
<v-row class="d-flex" align="center">
|
|
37
|
+
<v-col cols="4"></v-col>
|
|
38
|
+
<v-col cols="4" class="d-flex justify-center">
|
|
39
|
+
<p class="">{{ feedback }}</p>
|
|
40
|
+
</v-col>
|
|
41
|
+
<v-col cols="4" class="d-flex justify-end">
|
|
42
|
+
<v-icon @click="onHideFeedback">
|
|
43
|
+
mdi-alpha-x-circle-outline</v-icon
|
|
44
|
+
>
|
|
45
|
+
</v-col>
|
|
46
|
+
</v-row>
|
|
47
|
+
</v-container>
|
|
48
|
+
<v-row class="justify-center">
|
|
49
|
+
<div
|
|
50
|
+
v-for="(
|
|
51
|
+
strike, strikeIndex
|
|
52
|
+
) in sevenStrikesCounter"
|
|
53
|
+
:key="strikeIndex"
|
|
54
|
+
>
|
|
55
|
+
<div
|
|
56
|
+
v-if="strike.strike === false"
|
|
57
|
+
:ref="'strike' + strikeIndex"
|
|
58
|
+
class="strikeArea ml-1 mr-1 d-flex justify-center align-center"
|
|
59
|
+
maxlength="1"
|
|
60
|
+
></div>
|
|
61
|
+
<div
|
|
62
|
+
class="strike"
|
|
63
|
+
v-if="strike.strike === true"
|
|
64
|
+
>
|
|
65
|
+
X
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
</v-row>
|
|
69
|
+
<v-row
|
|
70
|
+
class="justify-center mt-12"
|
|
71
|
+
v-if="word.splitWord"
|
|
72
|
+
>
|
|
73
|
+
<div
|
|
74
|
+
v-for="(letter, splitIndex) in word.splitWord"
|
|
75
|
+
:key="splitIndex"
|
|
76
|
+
>
|
|
77
|
+
<div
|
|
78
|
+
:ref="'input' + splitIndex"
|
|
79
|
+
class="textArea ml-1 mr-1"
|
|
80
|
+
maxlength="1"
|
|
81
|
+
>
|
|
82
|
+
<div v-if="letter.show === true">
|
|
83
|
+
{{ letter.letter }}
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</v-row>
|
|
88
|
+
<div>
|
|
89
|
+
<keyboard
|
|
90
|
+
v-if="!showFeedback"
|
|
91
|
+
:key="index"
|
|
92
|
+
:keyboardClass="keyBoardClass + index"
|
|
93
|
+
@onChange="onChange"
|
|
94
|
+
@onKeyPress="onKeyPress"
|
|
95
|
+
:input="input"
|
|
96
|
+
/>
|
|
97
|
+
</div>
|
|
98
|
+
<v-row class="justify-center mt-12" v-if="showFeedback">
|
|
99
|
+
<v-btn
|
|
100
|
+
color="primary ml-4"
|
|
101
|
+
@click="onRevealAnswer"
|
|
102
|
+
>{{
|
|
103
|
+
$t(
|
|
104
|
+
'plugin.games.components.content.blocks.seven_strikes.reveal'
|
|
105
|
+
)
|
|
106
|
+
}}</v-btn
|
|
107
|
+
>
|
|
108
|
+
<v-btn
|
|
109
|
+
color="primary ml-4"
|
|
110
|
+
@click="onSlideChanged(index)"
|
|
111
|
+
>{{
|
|
112
|
+
$t(
|
|
113
|
+
'plugin.games.components.content.blocks.seven_strikes.again'
|
|
114
|
+
)
|
|
115
|
+
}}</v-btn
|
|
116
|
+
>
|
|
117
|
+
<v-btn
|
|
118
|
+
@click="onChangeSlide(index + 1)"
|
|
119
|
+
color="primary ml-4"
|
|
120
|
+
>{{
|
|
121
|
+
$t(
|
|
122
|
+
'plugin.games.components.content.blocks.seven_strikes.next'
|
|
123
|
+
)
|
|
124
|
+
}}</v-btn
|
|
125
|
+
>
|
|
126
|
+
</v-row>
|
|
127
|
+
</v-carousel-item>
|
|
128
|
+
</v-carousel>
|
|
129
|
+
</template>
|
|
130
|
+
</v-col>
|
|
131
|
+
</div>
|
|
132
|
+
</template>
|
|
133
|
+
|
|
134
|
+
<script>
|
|
135
|
+
import _ from 'lodash'
|
|
136
|
+
import draggable from 'vuedraggable'
|
|
137
|
+
import keyboard from './keyboard.vue'
|
|
138
|
+
import CrudTable from '../../CrudTable'
|
|
139
|
+
import BaseContentBlock from '~/components/Content/Blocks/BaseContentBlock'
|
|
140
|
+
|
|
141
|
+
export default {
|
|
142
|
+
name: 'SevenStrikesGame',
|
|
143
|
+
components: { CrudTable, draggable, keyboard },
|
|
144
|
+
extends: BaseContentBlock,
|
|
145
|
+
beforeMount() {
|
|
146
|
+
if (_.isEmpty(this.block)) {
|
|
147
|
+
this.block = {}
|
|
148
|
+
}
|
|
149
|
+
if (_.isEmpty(this.block.metadata)) {
|
|
150
|
+
this.block.metadata = {}
|
|
151
|
+
}
|
|
152
|
+
if (_.isEmpty(this.block.metadata.config)) {
|
|
153
|
+
this.block.metadata.config = {}
|
|
154
|
+
}
|
|
155
|
+
if (_.isEmpty(this.block.metadata.config.words)) {
|
|
156
|
+
this.block.metadata.config.words = []
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
data() {
|
|
160
|
+
return {
|
|
161
|
+
feedback: '',
|
|
162
|
+
feedbackStatus: '',
|
|
163
|
+
showFeedback: false,
|
|
164
|
+
input: '',
|
|
165
|
+
sevenStrikesCounter: [
|
|
166
|
+
{ strike: false },
|
|
167
|
+
{ strike: false },
|
|
168
|
+
{ strike: false },
|
|
169
|
+
{ strike: false },
|
|
170
|
+
{ strike: false },
|
|
171
|
+
{ strike: false },
|
|
172
|
+
{ strike: false },
|
|
173
|
+
],
|
|
174
|
+
keyBoardClass: 'simple-keyboard',
|
|
175
|
+
onSlide: 0,
|
|
176
|
+
onStrike: 0,
|
|
177
|
+
carouselIndex: 0,
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
mounted() {},
|
|
181
|
+
methods: {
|
|
182
|
+
onChangeSlide(newIndex) {
|
|
183
|
+
if (newIndex >= this.block.metadata.config.words.length) {
|
|
184
|
+
newIndex = 0
|
|
185
|
+
}
|
|
186
|
+
this.carouselIndex = newIndex
|
|
187
|
+
this.onSlideChanged(newIndex)
|
|
188
|
+
},
|
|
189
|
+
onChange(input) {
|
|
190
|
+
this.input = input
|
|
191
|
+
},
|
|
192
|
+
onKeyPress(letter) {
|
|
193
|
+
// can't play when editing
|
|
194
|
+
if (this.render) {
|
|
195
|
+
// to lowercase
|
|
196
|
+
letter = letter.toLowerCase()
|
|
197
|
+
// check if word value contains input letter
|
|
198
|
+
const doesContain =
|
|
199
|
+
this.block.metadata.config.words[
|
|
200
|
+
this.onSlide
|
|
201
|
+
].value.includes(letter)
|
|
202
|
+
if (doesContain) {
|
|
203
|
+
// loop over to show letters in case there are multiple of the same
|
|
204
|
+
this.block.metadata.config.words[
|
|
205
|
+
this.onSlide
|
|
206
|
+
].splitWord.forEach((character) => {
|
|
207
|
+
if (character.letter === letter) {
|
|
208
|
+
character.show = true
|
|
209
|
+
}
|
|
210
|
+
})
|
|
211
|
+
} else {
|
|
212
|
+
// checks if the user is already out of strikes
|
|
213
|
+
if (this.onStrike <= 6) {
|
|
214
|
+
this.sevenStrikesCounter[this.onStrike].strike = true
|
|
215
|
+
this.onStrike = this.onStrike + 1
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
const isComplete = this.checkIfComplete()
|
|
219
|
+
const checkStrikes = this.checkStrikes()
|
|
220
|
+
if (isComplete) {
|
|
221
|
+
this.thatIsCorrect()
|
|
222
|
+
}
|
|
223
|
+
if (checkStrikes) {
|
|
224
|
+
this.thatIsIncorrect()
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
checkIfComplete() {
|
|
229
|
+
// checks to see if the user guessed all the letters correctly
|
|
230
|
+
let finished = true
|
|
231
|
+
this.block.metadata.config.words[this.onSlide].splitWord.forEach(
|
|
232
|
+
(element) => {
|
|
233
|
+
if (element.show === false) {
|
|
234
|
+
finished = false
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
)
|
|
238
|
+
return finished
|
|
239
|
+
},
|
|
240
|
+
checkStrikes() {
|
|
241
|
+
// checks to see if user has exhausted strikes
|
|
242
|
+
let outOfStrikes = true
|
|
243
|
+
this.sevenStrikesCounter.forEach((element) => {
|
|
244
|
+
if (element.strike === false) {
|
|
245
|
+
outOfStrikes = false
|
|
246
|
+
}
|
|
247
|
+
})
|
|
248
|
+
return outOfStrikes
|
|
249
|
+
},
|
|
250
|
+
thatIsIncorrect() {
|
|
251
|
+
this.showFeedback = true
|
|
252
|
+
// updates class
|
|
253
|
+
this.feedbackStatus = 'error'
|
|
254
|
+
// gets custom or standard feedback
|
|
255
|
+
if (
|
|
256
|
+
!_.isEmpty(this.block.metadata.config.feedback_incorrect) &&
|
|
257
|
+
this.block.metadata.config.feedback_incorrect !== ''
|
|
258
|
+
) {
|
|
259
|
+
this.feedback = this.block.metadata.config.feedback_incorrect
|
|
260
|
+
} else {
|
|
261
|
+
this.feedback = this.$t(
|
|
262
|
+
'plugin.games.components.content.blocks.word_jumble.incorrect'
|
|
263
|
+
)
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
thatIsCorrect() {
|
|
267
|
+
this.showFeedback = true
|
|
268
|
+
this.feedbackStatus = 'success'
|
|
269
|
+
if (
|
|
270
|
+
!_.isEmpty(this.block.metadata.config.feedback_correct) &&
|
|
271
|
+
this.block.metadata.config.feedback_correct !== ''
|
|
272
|
+
) {
|
|
273
|
+
this.feedback = this.block.metadata.config.feedback_correct
|
|
274
|
+
} else {
|
|
275
|
+
this.feedback = this.$t(
|
|
276
|
+
'plugin.games.components.content.blocks.word_jumble.correct'
|
|
277
|
+
)
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
onHideFeedback() {
|
|
281
|
+
// fired from feedback x
|
|
282
|
+
this.showFeedback = false
|
|
283
|
+
this.onSlideChanged(this.onSlide)
|
|
284
|
+
},
|
|
285
|
+
onInputChange(input) {
|
|
286
|
+
// catches target input
|
|
287
|
+
this.input = input.target.value
|
|
288
|
+
},
|
|
289
|
+
onSlideChanged(event) {
|
|
290
|
+
// this function is called when the slide is changed
|
|
291
|
+
// manually resetting is necessary due to fact that components do not remount
|
|
292
|
+
// event hold slide index
|
|
293
|
+
this.onSlide = event
|
|
294
|
+
// hides feedback if showing
|
|
295
|
+
this.showFeedback = false
|
|
296
|
+
this.feedbackStatus = ''
|
|
297
|
+
this.onStrike = 0
|
|
298
|
+
this.feedback = this.$t(
|
|
299
|
+
'plugin.games.components.content.blocks.word_jumble.feedback'
|
|
300
|
+
)
|
|
301
|
+
// resets strikes
|
|
302
|
+
this.sevenStrikesCounter.forEach((element) => {
|
|
303
|
+
element.strike = false
|
|
304
|
+
})
|
|
305
|
+
if (
|
|
306
|
+
this.block.metadata.config.words[this.onSlide].splitWord &&
|
|
307
|
+
this.block.metadata.config.words[this.onSlide].splitWord
|
|
308
|
+
.length > 0
|
|
309
|
+
) {
|
|
310
|
+
// rehides the displayed correct letters
|
|
311
|
+
this.block.metadata.config.words[
|
|
312
|
+
this.onSlide
|
|
313
|
+
].splitWord.forEach((word) => {
|
|
314
|
+
if (word.show) {
|
|
315
|
+
word.show = false
|
|
316
|
+
}
|
|
317
|
+
})
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
onRevealAnswer() {
|
|
321
|
+
this.block.metadata.config.words[this.onSlide].splitWord.forEach(
|
|
322
|
+
(word) => {
|
|
323
|
+
word.show = true
|
|
324
|
+
}
|
|
325
|
+
)
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
}
|
|
329
|
+
</script>
|
|
330
|
+
|
|
331
|
+
<style scoped>
|
|
332
|
+
.outline {
|
|
333
|
+
border: 2px solid black;
|
|
334
|
+
border-radius: 10px;
|
|
335
|
+
}
|
|
336
|
+
.clueAndJumble {
|
|
337
|
+
font-size: 20px;
|
|
338
|
+
}
|
|
339
|
+
.spanBold {
|
|
340
|
+
font-weight: 900;
|
|
341
|
+
}
|
|
342
|
+
.error {
|
|
343
|
+
border: dashed 2px #dc3d1a;
|
|
344
|
+
background-color: #fff1f1;
|
|
345
|
+
}
|
|
346
|
+
.success {
|
|
347
|
+
border: dashed 2px #76b778;
|
|
348
|
+
background-color: #f1fff3;
|
|
349
|
+
}
|
|
350
|
+
.textArea {
|
|
351
|
+
width: 20px;
|
|
352
|
+
height: 20px;
|
|
353
|
+
border-bottom: 2px solid black;
|
|
354
|
+
display: flex;
|
|
355
|
+
justify-content: center;
|
|
356
|
+
align-items: center;
|
|
357
|
+
}
|
|
358
|
+
.strikeArea {
|
|
359
|
+
width: 40px;
|
|
360
|
+
height: 40px;
|
|
361
|
+
border: 2px solid black;
|
|
362
|
+
}
|
|
363
|
+
.strike {
|
|
364
|
+
color: #dc3d1a;
|
|
365
|
+
font-size: 40px;
|
|
366
|
+
margin: 10px;
|
|
367
|
+
}
|
|
368
|
+
</style>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="keyboardClass"></div>
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script>
|
|
6
|
+
import Keyboard from 'simple-keyboard'
|
|
7
|
+
import 'simple-keyboard/build/css/index.css'
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
name: 'SimpleKeyboard',
|
|
11
|
+
props: {
|
|
12
|
+
keyboardClass: {
|
|
13
|
+
default: 'simple-keyboard',
|
|
14
|
+
type: String,
|
|
15
|
+
},
|
|
16
|
+
input: {
|
|
17
|
+
type: String,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
data: () => ({
|
|
21
|
+
keyboard: null,
|
|
22
|
+
}),
|
|
23
|
+
mounted() {
|
|
24
|
+
this.keyboard = new Keyboard(this.keyboardClass, {
|
|
25
|
+
layout: {
|
|
26
|
+
default: [
|
|
27
|
+
'q w e r t y u i o p',
|
|
28
|
+
'a s d f g h j k l',
|
|
29
|
+
'z x c v b n m',
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
onChange: this.onChange,
|
|
33
|
+
onKeyPress: this.onKeyPress,
|
|
34
|
+
})
|
|
35
|
+
},
|
|
36
|
+
methods: {
|
|
37
|
+
onChange(input) {
|
|
38
|
+
this.$emit('onChange', input)
|
|
39
|
+
},
|
|
40
|
+
onKeyPress(button) {
|
|
41
|
+
this.$emit('onKeyPress', button)
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* If you want to handle the shift and caps lock buttons
|
|
45
|
+
*/
|
|
46
|
+
if (button === '{shift}' || button === '{lock}') this.handleShift()
|
|
47
|
+
},
|
|
48
|
+
handleShift() {
|
|
49
|
+
let currentLayout = this.keyboard.options.layoutName
|
|
50
|
+
let shiftToggle = currentLayout === 'default' ? 'shift' : 'default'
|
|
51
|
+
|
|
52
|
+
this.keyboard.setOptions({
|
|
53
|
+
layoutName: shiftToggle,
|
|
54
|
+
})
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
watch: {
|
|
58
|
+
input(input) {
|
|
59
|
+
this.keyboard.setInput(input)
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
66
|
+
<style scoped>
|
|
67
|
+
.hg-theme-default {
|
|
68
|
+
padding: 55px;
|
|
69
|
+
margin-top: 25px;
|
|
70
|
+
}
|
|
71
|
+
</style>
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
class="textArea ml-1 mr-1"
|
|
10
10
|
maxlength="1"
|
|
11
11
|
@input="onInput($event, index)"
|
|
12
|
-
v-on:keydown="onSpaceHandler($event)"
|
|
13
12
|
></v-text-field>
|
|
14
13
|
</div>
|
|
15
14
|
</v-row>
|
|
@@ -43,8 +42,8 @@ export default {
|
|
|
43
42
|
handler(newValue) {
|
|
44
43
|
// removes students answer from input if they got it correct
|
|
45
44
|
this.splitUpWord()
|
|
46
|
-
}
|
|
47
|
-
}
|
|
45
|
+
},
|
|
46
|
+
},
|
|
48
47
|
},
|
|
49
48
|
data() {
|
|
50
49
|
return {
|
|
@@ -71,13 +70,6 @@ export default {
|
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
72
|
},
|
|
74
|
-
onSpaceHandler(event) {
|
|
75
|
-
// prevents empty space from being entered
|
|
76
|
-
if (event.keyCode === 32) {
|
|
77
|
-
event.preventDefault()
|
|
78
|
-
return false
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
73
|
onInput(event, index) {
|
|
82
74
|
// handles focusing on next element after student enters a letter
|
|
83
75
|
if (!_.isEmpty(event) && this.$refs['input' + (index + 1)]) {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
v-for="(word, index) in block.metadata.config.words"
|
|
20
20
|
:key="index"
|
|
21
21
|
>
|
|
22
|
-
<v-row class="d-flex justify-center
|
|
22
|
+
<v-row class="d-flex justify-center ma-2">
|
|
23
23
|
<p class="pa-3 mb-0 clueAndJumble">
|
|
24
24
|
<span class="spanBold"
|
|
25
25
|
>{{
|
|
@@ -36,15 +36,22 @@
|
|
|
36
36
|
{{ shuffle(word.value) }}
|
|
37
37
|
</p>
|
|
38
38
|
</v-row>
|
|
39
|
-
<v-container
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
>
|
|
39
|
+
<v-container
|
|
40
|
+
v-if="showFeedback"
|
|
41
|
+
:key="'feedback'"
|
|
42
|
+
:class="feedbackStatus"
|
|
43
|
+
>
|
|
44
|
+
<v-row class="d-flex" align="center">
|
|
45
|
+
<v-col cols="4"></v-col>
|
|
46
|
+
<v-col cols="4" class="d-flex justify-center">
|
|
47
|
+
<p class="">{{ feedback }}</p>
|
|
48
|
+
</v-col>
|
|
49
|
+
<v-col cols="4" class="d-flex justify-end">
|
|
50
|
+
<v-icon @click="onHideFeedback">
|
|
51
|
+
mdi-alpha-x-circle-outline</v-icon
|
|
52
|
+
>
|
|
53
|
+
</v-col>
|
|
46
54
|
</v-row>
|
|
47
|
-
<br />
|
|
48
55
|
</v-container>
|
|
49
56
|
<v-row class="justify-center mt-4">
|
|
50
57
|
<Jumble
|
|
@@ -124,6 +131,7 @@ export default {
|
|
|
124
131
|
'plugin.games.components.content.blocks.word_jumble.feedback'
|
|
125
132
|
),
|
|
126
133
|
showAnswer: false,
|
|
134
|
+
showFeedback: false,
|
|
127
135
|
resetValue: false,
|
|
128
136
|
studentResponse: '',
|
|
129
137
|
feedbackStatus: '',
|
|
@@ -166,8 +174,12 @@ export default {
|
|
|
166
174
|
// reveal prop changed to true to show answer
|
|
167
175
|
this.showAnswer = true
|
|
168
176
|
},
|
|
177
|
+
onHideFeedback() {
|
|
178
|
+
this.showFeedback = false
|
|
179
|
+
},
|
|
169
180
|
onCheckAnswer(word) {
|
|
170
181
|
this.studentResponse = this.studentResponse.toLowerCase()
|
|
182
|
+
this.showFeedback = true
|
|
171
183
|
const answer = word.value.toLowerCase()
|
|
172
184
|
if (this.studentResponse === answer) {
|
|
173
185
|
// updates class
|
|
@@ -202,7 +214,7 @@ export default {
|
|
|
202
214
|
},
|
|
203
215
|
onSlideChanged() {
|
|
204
216
|
// this function is called when the slide is changed
|
|
205
|
-
// reset the game each time this occurs via props due to fact
|
|
217
|
+
// reset the game each time this occurs via props due to fact
|
|
206
218
|
// that components do not remount on slides each time the slide is revisited
|
|
207
219
|
// updates class
|
|
208
220
|
this.feedbackStatus = ''
|