Skip to content

Commit

Permalink
allow blank input
Browse files Browse the repository at this point in the history
  • Loading branch information
Vishwajith-Shettigar committed Jan 20, 2024
1 parent bb69b22 commit 6bb3dee
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.oppia.android.app.player.state.itemviewmodel

import androidx.annotation.StringRes
import androidx.databinding.Observable
import androidx.databinding.ObservableField
import org.oppia.android.R
Expand All @@ -9,6 +10,7 @@ import org.oppia.android.app.model.Interaction
import org.oppia.android.app.model.InteractionObject
import org.oppia.android.app.model.UserAnswer
import org.oppia.android.app.model.WrittenTranslationContext
import org.oppia.android.app.player.state.answerhandling.AnswerErrorCategory
import org.oppia.android.app.player.state.answerhandling.InteractionAnswerErrorOrAvailabilityCheckReceiver
import org.oppia.android.app.player.state.answerhandling.InteractionAnswerHandler
import org.oppia.android.app.player.state.answerhandling.InteractionAnswerReceiver
Expand All @@ -17,6 +19,7 @@ import org.oppia.android.app.utility.DefaultRegionClickedEvent
import org.oppia.android.app.utility.NamedRegionClickedEvent
import org.oppia.android.app.utility.OnClickableAreaClickedListener
import org.oppia.android.app.utility.RegionClickedEvent
import org.oppia.android.util.math.FractionParser
import javax.inject.Inject

/** [StateItemViewModel] for image region selection. */
Expand All @@ -31,12 +34,16 @@ class ImageRegionSelectionInteractionViewModel private constructor(
) : StateItemViewModel(ViewType.IMAGE_REGION_SELECTION_INTERACTION),
InteractionAnswerHandler,
OnClickableAreaClickedListener {
private var pendingAnswerError: String? = null
var errorMessage = ObservableField<String>("")
private var isDefaultRegionClicked = false
var answerText: CharSequence = ""
val selectableRegions: List<ImageWithRegions.LabeledRegion> by lazy {
val schemaObject = interaction.customizationArgsMap["imageAndRegions"]
schemaObject?.customSchemaValue?.imageWithRegions?.labelRegionsList ?: listOf()
}

private val fractionParser = FractionParser()
val imagePath: String by lazy {
val schemaObject = interaction.customizationArgsMap["imageAndRegions"]
schemaObject?.customSchemaValue?.imageWithRegions?.imagePath ?: ""
Expand All @@ -49,25 +56,68 @@ class ImageRegionSelectionInteractionViewModel private constructor(
object : Observable.OnPropertyChangedCallback() {
override fun onPropertyChanged(sender: Observable, propertyId: Int) {
errorOrAvailabilityCheckReceiver.onPendingAnswerErrorOrAvailabilityCheck(
pendingAnswerError = null,
inputAnswerAvailable = answerText.isNotEmpty()
pendingAnswerError = pendingAnswerError,
inputAnswerAvailable = true
)
}
}
isAnswerAvailable.addOnPropertyChangedCallback(callback)
errorMessage.addOnPropertyChangedCallback(callback)

errorOrAvailabilityCheckReceiver.onPendingAnswerErrorOrAvailabilityCheck(
pendingAnswerError = null,
inputAnswerAvailable = true
)
}

override fun onClickableAreaTouched(region: RegionClickedEvent) {

when (region) {
is DefaultRegionClickedEvent -> {
answerText = ""
isAnswerAvailable.set(false)
isDefaultRegionClicked = true
}
is NamedRegionClickedEvent -> {
answerText = region.regionLabel
isAnswerAvailable.set(true)
}
}
checkPendingAnswerError(AnswerErrorCategory.REAL_TIME)
}

/** It checks the pending error for the current fraction input, and correspondingly updates the error string based on the specified error category. */
override fun checkPendingAnswerError(category: AnswerErrorCategory): String? {
when (category) {
AnswerErrorCategory.REAL_TIME -> {

if (answerText.isNotEmpty()) {
pendingAnswerError =
ImageRegionParsingUiError.createFromParsingError(
getSubmitTimeError(answerText.toString())
).getErrorMessageFromStringRes(resourceHandler)
} else {
pendingAnswerError =
ImageRegionParsingUiError.createFromParsingError(
ImageRegionParsingError.VALID
).getErrorMessageFromStringRes(resourceHandler)
}
}

AnswerErrorCategory.SUBMIT_TIME -> {
if (answerText.isNotEmpty() || isDefaultRegionClicked) {
pendingAnswerError = null
} else {
pendingAnswerError =
ImageRegionParsingUiError.createFromParsingError(
getSubmitTimeError(answerText.toString())
).getErrorMessageFromStringRes(resourceHandler)
}
}
}

errorMessage.set(pendingAnswerError)
return pendingAnswerError
}

override fun getPendingAnswer(): UserAnswer = UserAnswer.newBuilder().apply {
Expand All @@ -91,6 +141,51 @@ class ImageRegionSelectionInteractionViewModel private constructor(
.build()
}

fun getSubmitTimeError(text: String): ImageRegionParsingError {
if (text.isNullOrBlank()) {
return ImageRegionParsingError.EMPTY_INPUT
}
return ImageRegionParsingError.VALID
}

/** Represents errors that can occur when parsing region name. */
enum class ImageRegionParsingError {

/** Indicates that the considered string is a valid. */
VALID,

/** Indicates that the input text was empty. */
EMPTY_INPUT
}

enum class ImageRegionParsingUiError(@StringRes private var error: Int?) {
/** Corresponds to [ImageRegionParsingError.VALID]. */
VALID(error = null),

/** Corresponds to [ImageRegionParsingError.EMPTY_INPUT]. */
EMPTY_INPUT(error = R.string.image_error_empty_input);

/**
* Returns the string corresponding to this error's string resources, or null if there is none.
*/
fun getErrorMessageFromStringRes(resourceHandler: AppLanguageResourceHandler): String? =
error?.let(resourceHandler::getStringInLocale)

companion object {
/**
* Returns the [ImageRegionParsingUiError] corresponding to the specified [ImageRegionParsingError].
*/
fun createFromParsingError(parsingError: ImageRegionParsingError): ImageRegionParsingUiError {
return when (parsingError) {

ImageRegionParsingError.VALID -> VALID

ImageRegionParsingError.EMPTY_INPUT -> EMPTY_INPUT
}
}
}
}

/** Implementation of [StateItemViewModel.InteractionItemFactory] for this view model. */
class FactoryImpl @Inject constructor(
private val resourceHandler: AppLanguageResourceHandler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
app:onRegionClicked="@{(region) -> viewModel.onClickableAreaTouched(region)}"
app:overlayView="@{interactionContainerFrameLayout}" />


<View
android:id="@+id/default_selected_region"
android:layout_width="24dp"
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
<string name="state_end_exploration_button">Return To Topic</string>
<string name="previous_responses_header">Previous Responses (%s)</string>
<string name="image_interaction_answer_text">Clicks on %s</string>
<string name="image_error_empty_input">Select a image to continue.</string>
<string name="state_learn_again_button">Learn Again</string>
<string name="topic_download_text">(%s)</string>
<string name="see_more">See More</string>
Expand Down

0 comments on commit 6bb3dee

Please sign in to comment.