[Unsupported] [Userscript] WaniKani Review Audio Tweak (reupload/fixed)

2019-10-03: I will no longer be investigating issues in this script when something breaks. If someone else provides a fix when a bug occurs I will still update the script in greasyfork.


The original script by Takuya Kobayashi recently broke since WaniKani changed the URL for the audio. I didn’t see any forum topic that was officially supporting this script, so I made a copy that uses the new URL.

Original description of the script:

Allow audio to be played after review meaning questions, when reading has been previously answered correctly. Also includes setting for enabling autoplay when answer is incorrect (default: off).

New version of the script.
https://greasyfork.org/en/scripts/34861-wanikani-review-audio-tweak-2

5 Likes

I just updated the script to handle the new audio.

CC: @Makise_Kurisu


@purajunyakara, regarding the change, the diff in greasyfork will show some additional cleanup I made, but the actual functional change is on lines 43-50 of the new version.

3 Likes

Thank you so much! It works perfectly and I’m happy to be back to my usual review routine :yum:

I think @Kumirei might also be interested in the updated script, based on his post in the other thread.

2 Likes

Yep. I set this thread to watching when the script broke

2 Likes

I didn’t know you used the script too. Cool!

2 Likes

Thanks for the tip! Update complete. I still can’t get it to do exactly what I want, tho. See note in userscript code if interested.
https://greasyfork.org/en/scripts/377361-wanikani-review-audio-tweak-3

The problem is that you’re using let in the commented out code. let is used for defining new variables, but the variable was already passed in to the function. So you want to just assign it without the let, like this:

if (questionType === "meaning") {
	audioAutoplay = false;
}

Slightly more technical explanation

To go into slightly more detail, the code before was using var to declare variables. var is the old version of assigning variables in JavaScript, and does this quirky thing called “hoisting” (which you can look up if you’re interested). let on the other hand follows an approach more similar to most programming languages, called block scoping. What that means is, a variable declared within a block (e.g. function, loop, condition) using let will only exist within that block. So with your current code, you are actually creating a new variable called audioAutoplay within the if block (effectively hiding the one passed into the function) instead of actually overwriting the one passed into the function with a new value.

2 Likes

Sweet, my man seanblue is on the case.

Thanks for detailed heads-up! What you say about block scoping makes total sense. Actually, tho, this is sort of an unfortunate red herring; I only added the let (not knowing that it would result in a more restrictive scope) as a desperate flail after many other attempts. Even if the let is not there (I’ve updated again), it still doesn’t work as hoped.

Specifically, the problem seems to lie with the parameter audioAutoplay. On the one hand, it simply always comes in as false, regardless of the real setting. But even assuming that I manually override that to true, I don’t seem to be able to successfully use if statements to change it in response to other variables in order to then pass it in with the { autoplay } object so as to make it do something useful. I.e., total fail.

I’m a Python programmer, not at all skilled in Javascript, so I feel like I’m stabbing around in the dark here, not really understanding why things don’t behave as expected, nor how to get more information. If you want to point me toward where to learn more, I’d be grateful.

I debugged through my version and also always saw false passed in for audioAutoplay. But my version of the script seems to work. I didn’t originally build this script, so I never did a thorough debugging through WaniKani’s code to understand how all this works. Now I’m honestly confused too, and I’m not sure how this works at all. :sweat_smile:

There is also a global variable called audioAutoplay which is passed into this additionalContent.audio function we’re overriding, so maybe that’s relevant somehow. But if it is, I’m not sure why it would be false locally in additionalContent.audio since it’s true globally when the autoplay setting is on.

1 Like

Right, that’s exactly the confusion I have too, which makes me feel more sane. Well, so, if I don’t improve this particular script any further, that’s basically ok with me.

But more generally, do you actually know HOW to debug through WaniKani code? Where would you start? I know how to inspect page source, and I know vaguely of the developer console — and the Open Framework looks like a fun thing to work with — but it’s unclear to me how to build a general picture of how many moving parts there are and how they work together.

There’s a button in the Chrome console (Source tab) to de-minify the code once you’ve opened it, so it’s at least somewhat readable. Then I usually search for HTML classes/ids that could be used or things like $.jStorage.get, which is how they maintain state (as you can see in this script). It’s very trial and error. A good way to start is by looking through existing scripts, like this one and [Userscript] WaniKani Prioritize Overdue Reviews (NEW reorder script).

Ok, cool stuff, thanks so much for sharing. Every little tip helps.

@seanblue Unfortunately, your script seems to have issues with the new audio update. It still works but when it’s active, it plays either male or female audio to each vocabulary item, “ignoring” the new option in Wanikani settings to select only male or only female audio.

To clarify, the choice of male/female audio doesn’t seem random, as even when I kept reloading to test this, I always got the same audio (either male or female) for the same word. Similarly, even when I kept pressing the audio button/J hotkey, the audio never changed.

Sorry to bother you with this but do you think it would be possible to make your script compatible with Wanikani’s new feature of picking one’s preferred audio?

2 Likes

This is looking like it’ll be a pain to fix. The script was working by duplicating code from WaniKani but changing one condition (to allow for audio to play after meaning review when reading had already been answered correctly). But in the latest update they basically rewrote that code from scratch. So I’d have to dig through their code and duplicate it again, risking it breaking the next time they update audio. At the very least, I want to wait a few days until the updates in this area have stabilized, but it kind of rubs me the wrong way to duplicate their code at all (I didn’t originally write the script, just maintained it since an audio URL changed).

Maybe our friendly WaniKani developer @viet would consider this feature as a first-class citizen. :slight_smile:

2 Likes

You could add a check for preferred audio (although still without regard to which reading you entered) to work around this.

+				if (audio.voice_actor_id == WaniKani.default_voice_actor_id) {
					$('<source></source>', {
						src: audio.url,
						type: audio.content_type
					}).appendTo(audioElem);
+				}
2 Likes

Thanks! This looks promising but I don’t know where to add this check in the code :sweat_smile:

Just look for the line $('<source></source>', {. I only added the first and last of the lines in my previous post (indicated by the +)

1 Like

This fixed the problem! Thank you, I really appreciate your help.

1 Like

Thank you for the quick response! Digging through the code like that really sounds like a hassle, especially since future updates might break things again. :slightly_frowning_face:

For now, maybe you could add the quick fix Kumirei posted above to your script? Seems like it has fixed the problem for me.

I’ll test it out tomorrow and do that if it works.

1 Like