Skip to content

Commit 1890f7e

Browse files
BrayanDSOmikehardy
authored andcommitted
fix: HTML type answer JS value changes
If the template has some kind of script that updates the value of the type answer <input>, the changes wouldn't be shown in the answer comparison unless the user typed something after the changes
1 parent b7271ad commit 1890f7e

File tree

3 files changed

+34
-17
lines changed

3 files changed

+34
-17
lines changed

AnkiDroid/src/main/assets/scripts/ankidroid.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,6 @@ globalThis.ankidroid.showAllHints = function () {
2222
document.querySelectorAll("a.hint").forEach(el => el.click());
2323
};
2424

25-
/**
26-
* @param {InputEvent} event - the oninput event of the type answer <input>
27-
*/
28-
globalThis.ankidroid.onTypeAnswerInput = function (event) {
29-
const encodedValue = encodeURIComponent(event.target.value);
30-
window.location.href = `ankidroid://typeinput/${encodedValue}`;
31-
};
32-
3325
/**
3426
* @param {KeyboardEvent} event - the onkeydown event of the type answer <input>
3527
*/

AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/ReviewerFragment.kt

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ import androidx.core.view.WindowInsetsControllerCompat
4848
import androidx.core.view.isVisible
4949
import androidx.core.view.updateLayoutParams
5050
import androidx.core.view.updatePadding
51-
import androidx.core.widget.addTextChangedListener
5251
import androidx.fragment.app.FragmentContainerView
5352
import androidx.fragment.app.commit
5453
import androidx.fragment.app.viewModels
@@ -288,7 +287,7 @@ class ReviewerFragment :
288287
val typeAnswerContainer = view.findViewById<MaterialCardView>(R.id.type_answer_container)
289288
val typeAnswerEditText =
290289
view.findViewById<TextInputEditText>(R.id.type_answer_edit_text).apply {
291-
setOnEditorActionListener { editTextView, actionId, _ ->
290+
setOnEditorActionListener { _, actionId, _ ->
292291
if (actionId == EditorInfo.IME_ACTION_DONE) {
293292
viewModel.onShowAnswer()
294293
return@setOnEditorActionListener true
@@ -303,11 +302,9 @@ class ReviewerFragment :
303302
insetsController.hide(WindowInsetsCompat.Type.ime())
304303
}
305304
}
306-
addTextChangedListener { editable ->
307-
viewModel.typedAnswer = editable?.toString() ?: ""
308-
}
309305
}
310306

307+
val isHtmlTypeAnswerEnabled = Prefs.isHtmlTypeAnswerEnabled
311308
lifecycleScope.launch {
312309
val autoFocusTypeAnswer = Prefs.autoFocusTypeAnswer
313310
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
@@ -317,7 +314,7 @@ class ReviewerFragment :
317314
return@collect
318315
}
319316

320-
if (Prefs.isHtmlTypeAnswerEnabled) {
317+
if (isHtmlTypeAnswerEnabled) {
321318
webView.requestFocus()
322319
webView.evaluateJavascript("document.getElementById('typeans').focus();", null)
323320
return@collect
@@ -341,6 +338,22 @@ class ReviewerFragment :
341338
viewModel.onCardUpdatedFlow.flowWithLifecycle(lifecycle).collectIn(lifecycleScope) {
342339
typeAnswerEditText.text = null
343340
}
341+
342+
viewModel.onTypedAnswerResultFlow
343+
.flowWithLifecycle(lifecycle)
344+
.collectIn(lifecycleScope) { request ->
345+
if (isHtmlTypeAnswerEnabled) {
346+
val script = """document.getElementById("typeans").value;"""
347+
webView.evaluateJavascript(script) { callback ->
348+
// the retuned string comes with surrounding `"`, so remove it once
349+
val typedAnswer = callback.removeSurrounding("\"")
350+
request.complete(typedAnswer)
351+
}
352+
} else {
353+
val typedAnswer = typeAnswerEditText.text.toString()
354+
request.complete(typedAnswer)
355+
}
356+
}
344357
}
345358

346359
/** Chooses the input type based on whether the expected answer is a number or text */
@@ -719,7 +732,6 @@ class ReviewerFragment :
719732
when (url.host) {
720733
"focusin" -> webviewHasFocus = true
721734
"focusout" -> webviewHasFocus = false
722-
"typeinput" -> url.path?.substring(1)?.let { viewModel.typedAnswer = it }
723735
"show-answer" -> viewModel.onShowAnswer()
724736
}
725737
true

AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/ReviewerViewModel.kt

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ import kotlinx.coroutines.Deferred
7373
import kotlinx.coroutines.delay
7474
import kotlinx.coroutines.flow.MutableSharedFlow
7575
import kotlinx.coroutines.flow.MutableStateFlow
76+
import kotlinx.coroutines.withTimeoutOrNull
7677
import org.intellij.lang.annotations.Language
7778
import timber.log.Timber
7879

@@ -100,6 +101,7 @@ class ReviewerViewModel(
100101
val redoLabelFlow = MutableStateFlow<String?>(null)
101102
val countsFlow = MutableStateFlow(Counts() to Counts.Queue.NEW)
102103
val typeAnswerFlow = MutableStateFlow<TypeAnswer?>(null)
104+
val onTypedAnswerResultFlow = MutableSharedFlow<CompletableDeferred<String>>()
103105
val onCardUpdatedFlow = MutableSharedFlow<Unit>()
104106
val destinationFlow = MutableSharedFlow<Destination>()
105107
val editNoteTagsFlow = MutableSharedFlow<NoteId>()
@@ -114,7 +116,7 @@ class ReviewerViewModel(
114116

115117
override val server: AnkiServer = AnkiServer(this, StudyScreenRepository.getServerPort()).also { it.start() }
116118
private val stateMutationKey = TimeManager.time.intTimeMS().toString()
117-
var typedAnswer = ""
119+
private var typedAnswer = ""
118120

119121
private val autoAdvance = AutoAdvance(this)
120122
private val isHtmlTypeAnswerEnabled = Prefs.isHtmlTypeAnswerEnabled
@@ -189,6 +191,17 @@ class ReviewerViewModel(
189191
while (!statesMutated) {
190192
delay(50)
191193
}
194+
195+
val typedAnswerResult = CompletableDeferred<String>()
196+
if (typeAnswerFlow.value != null) {
197+
onTypedAnswerResultFlow.emit(typedAnswerResult)
198+
} else {
199+
typedAnswerResult.complete("")
200+
}
201+
typedAnswer = withTimeoutOrNull(1000L) {
202+
typedAnswerResult.await()
203+
} ?: ""
204+
192205
updateNextTimes()
193206
showAnswer()
194207
loadAndPlayMedia(CardSide.ANSWER)
@@ -577,7 +590,7 @@ class ReviewerViewModel(
577590
val repl =
578591
"""
579592
<center>
580-
<input type="text" id="typeans" oninput="ankidroid.onTypeAnswerInput(event);" onkeydown="ankidroid.onTypeAnswerKeyDown(event);"
593+
<input type="text" id="typeans" onkeydown="ankidroid.onTypeAnswerKeyDown(event);"
581594
style="font-family: '${typeAnswer.font}'; font-size: ${typeAnswer.fontSize}px;">
582595
</center>
583596
""".trimIndent()

0 commit comments

Comments
 (0)