Skip to content

Commit

Permalink
add score saving
Browse files Browse the repository at this point in the history
Displays scores earned in exercises next to the exercise title in the index and exercise list. Ported from SethClydesdale/genki-study-resources#229
  • Loading branch information
SethClydesdale committed Dec 12, 2023
1 parent abb306c commit bf5115e
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 8 deletions.
37 changes: 36 additions & 1 deletion resources/css/stylesheet.css
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,42 @@ footer li:first-child:before { display:none; }
margin:0;
}

.menu-item-list {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
position:relative;
}

.result--perfect {
color: #F90;
font-weight: 600;
}

.result--good {
color: #080;
font-weight: 600;
}

.result--average {
color: #AA0;
font-weight: 600;
}

.result--low {
color: #F00;
font-weight: 600;
}

.exercise-results {
min-width:65px;
}

.exercise-results .fa {
font-size:16px;
}

#exercise-list .lesson-title {
color:#333;
font-size:15px;
Expand Down Expand Up @@ -1086,7 +1122,6 @@ footer li:first-child:before { display:none; }
text-overflow:ellipsis;
overflow:hidden;
display:block;
position:relative;
}

#exercise-list li a.active-lesson {
Expand Down
2 changes: 1 addition & 1 deletion resources/css/stylesheet.min.css

Large diffs are not rendered by default.

50 changes: 47 additions & 3 deletions resources/javascript/genki.js
Original file line number Diff line number Diff line change
Expand Up @@ -1373,6 +1373,21 @@
'</div>'+
'</div>';

// save results in local storage
if (Genki.active.exercise.length > 0 && !/appendix|study-tools/.test(Genki.active.exercise[0])) {
var lesson = Genki.active.exercise[0],
lessonsResults = JSON.parse(localStorage.TobiraResults);

if (!lessonsResults) lessonsResults = {};
lessonsResults[lesson] = Genki.stats.score;

localStorage.TobiraResults = JSON.stringify(lessonsResults);

// refresh the exercise list with the new results
Genki.create.removeExerciseList();
Genki.create.exerciseList();
}

// changes display over certain buttons
if (type == 'stroke') {
document.getElementById('toggle-stroke-numbers').style.display = '';
Expand Down Expand Up @@ -2143,6 +2158,16 @@
// add the "more exercises" buttons to the document
document.getElementById('quiz-timer').insertAdjacentHTML('afterend', more + '</div>');
},


// removes the exercise list when needed update without refreshing the page
removeExerciseList : function () {
var list = document.getElementById('exercise-list'),
toggle = document.getElementById('toggle-exercises');

if (list) list.parentNode.removeChild(list);
if (toggle) toggle.parentNode.removeChild(toggle);
},


// creates the exercise list
Expand All @@ -2151,7 +2176,7 @@
list =
'<nav id="exercise-list">'+
'<h3 class="main-title">Exercise List</h3>'+
'<button id="random-exercise" class="button" onclick="Genki.randomExercise();" title="Random Exericse"><i class="fa">&#xf074;</i></button>'+
'<button id="random-exercise" class="button" onclick="Genki.randomExercise();" title="Random Exercise"><i class="fa">&#xf074;</i></button>'+
'<div id="lessons-list"><h4 ' + attrs + '>ページリンク</h4><ul id="page-links">',
lesson = '\\.\\.\\/',
i = 0,
Expand All @@ -2168,6 +2193,11 @@
'kanji-review-wb' : '漢字ワークブック・復習漢字の練習',
'kanji-wb' : '漢字ワークブック'
};


if (storageOK && !localStorage.TobiraResults) {
localStorage.TobiraResults = JSON.stringify({});
}

// loop over all the exercises and place them into their respectice lesson group
for (; i < j; i++) {
Expand All @@ -2189,8 +2219,21 @@
list += '<li><h4 class="sub-lesson-title">' + groupTitles[group] + '</h4></li>';
}

// add the exercise link to the group
list += '<li><a href="' + (lesson == '\\.\\.\\/' ? linkData[0] : '../../../' + Genki.ed + '/' + linkData[0] + '/') + Genki.local + Genki.debug + '" ' + (linkData[2] ? 'data-page="Tobira' + /*(+linkData[0].replace(/lesson-(\d+).*//*, '$1') < 13 ? 'I' : 'II') +*/ (/grammar-wb/.test(linkData[0]) ? ' Grammar Power' : /kanji-wb|kanji-review-wb|kanji-vocab/.test(linkData[0]) ? ' Power Up Your Kanji' : '') + ': ' + linkData[2] + '"' : '') + ' title="' + linkData[1] + '">' + linkData[1] + '</a></li>';
// add the exercise link to the group and display results
var resultsStorage = JSON.parse(localStorage.TobiraResults),

lessonResult = resultsStorage ? parseInt(resultsStorage[linkData[0]]) : null,
resultSpans = {
perfect: '<span class="exercise-results result--perfect" title="Exercise score"><i class="fa">&#xf005;</i> ',
good: '<span class="exercise-results result--good" title="Exercise score"><i class="fa">&#xf00c;</i> ',
average: '<span class="exercise-results result--average" title="Exercise score"><i class="fa">&#xf10c;</i> ',
low: '<span class="exercise-results result--low" title="Exercise score"><i class="fa">&#xf00d;</i> ',
},

resultSpan = lessonResult == 100 ? resultSpans.perfect : lessonResult >= 70 ? resultSpans.good : lessonResult >= 50 ? resultSpans.average : resultSpans.low,
prevScore = lessonResult ? resultSpan + lessonResult +'%' +'</span>' : '';

list += '<li class="menu-item-list"><a href="' + (lesson == '\\.\\.\\/' ? linkData[0] : '../../../' + Genki.ed + '/' + linkData[0] + '/') + Genki.local + Genki.debug + '" ' + (linkData[2] ? 'data-page="Tobira' + /*(+linkData[0].replace(/lesson-(\d+).*//*, '$1') < 13 ? 'I' : 'II') +*/ (/grammar-wb/.test(linkData[0]) ? ' Grammar Power' : /kanji-wb|kanji-review-wb|kanji-vocab/.test(linkData[0]) ? ' Power Up Your Kanji' : '') + ': ' + linkData[2] + '"' : '') + ' title="' + linkData[1] + '">' + linkData[1] + '</a>'+ " "+ prevScore +'</li>';

}

Expand All @@ -2205,6 +2248,7 @@
// highlight the active exercise and scoll to it
active = document.querySelector('a[href*="' + Genki.active.exercise[0] + '"]');
active.className += ' active-lesson';
active = active.parentNode;

// jump to the active exercise
document.getElementById('lessons-list').scrollTop = active.offsetTop - (active.getBoundingClientRect().height + (window.matchMedia && matchMedia('(pointer:coarse)').matches ? 0 : 6));
Expand Down
2 changes: 1 addition & 1 deletion resources/javascript/genki.min.js

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions resources/javascript/head.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,12 @@
'<span class="label" title="Enable or disable pausing timer when you leave or hide the exercise page">Pause Timer Automatically:</span>'+
'<button id="settings-timer-auto-pause" class="button' + (timerAutoPause == 'true' ? '' : ' opt-off') + '" onclick="GenkiSettings.updateTimerAutoPause(this);">' + (timerAutoPause == 'true' ? 'ON' : 'OFF') + '</button>'+
'</li>'+

'<li>'+
'<span class="label" title="Save or load your exercise score data.\nThis data is stored locally in the browser, so it\'s highly recommended that you save your data periodically so you don\'t lose it.">Save/Load Exercise Score Data:</span>'+
'<a id="settings-save-exercise-data" class="button" download="Tobira Exercise Score Data" href="data:,' + (storageOK && localStorage.TobiraResults ? encodeURIComponent(localStorage.TobiraResults.replace(/\n/g, '\r\n')) : '') + '"><i class="fa">&#xf019;</i>Save</a>'+
'<button id="settings-load-exercise-data" class="button" onclick="this.nextSibling.click();"><i class="fa">&#xf093;</i>Load</button><input id="settings-load-data" type="file" accept=".txt,.json,.js" onchange="GenkiSettings.loadExerciseData(this);" style="visibility:hidden;position:absolute;">'+
'</li>'+
'</ul>',

buttonText : 'Close',
Expand All @@ -287,6 +293,28 @@
},


// loads exercise score data
loadExerciseData : function (input) {
var file = input.files[0],
reader = new FileReader();

reader.onload = function (e) {
if (/"3rd"\:|"2nd"\:/.test(e.target.result)) return alert('This exercise data is only for use with Genki Study Resources. Please select your Tobira Exercise Data file to load your scores.');

if (/"\:\d+/.test(e.target.result)) {
localStorage.TobiraResults = e.target.result;

alert('Exercise score data has been loaded successfully! Please reload the page to update your scores.');

} else {
alert('There was an error loading the exercise score data. Please try again or open a new issue on GitHub for help: https://github.com/SethClydesdale/tobira-study-resources/issues');
}
};

reader.readAsText(file, 'UTF-8');
},


// update button state for settings
updateButton : function (caller, callback) {
// switches button state to ON if it's off
Expand Down
2 changes: 1 addition & 1 deletion resources/javascript/head.min.js

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions resources/javascript/homepage.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,4 +309,19 @@
// Add arrows to each lesson title that will take the student back to the quick navigation
AddJumpArrowsTo('.lesson-title', 'quick-nav', 'Jump to Quick Navigation');


// # EXERCISE RESULTS #
// Displays exercise results next to each exercise
if (storageOK && localStorage.TobiraResults) {
var exResults = JSON.parse(localStorage.TobiraResults), k, a;

for (k in exResults) {
a = document.querySelector('a[href*="' + k + '"]');

if (a) {
a.parentNode.insertAdjacentHTML('beforeend', '&nbsp;<span class="exercise-results result--' + (exResults[k] == 100 ? 'perfect' : exResults[k] >= 70 ? 'good' : exResults[k] >= 50 ? 'average' : 'low') + '" title="Exercise score"><i class="fa">' + (exResults[k] == 100 ? '&#xf005;' : exResults[k] >= 70 ? '&#xf00c;' : exResults[k] >= 50 ? '&#xf10c;' : '&#xf00d;') + '</i> ' + exResults[k] + '%</span>');
}
}
}

}(window, document));
Loading

0 comments on commit bf5115e

Please sign in to comment.