Last active
August 14, 2019 18:26
-
-
Save flavluc/96fd41cca9457bd73909c3ef016ee3bc to your computer and use it in GitHub Desktop.
wanikani script to simulate anki with mobile support
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Wanikani Anki Mode (mobile support) | |
// @namespace zen | |
// @version 0.0.1 | |
// @description Anki mode for Wanikani with mobile support | |
// @author Zen | |
// @match https://www.wanikani.com/review/session* | |
// @match http://www.wanikani.com/review/session* | |
// @grant none | |
// @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html | |
// ==/UserScript== | |
const ANKI_MODE = "WANKIMODE"; | |
const CORRECT_ANS = { accurate: !0, passed: !0 }; | |
const WRONG_ANS = { accurate: !0, passed: 0 }; | |
const originalChecker = answerChecker.evaluate; | |
const originalValidator = answerChecker.isNonKanaPresent; | |
let answerShown = false; | |
let answerChecked = false; | |
function toggleAnkiMode() { | |
if (localStorage.getItem(ANKI_MODE) === "true") { | |
$("#anki-toggle").text("Anki Off"); | |
$("#user-response").off("focus"); | |
$("#user-response").focus(); | |
$("#answer-form form button").attr("disabled", false); | |
toggleButtons(); | |
answerChecker.evaluate = originalChecker; | |
answerShown = false; | |
localStorage.setItem(ANKI_MODE, false); | |
} else { | |
$("#anki-toggle").text("Anki On"); | |
$("#user-response").on("focus", function() { | |
$("#user-response").blur(); | |
}); | |
$("#answer-form form button").attr("disabled", true); | |
toggleButtons({ show: true }); | |
localStorage.setItem(ANKI_MODE, true); | |
} | |
} | |
function showAnswer() { | |
if (!answerShown) { | |
const currentItem = $.jStorage.get("currentItem"); | |
if ($.jStorage.get("questionType") === "meaning") { | |
let ans = currentItem.en.join(", "); | |
if (currentItem.syn.length) { | |
ans += " (" + currentItem.syn.join(", ") + ")"; | |
} | |
$("#user-response").val(ans); | |
} else { | |
let i = 0; | |
let ans = ""; | |
if (currentItem.voc) { | |
for (i = 0; i < currentItem.kana.length - 1; i++) { | |
ans += currentItem.kana[i] + ", "; | |
} | |
ans += currentItem.kana[currentItem.kana.length - 1]; | |
} else if (currentItem.emph == "kunyomi") { | |
for (i = 0; i < currentItem.kun.length - 1; i++) { | |
ans += currentItem.kun[i] + ", "; | |
} | |
ans += currentItem.kun[currentItem.kun.length - 1]; | |
} else if (currentItem.emph == "nanori") { | |
for (i = 0; i < currentItem.nanori.length - 1; i++) { | |
ans += currentItem.nanori[i] + ", "; | |
} | |
ans += currentItem.nanori[currentItem.nanori.length - 1]; | |
} else { | |
for (i = 0; i < currentItem.on.length - 1; i++) { | |
ans += currentItem.on[i] + ", "; | |
} | |
ans += currentItem.on[currentItem.on.length - 1]; | |
} | |
$("#user-response").val(ans); | |
} | |
answerShown = true; | |
toggleButtons({ correct: true, incorrect: true }); | |
} | |
} | |
function answer(evaluate) { | |
if (answerShown) { | |
if (!answerChecked) { | |
answerChecker.evaluate = () => evaluate; | |
answerChecker.isNonKanaPresent = () => false; | |
$("#answer-form form button").click(); | |
answerChecker.evaluate = originalChecker; | |
answerChecker.isNonKanaPresent = originalValidator; | |
answerChecked = true; | |
} else { | |
$("#answer-form form button").click(); | |
toggleButtons({ show: true }); | |
answerChecked = false; | |
answerShown = false; | |
} | |
} | |
} | |
function addStyle(css) { | |
$("footer") | |
.css("display", "flex") | |
.css("width", "100%") | |
.css("height", "55px"); | |
const head = document.getElementsByTagName("head")[0]; | |
if (head) { | |
const style = document.createElement("style"); | |
style.setAttribute("type", "text/css"); | |
style.textContent = css; | |
head.appendChild(style); | |
} | |
} | |
function createToggle(activated) { | |
$("<a />", { | |
id: "anki-toggle" | |
}) | |
.text(`Anki ${activated ? "On" : "Off"}`) | |
.on("click", toggleAnkiMode) | |
.addClass("anki-toggle") | |
.prependTo("#summary-button"); | |
} | |
function createButton({ id, texts, backgroundColor, onClick }) { | |
$("<div />", { | |
id | |
}) | |
.html(texts.reduce((a, i) => a + `<p class="p-text">${i}</p>`, "")) | |
.addClass("anki-button") | |
.css("background-color", backgroundColor) | |
.on("click", onClick) | |
.prependTo("footer") | |
.hide(); | |
} | |
function bindHotkeys() { | |
$(document).on("keydown.reviewScreen", function(event) { | |
if (event.keyCode === 27) { | |
return toggleAnkiMode(); | |
} | |
if ( | |
localStorage.getItem(ANKI_MODE) === "true" && | |
[13, 32, 49, 50].includes(event.keyCode) | |
) { | |
switch (event.keyCode) { | |
case 32: | |
return showAnswer(); | |
case 49: | |
return answer(WRONG_ANS); | |
case 13: | |
case 50: | |
return answer(CORRECT_ANS); | |
} | |
} | |
}); | |
} | |
function toggleButtons({ show, correct, incorrect } = {}) { | |
$("#anki-show-button")[show ? "show" : "hide"](); | |
$("#anki-correct-button")[correct ? "show" : "hide"](); | |
$("#anki-incorrect-button")[incorrect ? "show" : "hide"](); | |
} | |
const css = ` | |
.p-text { | |
padding: 0; | |
margin: 0; | |
} | |
.anki-toggle { | |
cursor: pointer; | |
} | |
.anki-button { | |
display: flex; | |
flex-direction: column; | |
font-size: 0.8125em; | |
color: #FFFFFF; | |
cursor: pointer; | |
padding: 10px; | |
width: 100%; | |
align-items: center; | |
justify-content: center; | |
} | |
`; | |
function main() { | |
addStyle(css); | |
createToggle(localStorage.getItem(ANKI_MODE) === "true"); | |
createButton({ | |
id: "anki-show-button", | |
texts: ["Show answer", "(space)"], | |
backgroundColor: "#0277BD", | |
onClick: showAnswer | |
}); | |
createButton({ | |
id: "anki-correct-button", | |
texts: ["Know", "(2)"], | |
backgroundColor: "#2F7D32", | |
onClick: () => answer(CORRECT_ANS) | |
}); | |
createButton({ | |
id: "anki-incorrect-button", | |
texts: ["Don't know", "(1)"], | |
backgroundColor: "#C62827", | |
onClick: () => answer(WRONG_ANS) | |
}); | |
if (localStorage.getItem(ANKI_MODE) === "true") { | |
$("#answer-form form button").attr("disabled", true); | |
$("#user-response").on("focus", function() { | |
$("#user-response").blur(); | |
}); | |
} | |
toggleButtons({ | |
show: true | |
}); | |
bindHotkeys(); | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment