From 3274c450d31baefb6c3f053442901668ecc40c86 Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Wed, 7 Aug 2024 11:38:21 +0530 Subject: [PATCH 01/22] Drap and drop interaction retain input when devices configuration changes --- .../DragAndDropSortInteractionViewModel.kt | 66 +++++++++++++++++-- model/src/main/proto/exploration.proto | 2 + 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/DragAndDropSortInteractionViewModel.kt b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/DragAndDropSortInteractionViewModel.kt index aa205417099..cd4de7e302e 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/DragAndDropSortInteractionViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/DragAndDropSortInteractionViewModel.kt @@ -1,5 +1,6 @@ package org.oppia.android.app.player.state.itemviewmodel +import android.util.Log import androidx.annotation.StringRes import androidx.databinding.Observable import androidx.databinding.ObservableField @@ -48,7 +49,8 @@ class DragAndDropSortInteractionViewModel private constructor( val isSplitView: Boolean, private val writtenTranslationContext: WrittenTranslationContext, private val resourceHandler: AppLanguageResourceHandler, - private val translationController: TranslationController + private val translationController: TranslationController, + userAnswerState: UserAnswerState ) : StateItemViewModel(ViewType.DRAG_DROP_SORT_INTERACTION), InteractionAnswerHandler, OnItemDragListener, @@ -71,10 +73,18 @@ class DragAndDropSortInteractionViewModel private constructor( subtitledHtml.contentId to translatedHtml } + private var answerErrorCetegory: AnswerErrorCategory = AnswerErrorCategory.NO_ERROR + private val _originalChoiceItems: MutableList = - computeChoiceItems(contentIdHtmlMap, choiceSubtitledHtmls, this, resourceHandler) + computeOriginalChoiceItems(contentIdHtmlMap, choiceSubtitledHtmls, this, resourceHandler) - private val _choiceItems = _originalChoiceItems.toMutableList() + private val _choiceItems = computeSelectedChoiceItems( + contentIdHtmlMap, + choiceSubtitledHtmls, + this, + resourceHandler, + userAnswerState + ) val choiceItems: List = _choiceItems private var pendingAnswerError: String? = null @@ -99,6 +109,7 @@ class DragAndDropSortInteractionViewModel private constructor( pendingAnswerError = null, inputAnswerAvailable = true ) + checkPendingAnswerError(userAnswerState.answerErrorCategory) } override fun onItemDragged( @@ -160,6 +171,7 @@ class DragAndDropSortInteractionViewModel private constructor( * updates the error string based on the specified error category. */ override fun checkPendingAnswerError(category: AnswerErrorCategory): String? { + answerErrorCetegory = category pendingAnswerError = when (category) { AnswerErrorCategory.REAL_TIME -> null AnswerErrorCategory.SUBMIT_TIME -> @@ -232,9 +244,9 @@ class DragAndDropSortInteractionViewModel private constructor( } private fun getSubmitTimeError(): DragAndDropSortInteractionError { - return if (_originalChoiceItems == _choiceItems) + return if (_originalChoiceItems == _choiceItems) { DragAndDropSortInteractionError.EMPTY_INPUT - else + } else DragAndDropSortInteractionError.VALID } @@ -263,13 +275,30 @@ class DragAndDropSortInteractionViewModel private constructor( isSplitView, writtenTranslationContext, resourceHandler, - translationController + translationController, + userAnswerState ) } } + override fun getUserAnswerState(): UserAnswerState { + if (_choiceItems==_originalChoiceItems) { + return UserAnswerState.newBuilder().apply { + this.answerErrorCategory= answerErrorCetegory + }.build() + } + return UserAnswerState.newBuilder().apply { + val htmlContentIds = _choiceItems.map { it.htmlContent } + listOfSetsOfTranslatableHtmlContentIds = + ListOfSetsOfTranslatableHtmlContentIds.newBuilder().apply { + addAllContentIdLists(htmlContentIds) + }.build() + answerErrorCategory = answerErrorCetegory + }.build() + } + companion object { - private fun computeChoiceItems( + private fun computeOriginalChoiceItems( contentIdHtmlMap: Map, choiceStrings: List, dragAndDropSortInteractionViewModel: DragAndDropSortInteractionViewModel, @@ -293,4 +322,27 @@ class DragAndDropSortInteractionViewModel private constructor( }.toMutableList() } } + + private fun computeSelectedChoiceItems( + contentIdHtmlMap: Map, + choiceStrings: List, + dragAndDropSortInteractionViewModel: DragAndDropSortInteractionViewModel, + resourceHandler: AppLanguageResourceHandler, + userAnswerState: UserAnswerState + ): MutableList { + return if (userAnswerState.listOfSetsOfTranslatableHtmlContentIds.contentIdListsCount==0 ) { + _originalChoiceItems.toMutableList() + } else { + userAnswerState.listOfSetsOfTranslatableHtmlContentIds.contentIdListsList.mapIndexed { index, contentId -> + DragDropInteractionContentViewModel( + contentIdHtmlMap = contentIdHtmlMap, + htmlContent = contentId, + itemIndex = index, + listSize = choiceStrings.size, + dragAndDropSortInteractionViewModel = dragAndDropSortInteractionViewModel, + resourceHandler = resourceHandler + ) + }.toMutableList() + } + } } diff --git a/model/src/main/proto/exploration.proto b/model/src/main/proto/exploration.proto index b1ad61b51b4..2b3a3215370 100644 --- a/model/src/main/proto/exploration.proto +++ b/model/src/main/proto/exploration.proto @@ -438,6 +438,8 @@ message UserAnswerState { ItemSelectionAnswerState item_selection = 2; // Raw answer entered by the user in text-based interactions. string text_input_answer = 3; + // A user's selected list of set of html content ids in drag and drop interaction. + ListOfSetsOfTranslatableHtmlContentIds list_of_sets_of_translatable_html_content_ids = 4; } } From f73b5e77d594a44df38e8d4f21fa0c8724534c6c Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Wed, 7 Aug 2024 11:39:39 +0530 Subject: [PATCH 02/22] klint --- .../DragAndDropSortInteractionViewModel.kt | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/DragAndDropSortInteractionViewModel.kt b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/DragAndDropSortInteractionViewModel.kt index cd4de7e302e..11d87f4bed0 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/DragAndDropSortInteractionViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/DragAndDropSortInteractionViewModel.kt @@ -1,6 +1,5 @@ package org.oppia.android.app.player.state.itemviewmodel -import android.util.Log import androidx.annotation.StringRes import androidx.databinding.Observable import androidx.databinding.ObservableField @@ -282,9 +281,9 @@ class DragAndDropSortInteractionViewModel private constructor( } override fun getUserAnswerState(): UserAnswerState { - if (_choiceItems==_originalChoiceItems) { + if (_choiceItems == _originalChoiceItems) { return UserAnswerState.newBuilder().apply { - this.answerErrorCategory= answerErrorCetegory + this.answerErrorCategory = answerErrorCetegory }.build() } return UserAnswerState.newBuilder().apply { @@ -330,19 +329,20 @@ class DragAndDropSortInteractionViewModel private constructor( resourceHandler: AppLanguageResourceHandler, userAnswerState: UserAnswerState ): MutableList { - return if (userAnswerState.listOfSetsOfTranslatableHtmlContentIds.contentIdListsCount==0 ) { + return if (userAnswerState.listOfSetsOfTranslatableHtmlContentIds.contentIdListsCount == 0) { _originalChoiceItems.toMutableList() } else { - userAnswerState.listOfSetsOfTranslatableHtmlContentIds.contentIdListsList.mapIndexed { index, contentId -> - DragDropInteractionContentViewModel( - contentIdHtmlMap = contentIdHtmlMap, - htmlContent = contentId, - itemIndex = index, - listSize = choiceStrings.size, - dragAndDropSortInteractionViewModel = dragAndDropSortInteractionViewModel, - resourceHandler = resourceHandler - ) - }.toMutableList() + userAnswerState.listOfSetsOfTranslatableHtmlContentIds.contentIdListsList + .mapIndexed { index, contentId -> + DragDropInteractionContentViewModel( + contentIdHtmlMap = contentIdHtmlMap, + htmlContent = contentId, + itemIndex = index, + listSize = choiceStrings.size, + dragAndDropSortInteractionViewModel = dragAndDropSortInteractionViewModel, + resourceHandler = resourceHandler + ) + }.toMutableList() } } } From b42552a926023dad18adf79df40e4cbae7cb885b Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Fri, 9 Aug 2024 09:06:13 +0530 Subject: [PATCH 03/22] retain input in image selection interaction --- .../ImageRegionSelectionInteractionView.kt | 20 +++++- ...mageRegionSelectionInteractionViewModel.kt | 63 ++++++++++++++----- .../app/utility/ClickableAreasImage.kt | 37 ++++++++++- .../android/app/utility/RegionClickEvent.kt | 2 +- ...mage_region_selection_interaction_item.xml | 1 + model/src/main/proto/exploration.proto | 8 +++ 6 files changed, 112 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt b/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt index 53cb5fd3b1b..f632a972e70 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt @@ -1,13 +1,17 @@ package org.oppia.android.app.player.state import android.content.Context +import android.database.Observable import android.util.AttributeSet +import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.appcompat.widget.AppCompatImageView import androidx.core.view.forEachIndexed +import androidx.databinding.ObservableField import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager +import com.google.firebase.firestore.GeoPoint import org.oppia.android.app.model.ImageWithRegions import org.oppia.android.app.shim.ViewBindingShim import org.oppia.android.app.utility.ClickableAreasImage @@ -23,6 +27,8 @@ import org.oppia.android.util.parser.image.ImageDownloadUrlTemplate import org.oppia.android.util.parser.image.ImageLoader import org.oppia.android.util.parser.image.ImageViewTarget import javax.inject.Inject +import org.oppia.android.app.model.Point2d +import org.oppia.android.app.model.UserAnswerState /** * A custom [AppCompatImageView] with a list of [ImageWithRegions.LabeledRegion]s to work with @@ -52,6 +58,10 @@ class ImageRegionSelectionInteractionView @JvmOverloads constructor( private lateinit var imageUrl: String private lateinit var clickableAreas: List + private lateinit var userAnswerState: ObservableField + + + /** * Sets the URL for the image & initiates loading it. This is intended to be called via * data-binding. @@ -61,11 +71,17 @@ class ImageRegionSelectionInteractionView @JvmOverloads constructor( maybeInitializeClickableAreas() } + fun setUserAnswerState(userAnswerrState: ObservableField ) { + userAnswerState= userAnswerrState + } + fun setEntityId(entityId: String) { this.entityId = entityId maybeInitializeClickableAreas() } + + fun setClickableAreas(clickableAreas: List) { this.clickableAreas = clickableAreas // Resets the backgrounds for all regions if any have been loaded. This ensures the backgrounds @@ -121,9 +137,11 @@ class ImageRegionSelectionInteractionView @JvmOverloads constructor( onRegionClicked, bindingInterface, isAccessibilityEnabled = accessibilityService.isScreenReaderEnabled(), - clickableAreas + clickableAreas, + userAnswerState ) areasImage.addRegionViews() + areasImage.addDefaultImageSelection() performAttachment(areasImage) } } diff --git a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt index aa56b9548e9..ae80fc6f769 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt @@ -1,5 +1,6 @@ package org.oppia.android.app.player.state.itemviewmodel +import android.util.Log import androidx.annotation.StringRes import androidx.databinding.Observable import androidx.databinding.ObservableField @@ -21,6 +22,8 @@ import org.oppia.android.app.utility.NamedRegionClickedEvent import org.oppia.android.app.utility.OnClickableAreaClickedListener import org.oppia.android.app.utility.RegionClickedEvent import javax.inject.Inject +import org.oppia.android.app.model.ImageInteractionState +import org.oppia.android.app.model.Point2d /** [StateItemViewModel] for image region selection. */ class ImageRegionSelectionInteractionViewModel private constructor( @@ -30,7 +33,8 @@ class ImageRegionSelectionInteractionViewModel private constructor( private val errorOrAvailabilityCheckReceiver: InteractionAnswerErrorOrAvailabilityCheckReceiver, val isSplitView: Boolean, private val writtenTranslationContext: WrittenTranslationContext, - private val resourceHandler: AppLanguageResourceHandler + private val resourceHandler: AppLanguageResourceHandler, + userAnswerState: UserAnswerState ) : StateItemViewModel(ViewType.IMAGE_REGION_SELECTION_INTERACTION), InteractionAnswerHandler, OnClickableAreaClickedListener { @@ -38,11 +42,16 @@ class ImageRegionSelectionInteractionViewModel private constructor( var errorMessage = ObservableField("") private var isDefaultRegionClicked = false var answerText: CharSequence = "" + private var dafaultRegionCoordinates: Point2d? = null val selectableRegions: List by lazy { val schemaObject = interaction.customizationArgsMap["imageAndRegions"] schemaObject?.customSchemaValue?.imageWithRegions?.labelRegionsList ?: listOf() } + val observableUserAnswrerState = ObservableField(userAnswerState) + + private var answerErrorCetegory: AnswerErrorCategory = AnswerErrorCategory.NO_ERROR + val imagePath: String by lazy { val schemaObject = interaction.customizationArgsMap["imageAndRegions"] schemaObject?.customSchemaValue?.imageWithRegions?.imagePath ?: "" @@ -68,17 +77,23 @@ class ImageRegionSelectionInteractionViewModel private constructor( pendingAnswerError = null, inputAnswerAvailable = true ) + + checkPendingAnswerError(userAnswerState.answerErrorCategory) } override fun onClickableAreaTouched(region: RegionClickedEvent) { - when (region) { is DefaultRegionClickedEvent -> { + dafaultRegionCoordinates = Point2d.newBuilder().apply { + x = region.x + y = region.y + }.build() answerText = "" isAnswerAvailable.set(false) isDefaultRegionClicked = true } is NamedRegionClickedEvent -> { + dafaultRegionCoordinates = null answerText = region.regionLabel isAnswerAvailable.set(true) } @@ -88,6 +103,7 @@ class ImageRegionSelectionInteractionViewModel private constructor( /** It checks the pending error for the current image region input, and correspondingly updates the error string based on the specified error category. */ override fun checkPendingAnswerError(category: AnswerErrorCategory): String? { + answerErrorCetegory=category when (category) { AnswerErrorCategory.REAL_TIME -> { pendingAnswerError = null @@ -110,18 +126,36 @@ class ImageRegionSelectionInteractionViewModel private constructor( return pendingAnswerError } - override fun getPendingAnswer(): UserAnswer = UserAnswer.newBuilder().apply { - val answerTextString = answerText.toString() - answer = InteractionObject.newBuilder().apply { - clickOnImage = parseClickOnImage(answerTextString) + override fun getUserAnswerState(): UserAnswerState { + return UserAnswerState.newBuilder().apply { + if (answerText != "" || dafaultRegionCoordinates != null) { + this.imageInteractionState = ImageInteractionState.newBuilder().apply { + if (answerText != "") { + this.imageLabel = answerText.toString() + } else { + this.defaultRegionCoordinates = dafaultRegionCoordinates + } + }.build() + } + this.answerErrorCategory= answerErrorCetegory }.build() - plainAnswer = resourceHandler.getStringInLocaleWithWrapping( - R.string.image_interaction_answer_text, - answerTextString - ) - this.writtenTranslationContext = - this@ImageRegionSelectionInteractionViewModel.writtenTranslationContext - }.build() + } + + override fun getPendingAnswer(): UserAnswer { + observableUserAnswrerState.set(UserAnswerState.getDefaultInstance()) + return UserAnswer.newBuilder().apply { + val answerTextString = answerText.toString() + answer = InteractionObject.newBuilder().apply { + clickOnImage = parseClickOnImage(answerTextString) + }.build() + plainAnswer = resourceHandler.getStringInLocaleWithWrapping( + R.string.image_interaction_answer_text, + answerTextString + ) + this.writtenTranslationContext = + this@ImageRegionSelectionInteractionViewModel.writtenTranslationContext + }.build() + } private fun parseClickOnImage(answerTextString: String): ClickOnImage { val region = selectableRegions.find { it.label == answerTextString } @@ -204,7 +238,8 @@ class ImageRegionSelectionInteractionViewModel private constructor( answerErrorReceiver, isSplitView, writtenTranslationContext, - resourceHandler + resourceHandler, + userAnswerState ) } } diff --git a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt index 1a0081db7ee..d31b970c78c 100644 --- a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt +++ b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt @@ -1,6 +1,7 @@ package org.oppia.android.app.utility import android.graphics.RectF +import android.util.Log import android.view.MotionEvent import android.view.View import android.widget.FrameLayout @@ -8,11 +9,14 @@ import androidx.core.view.ViewCompat import androidx.core.view.children import androidx.core.view.forEachIndexed import androidx.core.view.isVisible +import androidx.databinding.ObservableField import org.oppia.android.R import org.oppia.android.app.model.ImageWithRegions.LabeledRegion import org.oppia.android.app.player.state.ImageRegionSelectionInteractionView import org.oppia.android.app.shim.ViewBindingShim import kotlin.math.roundToInt +import org.oppia.android.app.model.Point2d +import org.oppia.android.app.model.UserAnswerState /** Helper class to handle clicks on an image along with highlighting the selected region. */ class ClickableAreasImage( @@ -21,11 +25,28 @@ class ClickableAreasImage( private val listener: OnClickableAreaClickedListener, bindingInterface: ViewBindingShim, private val isAccessibilityEnabled: Boolean, - private val clickableAreas: List + private val clickableAreas: List, + userAnswerState: ObservableField ) { + private var label: String? = null + private var coordinates: Point2d? = null + private val defaultRegionView by lazy { bindingInterface.getDefaultRegion(parentView) } - init { imageView.initializeShowRegionTouchListener() } + init { + imageView.initializeShowRegionTouchListener() + + if (userAnswerState.get()!!.hasImageInteractionState()) { + if (userAnswerState.get()!!.imageInteractionState.imageLabel.isNotBlank()) { + label = userAnswerState.get()!!.imageInteractionState.imageLabel + } else { + coordinates = userAnswerState.get()!!.imageInteractionState.defaultRegionCoordinates + } + } else { + label = null + coordinates = null + } + } /** * Called when an image is clicked. @@ -41,7 +62,7 @@ class ClickableAreasImage( defaultRegionView.setBackgroundResource(R.drawable.selected_region_background) defaultRegionView.x = x defaultRegionView.y = y - listener.onClickableAreaTouched(DefaultRegionClickedEvent()) + listener.onClickableAreaTouched(DefaultRegionClickedEvent(x, y)) } } @@ -73,6 +94,13 @@ class ClickableAreasImage( return imageView.height - imageView.paddingTop - imageView.paddingBottom } + fun addDefaultImageSelection() { + if (coordinates != null) { + onPhotoTap(coordinates!!.x, coordinates!!.y) + coordinates = null + } + } + /** Add selectable regions to [FrameLayout]. */ fun addRegionViews() { // Remove all views other than the default region & selectable image. @@ -152,6 +180,9 @@ class ClickableAreasImage( } private fun View.initializeToggleRegionTouchListener(clickableArea: LabeledRegion) { + if (clickableArea.label.equals(label)) { + showOrHideRegion(this@initializeToggleRegionTouchListener, clickableArea) + } setOnTouchListener { view, event -> if (event.action == MotionEvent.ACTION_DOWN) { showOrHideRegion(this@initializeToggleRegionTouchListener, clickableArea) diff --git a/app/src/main/java/org/oppia/android/app/utility/RegionClickEvent.kt b/app/src/main/java/org/oppia/android/app/utility/RegionClickEvent.kt index 59ae1a2445c..c95712a4736 100644 --- a/app/src/main/java/org/oppia/android/app/utility/RegionClickEvent.kt +++ b/app/src/main/java/org/oppia/android/app/utility/RegionClickEvent.kt @@ -17,4 +17,4 @@ data class NamedRegionClickedEvent(val regionLabel: String, val contentDescripti * Class to be used in case when [OnClickableAreaClickedListener] is called with an unspecified * region that is when any other is tapped on which wasn't defined by creator. */ -class DefaultRegionClickedEvent : RegionClickedEvent() +class DefaultRegionClickedEvent(val x:Float, val y:Float) : RegionClickedEvent() diff --git a/app/src/main/res/layout/image_region_selection_interaction_item.xml b/app/src/main/res/layout/image_region_selection_interaction_item.xml index 7224cabb202..0f338b4b69d 100644 --- a/app/src/main/res/layout/image_region_selection_interaction_item.xml +++ b/app/src/main/res/layout/image_region_selection_interaction_item.xml @@ -58,6 +58,7 @@ app:clickableAreas="@{viewModel.selectableRegions}" app:entityId="@{viewModel.entityId}" app:imageUrl="@{viewModel.imagePath}" + app:userAnswerState="@{viewModel.observableUserAnswrerState}" app:onRegionClicked="@{(region) -> viewModel.onClickableAreaTouched(region)}" app:overlayView="@{interactionContainerFrameLayout}" /> diff --git a/model/src/main/proto/exploration.proto b/model/src/main/proto/exploration.proto index 2b3a3215370..1b476813e4c 100644 --- a/model/src/main/proto/exploration.proto +++ b/model/src/main/proto/exploration.proto @@ -440,9 +440,17 @@ message UserAnswerState { string text_input_answer = 3; // A user's selected list of set of html content ids in drag and drop interaction. ListOfSetsOfTranslatableHtmlContentIds list_of_sets_of_translatable_html_content_ids = 4; + + ImageInteractionState image_interaction_state=5; } } +message ImageInteractionState{ + string image_label=2; + Point2d default_region_coordinates=3; + } + + // Represents categories of errors that can be inferred from a pending answer. enum AnswerErrorCategory { // The error is unknown or not specified. From cebc439efb5c20f0a3f2684b0ec8d93eb54fdd36 Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Fri, 9 Aug 2024 09:07:02 +0530 Subject: [PATCH 04/22] klint --- .../state/ImageRegionSelectionInteractionView.kt | 12 ++---------- .../ImageRegionSelectionInteractionViewModel.kt | 9 ++++----- .../oppia/android/app/utility/ClickableAreasImage.kt | 5 ++--- .../oppia/android/app/utility/RegionClickEvent.kt | 2 +- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt b/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt index f632a972e70..efa2c202886 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt @@ -1,9 +1,7 @@ package org.oppia.android.app.player.state import android.content.Context -import android.database.Observable import android.util.AttributeSet -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.appcompat.widget.AppCompatImageView @@ -11,8 +9,8 @@ import androidx.core.view.forEachIndexed import androidx.databinding.ObservableField import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager -import com.google.firebase.firestore.GeoPoint import org.oppia.android.app.model.ImageWithRegions +import org.oppia.android.app.model.UserAnswerState import org.oppia.android.app.shim.ViewBindingShim import org.oppia.android.app.utility.ClickableAreasImage import org.oppia.android.app.utility.OnClickableAreaClickedListener @@ -27,8 +25,6 @@ import org.oppia.android.util.parser.image.ImageDownloadUrlTemplate import org.oppia.android.util.parser.image.ImageLoader import org.oppia.android.util.parser.image.ImageViewTarget import javax.inject.Inject -import org.oppia.android.app.model.Point2d -import org.oppia.android.app.model.UserAnswerState /** * A custom [AppCompatImageView] with a list of [ImageWithRegions.LabeledRegion]s to work with @@ -60,8 +56,6 @@ class ImageRegionSelectionInteractionView @JvmOverloads constructor( private lateinit var userAnswerState: ObservableField - - /** * Sets the URL for the image & initiates loading it. This is intended to be called via * data-binding. @@ -72,7 +66,7 @@ class ImageRegionSelectionInteractionView @JvmOverloads constructor( } fun setUserAnswerState(userAnswerrState: ObservableField ) { - userAnswerState= userAnswerrState + userAnswerState = userAnswerrState } fun setEntityId(entityId: String) { @@ -80,8 +74,6 @@ class ImageRegionSelectionInteractionView @JvmOverloads constructor( maybeInitializeClickableAreas() } - - fun setClickableAreas(clickableAreas: List) { this.clickableAreas = clickableAreas // Resets the backgrounds for all regions if any have been loaded. This ensures the backgrounds diff --git a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt index ae80fc6f769..0c273cd2fc1 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt @@ -1,15 +1,16 @@ package org.oppia.android.app.player.state.itemviewmodel -import android.util.Log import androidx.annotation.StringRes import androidx.databinding.Observable import androidx.databinding.ObservableField import org.oppia.android.R import org.oppia.android.app.model.AnswerErrorCategory import org.oppia.android.app.model.ClickOnImage +import org.oppia.android.app.model.ImageInteractionState import org.oppia.android.app.model.ImageWithRegions import org.oppia.android.app.model.Interaction import org.oppia.android.app.model.InteractionObject +import org.oppia.android.app.model.Point2d import org.oppia.android.app.model.UserAnswer import org.oppia.android.app.model.UserAnswerState import org.oppia.android.app.model.WrittenTranslationContext @@ -22,8 +23,6 @@ import org.oppia.android.app.utility.NamedRegionClickedEvent import org.oppia.android.app.utility.OnClickableAreaClickedListener import org.oppia.android.app.utility.RegionClickedEvent import javax.inject.Inject -import org.oppia.android.app.model.ImageInteractionState -import org.oppia.android.app.model.Point2d /** [StateItemViewModel] for image region selection. */ class ImageRegionSelectionInteractionViewModel private constructor( @@ -103,7 +102,7 @@ class ImageRegionSelectionInteractionViewModel private constructor( /** It checks the pending error for the current image region input, and correspondingly updates the error string based on the specified error category. */ override fun checkPendingAnswerError(category: AnswerErrorCategory): String? { - answerErrorCetegory=category + answerErrorCetegory = category when (category) { AnswerErrorCategory.REAL_TIME -> { pendingAnswerError = null @@ -137,7 +136,7 @@ class ImageRegionSelectionInteractionViewModel private constructor( } }.build() } - this.answerErrorCategory= answerErrorCetegory + this.answerErrorCategory = answerErrorCetegory }.build() } diff --git a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt index d31b970c78c..03b466e12f5 100644 --- a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt +++ b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt @@ -1,7 +1,6 @@ package org.oppia.android.app.utility import android.graphics.RectF -import android.util.Log import android.view.MotionEvent import android.view.View import android.widget.FrameLayout @@ -12,11 +11,11 @@ import androidx.core.view.isVisible import androidx.databinding.ObservableField import org.oppia.android.R import org.oppia.android.app.model.ImageWithRegions.LabeledRegion +import org.oppia.android.app.model.Point2d +import org.oppia.android.app.model.UserAnswerState import org.oppia.android.app.player.state.ImageRegionSelectionInteractionView import org.oppia.android.app.shim.ViewBindingShim import kotlin.math.roundToInt -import org.oppia.android.app.model.Point2d -import org.oppia.android.app.model.UserAnswerState /** Helper class to handle clicks on an image along with highlighting the selected region. */ class ClickableAreasImage( diff --git a/app/src/main/java/org/oppia/android/app/utility/RegionClickEvent.kt b/app/src/main/java/org/oppia/android/app/utility/RegionClickEvent.kt index c95712a4736..e8e290c74f1 100644 --- a/app/src/main/java/org/oppia/android/app/utility/RegionClickEvent.kt +++ b/app/src/main/java/org/oppia/android/app/utility/RegionClickEvent.kt @@ -17,4 +17,4 @@ data class NamedRegionClickedEvent(val regionLabel: String, val contentDescripti * Class to be used in case when [OnClickableAreaClickedListener] is called with an unspecified * region that is when any other is tapped on which wasn't defined by creator. */ -class DefaultRegionClickedEvent(val x:Float, val y:Float) : RegionClickedEvent() +class DefaultRegionClickedEvent(val x: Float, val y: Float) : RegionClickedEvent() From 1e99c58bd5d3facdf3342b898999277e895ff011 Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Fri, 9 Aug 2024 10:27:49 +0530 Subject: [PATCH 05/22] Clean up --- .../ImageRegionSelectionInteractionView.kt | 8 +++--- ...mageRegionSelectionInteractionViewModel.kt | 8 ++++-- .../app/utility/ClickableAreasImage.kt | 28 +++++++++---------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt b/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt index efa2c202886..53e30dd74f0 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt @@ -54,7 +54,7 @@ class ImageRegionSelectionInteractionView @JvmOverloads constructor( private lateinit var imageUrl: String private lateinit var clickableAreas: List - private lateinit var userAnswerState: ObservableField + private lateinit var observableUserAnswerState: ObservableField /** * Sets the URL for the image & initiates loading it. This is intended to be called via @@ -66,7 +66,7 @@ class ImageRegionSelectionInteractionView @JvmOverloads constructor( } fun setUserAnswerState(userAnswerrState: ObservableField ) { - userAnswerState = userAnswerrState + observableUserAnswerState = userAnswerrState } fun setEntityId(entityId: String) { @@ -130,10 +130,10 @@ class ImageRegionSelectionInteractionView @JvmOverloads constructor( bindingInterface, isAccessibilityEnabled = accessibilityService.isScreenReaderEnabled(), clickableAreas, - userAnswerState + observableUserAnswerState ) areasImage.addRegionViews() - areasImage.addDefaultImageSelection() + areasImage.maybeSelectDefaultRegion() performAttachment(areasImage) } } diff --git a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt index 0c273cd2fc1..c46884ef9a7 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt @@ -47,7 +47,9 @@ class ImageRegionSelectionInteractionViewModel private constructor( schemaObject?.customSchemaValue?.imageWithRegions?.labelRegionsList ?: listOf() } - val observableUserAnswrerState = ObservableField(userAnswerState) + val observableUserAnswrerState by lazy { + ObservableField(userAnswerState) + } private var answerErrorCetegory: AnswerErrorCategory = AnswerErrorCategory.NO_ERROR @@ -127,9 +129,9 @@ class ImageRegionSelectionInteractionViewModel private constructor( override fun getUserAnswerState(): UserAnswerState { return UserAnswerState.newBuilder().apply { - if (answerText != "" || dafaultRegionCoordinates != null) { + if (answerText.isNotEmpty() || dafaultRegionCoordinates != null) { this.imageInteractionState = ImageInteractionState.newBuilder().apply { - if (answerText != "") { + if (answerText.isNotEmpty()) { this.imageLabel = answerText.toString() } else { this.defaultRegionCoordinates = dafaultRegionCoordinates diff --git a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt index 03b466e12f5..d50a3cbef63 100644 --- a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt +++ b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt @@ -25,25 +25,23 @@ class ClickableAreasImage( bindingInterface: ViewBindingShim, private val isAccessibilityEnabled: Boolean, private val clickableAreas: List, - userAnswerState: ObservableField + observableUserAnswerState: ObservableField ) { - private var label: String? = null - private var coordinates: Point2d? = null + private var imageLabel: String? = null + private var defaultRegionCoordinates: Point2d? = null private val defaultRegionView by lazy { bindingInterface.getDefaultRegion(parentView) } init { imageView.initializeShowRegionTouchListener() - if (userAnswerState.get()!!.hasImageInteractionState()) { - if (userAnswerState.get()!!.imageInteractionState.imageLabel.isNotBlank()) { - label = userAnswerState.get()!!.imageInteractionState.imageLabel + if (observableUserAnswerState.get()!!.hasImageInteractionState()) { + if (observableUserAnswerState.get()!!.imageInteractionState.imageLabel.isNotBlank()) { + imageLabel = observableUserAnswerState.get()!!.imageInteractionState.imageLabel } else { - coordinates = userAnswerState.get()!!.imageInteractionState.defaultRegionCoordinates + defaultRegionCoordinates = + observableUserAnswerState.get()!!.imageInteractionState.defaultRegionCoordinates } - } else { - label = null - coordinates = null } } @@ -93,10 +91,10 @@ class ClickableAreasImage( return imageView.height - imageView.paddingTop - imageView.paddingBottom } - fun addDefaultImageSelection() { - if (coordinates != null) { - onPhotoTap(coordinates!!.x, coordinates!!.y) - coordinates = null + /** Selects default region. **/ + fun maybeSelectDefaultRegion() { + if (defaultRegionCoordinates != null) { + onPhotoTap(defaultRegionCoordinates!!.x, defaultRegionCoordinates!!.y) } } @@ -179,7 +177,7 @@ class ClickableAreasImage( } private fun View.initializeToggleRegionTouchListener(clickableArea: LabeledRegion) { - if (clickableArea.label.equals(label)) { + if (clickableArea.label.equals(imageLabel)) { showOrHideRegion(this@initializeToggleRegionTouchListener, clickableArea) } setOnTouchListener { view, event -> From 01a426e44f0d53b504b564cf2651f19a3727af21 Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Fri, 9 Aug 2024 10:34:53 +0530 Subject: [PATCH 06/22] Added comments --- model/src/main/proto/exploration.proto | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/model/src/main/proto/exploration.proto b/model/src/main/proto/exploration.proto index 1b476813e4c..71c279c95ad 100644 --- a/model/src/main/proto/exploration.proto +++ b/model/src/main/proto/exploration.proto @@ -440,17 +440,19 @@ message UserAnswerState { string text_input_answer = 3; // A user's selected list of set of html content ids in drag and drop interaction. ListOfSetsOfTranslatableHtmlContentIds list_of_sets_of_translatable_html_content_ids = 4; - + // Image region selected by user. ImageInteractionState image_interaction_state=5; } } +// Represents the state of image selection that the user has selected. message ImageInteractionState{ - string image_label=2; - Point2d default_region_coordinates=3; + // Selected image label. + string image_label=1; + // Selected default region coordinates. + Point2d default_region_coordinates=2; } - // Represents categories of errors that can be inferred from a pending answer. enum AnswerErrorCategory { // The error is unknown or not specified. From 07ff0aca14659e0444c09f95b16915834c8bde51 Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Fri, 9 Aug 2024 10:36:24 +0530 Subject: [PATCH 07/22] Clean up --- model/src/main/proto/exploration.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/src/main/proto/exploration.proto b/model/src/main/proto/exploration.proto index 71c279c95ad..87ca49b0812 100644 --- a/model/src/main/proto/exploration.proto +++ b/model/src/main/proto/exploration.proto @@ -451,7 +451,7 @@ message ImageInteractionState{ string image_label=1; // Selected default region coordinates. Point2d default_region_coordinates=2; - } +} // Represents categories of errors that can be inferred from a pending answer. enum AnswerErrorCategory { From bfaf1f2f593ed47f0bc96b7abb05c99224ad78c8 Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Sat, 10 Aug 2024 10:59:22 +0530 Subject: [PATCH 08/22] remove observer --- .../state/ImageRegionSelectionInteractionView.kt | 9 ++++----- .../ImageRegionSelectionInteractionViewModel.kt | 1 - .../oppia/android/app/utility/ClickableAreasImage.kt | 10 +++++----- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt b/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt index 53e30dd74f0..10e4ff0a5ac 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt @@ -6,7 +6,6 @@ import android.view.View import android.widget.FrameLayout import androidx.appcompat.widget.AppCompatImageView import androidx.core.view.forEachIndexed -import androidx.databinding.ObservableField import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import org.oppia.android.app.model.ImageWithRegions @@ -54,7 +53,7 @@ class ImageRegionSelectionInteractionView @JvmOverloads constructor( private lateinit var imageUrl: String private lateinit var clickableAreas: List - private lateinit var observableUserAnswerState: ObservableField + private lateinit var userAnswerState: UserAnswerState /** * Sets the URL for the image & initiates loading it. This is intended to be called via @@ -65,8 +64,8 @@ class ImageRegionSelectionInteractionView @JvmOverloads constructor( maybeInitializeClickableAreas() } - fun setUserAnswerState(userAnswerrState: ObservableField ) { - observableUserAnswerState = userAnswerrState + fun setUserAnswerState(userAnswerrState: UserAnswerState) { + this.userAnswerState = userAnswerrState } fun setEntityId(entityId: String) { @@ -130,7 +129,7 @@ class ImageRegionSelectionInteractionView @JvmOverloads constructor( bindingInterface, isAccessibilityEnabled = accessibilityService.isScreenReaderEnabled(), clickableAreas, - observableUserAnswerState + userAnswerState ) areasImage.addRegionViews() areasImage.maybeSelectDefaultRegion() diff --git a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt index c46884ef9a7..ec018c6bf54 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt @@ -78,7 +78,6 @@ class ImageRegionSelectionInteractionViewModel private constructor( pendingAnswerError = null, inputAnswerAvailable = true ) - checkPendingAnswerError(userAnswerState.answerErrorCategory) } diff --git a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt index d50a3cbef63..80d3b58f261 100644 --- a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt +++ b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt @@ -25,7 +25,7 @@ class ClickableAreasImage( bindingInterface: ViewBindingShim, private val isAccessibilityEnabled: Boolean, private val clickableAreas: List, - observableUserAnswerState: ObservableField + userAnswerState: UserAnswerState ) { private var imageLabel: String? = null private var defaultRegionCoordinates: Point2d? = null @@ -35,12 +35,12 @@ class ClickableAreasImage( init { imageView.initializeShowRegionTouchListener() - if (observableUserAnswerState.get()!!.hasImageInteractionState()) { - if (observableUserAnswerState.get()!!.imageInteractionState.imageLabel.isNotBlank()) { - imageLabel = observableUserAnswerState.get()!!.imageInteractionState.imageLabel + if (userAnswerState.hasImageInteractionState()) { + if (userAnswerState.imageInteractionState.imageLabel.isNotBlank()) { + imageLabel = userAnswerState.imageInteractionState.imageLabel } else { defaultRegionCoordinates = - observableUserAnswerState.get()!!.imageInteractionState.defaultRegionCoordinates + userAnswerState.imageInteractionState.defaultRegionCoordinates } } } From a9647ba6f0821154db521aeb0229fcc55386a608 Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Sat, 10 Aug 2024 11:00:17 +0530 Subject: [PATCH 09/22] remove observer --- .../app/player/state/ImageRegionSelectionInteractionView.kt | 4 ++-- .../java/org/oppia/android/app/utility/ClickableAreasImage.kt | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt b/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt index 10e4ff0a5ac..803d68fb9b0 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt @@ -53,7 +53,7 @@ class ImageRegionSelectionInteractionView @JvmOverloads constructor( private lateinit var imageUrl: String private lateinit var clickableAreas: List - private lateinit var userAnswerState: UserAnswerState + private lateinit var userAnswerState: UserAnswerState /** * Sets the URL for the image & initiates loading it. This is intended to be called via @@ -65,7 +65,7 @@ class ImageRegionSelectionInteractionView @JvmOverloads constructor( } fun setUserAnswerState(userAnswerrState: UserAnswerState) { - this.userAnswerState = userAnswerrState + this.userAnswerState = userAnswerrState } fun setEntityId(entityId: String) { diff --git a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt index 80d3b58f261..204c6757a91 100644 --- a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt +++ b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt @@ -8,7 +8,6 @@ import androidx.core.view.ViewCompat import androidx.core.view.children import androidx.core.view.forEachIndexed import androidx.core.view.isVisible -import androidx.databinding.ObservableField import org.oppia.android.R import org.oppia.android.app.model.ImageWithRegions.LabeledRegion import org.oppia.android.app.model.Point2d From 7597c1d678a32f3f2d486b7e96bceec353f275e2 Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Sat, 10 Aug 2024 11:14:32 +0530 Subject: [PATCH 10/22] Added comment --- .../itemviewmodel/ImageRegionSelectionInteractionViewModel.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt index ec018c6bf54..3ca7211f24a 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt @@ -142,6 +142,10 @@ class ImageRegionSelectionInteractionViewModel private constructor( } override fun getPendingAnswer(): UserAnswer { + // Resetting Observable UserAnswerState to its default instance to ensure that + // the ImageRegionSelectionInteractionView is updated with the correct state. + // This is necessary because ImageRegionSelectionInteractionView is not recreated every time + // the user submits an answer, leading it to retain the old UserAnswerState. observableUserAnswrerState.set(UserAnswerState.getDefaultInstance()) return UserAnswer.newBuilder().apply { val answerTextString = answerText.toString() From fe281ddbe197149f6b2312284a11030e138eba41 Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Sat, 10 Aug 2024 11:35:45 +0530 Subject: [PATCH 11/22] Modified comment --- .../ImageRegionSelectionInteractionViewModel.kt | 5 +++-- .../org/oppia/android/app/utility/ClickableAreasImage.kt | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt index 3ca7211f24a..dd0b9d4278e 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt @@ -143,10 +143,11 @@ class ImageRegionSelectionInteractionViewModel private constructor( override fun getPendingAnswer(): UserAnswer { // Resetting Observable UserAnswerState to its default instance to ensure that - // the ImageRegionSelectionInteractionView is updated with the correct state. + // the ImageRegionSelectionInteractionView reflects no image region selection. // This is necessary because ImageRegionSelectionInteractionView is not recreated every time - // the user submits an answer, leading it to retain the old UserAnswerState. + // the user submits an answer, causing it to retain the old UserAnswerState. observableUserAnswrerState.set(UserAnswerState.getDefaultInstance()) + return UserAnswer.newBuilder().apply { val answerTextString = answerText.toString() answer = InteractionObject.newBuilder().apply { diff --git a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt index 204c6757a91..aafa963da86 100644 --- a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt +++ b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt @@ -90,7 +90,7 @@ class ClickableAreasImage( return imageView.height - imageView.paddingTop - imageView.paddingBottom } - /** Selects default region. **/ + /** Selects default region. */ fun maybeSelectDefaultRegion() { if (defaultRegionCoordinates != null) { onPhotoTap(defaultRegionCoordinates!!.x, defaultRegionCoordinates!!.y) From f7b59b685a875ba44357646b70784ce53937b362 Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Mon, 12 Aug 2024 08:36:42 +0530 Subject: [PATCH 12/22] Reorganize code for clarity --- .../org/oppia/android/app/utility/ClickableAreasImage.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt index aafa963da86..e7d3995f31e 100644 --- a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt +++ b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt @@ -128,6 +128,9 @@ class ClickableAreasImage( newView.isFocusableInTouchMode = true newView.tag = clickableArea.label newView.initializeToggleRegionTouchListener(clickableArea) + if (clickableArea.label.equals(imageLabel)) { + showOrHideRegion(newView = newView, clickableArea = clickableArea) + } if (isAccessibilityEnabled) { // Make default region visibility gone when talkback enabled to avoid any accidental touch. defaultRegionView.isVisible = false @@ -176,9 +179,6 @@ class ClickableAreasImage( } private fun View.initializeToggleRegionTouchListener(clickableArea: LabeledRegion) { - if (clickableArea.label.equals(imageLabel)) { - showOrHideRegion(this@initializeToggleRegionTouchListener, clickableArea) - } setOnTouchListener { view, event -> if (event.action == MotionEvent.ACTION_DOWN) { showOrHideRegion(this@initializeToggleRegionTouchListener, clickableArea) From 8420daa9228b7e14824cc350a980ea949961bac7 Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Tue, 13 Aug 2024 10:21:41 +0530 Subject: [PATCH 13/22] Added test for drag and drop and image interaction inout --- .../app/player/state/StateFragmentTest.kt | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt index eb141d43015..4534c98bf55 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt @@ -1118,6 +1118,58 @@ class StateFragmentTest { } } + @Test + fun testStateFragment_dragAndDrop_retainStateOnConfigurationChange() { + setUpTestWithLanguageSwitchingFeatureOff() + launchForExploration(TEST_EXPLORATION_ID_2, shouldSavePartialProgress = false).use { + startPlayingExploration() + playThroughPrototypeState1() + playThroughPrototypeState2() + playThroughPrototypeState3() + playThroughPrototypeState4() + playThroughPrototypeState5() + playThroughPrototypeState6() + playThroughPrototypeState7() + playThroughPrototypeState8() + // Drag and drop interaction without grouping. + dragAndDropItem(fromPosition = 0, toPosition = 3) + rotateToLandscape() + onView( + atPositionOnView( + recyclerViewId = R.id.drag_drop_interaction_recycler_view, + position = 3, + targetViewId = R.id.drag_drop_content_text_view + ) + ).check(matches(withText(containsString("0.35")))) + } + } + + @Test + fun testStateFragment_dragAndDrop_mergeFirstTwoItems_dragItem_retainStateOnConfigurationChange() { + setUpTestWithLanguageSwitchingFeatureOff() + launchForExploration(TEST_EXPLORATION_ID_4, shouldSavePartialProgress = false).use { + startPlayingExploration() + mergeDragAndDropItems(position = 0) + dragAndDropItem(fromPosition = 0, toPosition = 2) + rotateToLandscape() + scrollToViewType(DRAG_DROP_SORT_INTERACTION) + onView( + atPositionOnView( + recyclerViewId = R.id.drag_drop_interaction_recycler_view, + position = 2, + targetViewId = R.id.drag_drop_item_recyclerview + ) + ).check(matches(hasChildCount(2))) + onView( + atPositionOnView( + recyclerViewId = R.id.drag_drop_interaction_recycler_view, + position = 2, + targetViewId = R.id.drag_drop_content_text_view + ) + ).check(matches(withText(containsString("a camera at the store")))) + } + } + @Test fun testStateFragment_loadDragDropExp_withoutGrouping_submitWithoutArranging_showsErrorMessage_dragItem_errorMessageIsReset() { // ktlint-disable max-line-length setUpTestWithLanguageSwitchingFeatureOff() @@ -1293,6 +1345,41 @@ class StateFragmentTest { } } + @Test + fun testStateFragment_loadImageRegion_clickRegion6_retainStateOnConfigurationChange() { + setUpTestWithLanguageSwitchingFeatureOff() + launchForExploration(TEST_EXPLORATION_ID_13, shouldSavePartialProgress = false).use { + startPlayingExploration() + waitForImageViewInteractionToFullyLoad() + clickImageRegion(pointX = 0.5f, pointY = 0.5f) + rotateToLandscape() + scrollToViewType(SUBMIT_ANSWER_BUTTON) + onView(withId(R.id.submit_answer_button)).check(matches(isEnabled())) + clickSubmitAnswerButton() + scrollToViewType(FEEDBACK) + onView(withId(R.id.feedback_text_view)).check( + matches( + withText(containsString("Saturn")) + ) + ) + } + } + + @Test + fun testStateFragment_loadImageRegion_submitTimeError_retainStateOnConfigurationChange() { + setUpTestWithLanguageSwitchingFeatureOff() + launchForExploration(TEST_EXPLORATION_ID_13, shouldSavePartialProgress = false).use { + startPlayingExploration() + waitForImageViewInteractionToFullyLoad() + onView(withId(R.id.submit_answer_button)).check(matches(isEnabled())) + clickSubmitAnswerButton() + rotateToLandscape() + onView(withId(R.id.image_input_error)).check( + matches(withText(containsString("Select an image to continue"))) + ) + } + } + @Test @RunOn(TestPlatform.ESPRESSO) // TODO(#1611): Enable for Robolectric. @Ignore("Flaky test") // TODO(#3171): Fix ImageRegion failing test cases. From 6e7aa3e89b57561a28dfdaec96aeaef4569cfaec Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Tue, 13 Aug 2024 11:00:03 +0530 Subject: [PATCH 14/22] handle null using let --- .../java/org/oppia/android/app/utility/ClickableAreasImage.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt index e7d3995f31e..684720a1f48 100644 --- a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt +++ b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt @@ -92,8 +92,8 @@ class ClickableAreasImage( /** Selects default region. */ fun maybeSelectDefaultRegion() { - if (defaultRegionCoordinates != null) { - onPhotoTap(defaultRegionCoordinates!!.x, defaultRegionCoordinates!!.y) + defaultRegionCoordinates?.let { + onPhotoTap(it.x, it.y) } } From c2b0e660a994dbc1a96b269444ad56dca8837c77 Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Tue, 13 Aug 2024 11:47:07 +0530 Subject: [PATCH 15/22] Fix test --- .../org/oppia/android/app/player/state/StateFragmentTest.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt index 4534c98bf55..5fc25bcd9c1 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt @@ -1134,6 +1134,7 @@ class StateFragmentTest { // Drag and drop interaction without grouping. dragAndDropItem(fromPosition = 0, toPosition = 3) rotateToLandscape() + testCoroutineDispatchers.runCurrent() onView( atPositionOnView( recyclerViewId = R.id.drag_drop_interaction_recycler_view, @@ -1152,6 +1153,7 @@ class StateFragmentTest { mergeDragAndDropItems(position = 0) dragAndDropItem(fromPosition = 0, toPosition = 2) rotateToLandscape() + testCoroutineDispatchers.runCurrent() scrollToViewType(DRAG_DROP_SORT_INTERACTION) onView( atPositionOnView( From 73a4203e334e0800f965350c82520fdbd706f3ca Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Wed, 14 Aug 2024 10:04:57 +0530 Subject: [PATCH 16/22] modified tests --- .../app/player/state/StateFragmentTest.kt | 31 ++++--------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt index 5fc25bcd9c1..6f5b8bc811a 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt @@ -1121,54 +1121,35 @@ class StateFragmentTest { @Test fun testStateFragment_dragAndDrop_retainStateOnConfigurationChange() { setUpTestWithLanguageSwitchingFeatureOff() - launchForExploration(TEST_EXPLORATION_ID_2, shouldSavePartialProgress = false).use { + launchForExploration(TEST_EXPLORATION_ID_4, shouldSavePartialProgress = false).use { startPlayingExploration() - playThroughPrototypeState1() - playThroughPrototypeState2() - playThroughPrototypeState3() - playThroughPrototypeState4() - playThroughPrototypeState5() - playThroughPrototypeState6() - playThroughPrototypeState7() - playThroughPrototypeState8() - // Drag and drop interaction without grouping. - dragAndDropItem(fromPosition = 0, toPosition = 3) + dragAndDropItem(fromPosition = 0, toPosition = 1) rotateToLandscape() - testCoroutineDispatchers.runCurrent() onView( atPositionOnView( recyclerViewId = R.id.drag_drop_interaction_recycler_view, - position = 3, + position = 0, targetViewId = R.id.drag_drop_content_text_view ) - ).check(matches(withText(containsString("0.35")))) + ).check(matches(withText(containsString("a camera at the store")))) } } @Test - fun testStateFragment_dragAndDrop_mergeFirstTwoItems_dragItem_retainStateOnConfigurationChange() { + fun testStateFragment_dragAndDrop_mergeFirstTwoItems_retainStateOnConfigurationChange() { setUpTestWithLanguageSwitchingFeatureOff() launchForExploration(TEST_EXPLORATION_ID_4, shouldSavePartialProgress = false).use { startPlayingExploration() mergeDragAndDropItems(position = 0) - dragAndDropItem(fromPosition = 0, toPosition = 2) rotateToLandscape() - testCoroutineDispatchers.runCurrent() scrollToViewType(DRAG_DROP_SORT_INTERACTION) onView( atPositionOnView( recyclerViewId = R.id.drag_drop_interaction_recycler_view, - position = 2, + position = 0, targetViewId = R.id.drag_drop_item_recyclerview ) ).check(matches(hasChildCount(2))) - onView( - atPositionOnView( - recyclerViewId = R.id.drag_drop_interaction_recycler_view, - position = 2, - targetViewId = R.id.drag_drop_content_text_view - ) - ).check(matches(withText(containsString("a camera at the store")))) } } From f11ae72f5323409671df7555be75d71ef2dcbd91 Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Wed, 14 Aug 2024 10:51:04 +0530 Subject: [PATCH 17/22] modified tests --- .../java/org/oppia/android/app/player/state/StateFragmentTest.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt index 6f5b8bc811a..d40216cf2cb 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt @@ -1125,6 +1125,7 @@ class StateFragmentTest { startPlayingExploration() dragAndDropItem(fromPosition = 0, toPosition = 1) rotateToLandscape() + scrollToViewType(DRAG_DROP_SORT_INTERACTION) onView( atPositionOnView( recyclerViewId = R.id.drag_drop_interaction_recycler_view, From 50f35db123cd632d738be4aba30ddd8163445944 Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Wed, 14 Aug 2024 11:35:28 +0530 Subject: [PATCH 18/22] modified tests --- .../java/org/oppia/android/app/player/state/StateFragmentTest.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt index d40216cf2cb..879b6f87878 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt @@ -1119,6 +1119,7 @@ class StateFragmentTest { } @Test + @RunOn(TestPlatform.ESPRESSO) fun testStateFragment_dragAndDrop_retainStateOnConfigurationChange() { setUpTestWithLanguageSwitchingFeatureOff() launchForExploration(TEST_EXPLORATION_ID_4, shouldSavePartialProgress = false).use { From 654414d32360a102d70de2512a10deb148c3c3ea Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Wed, 14 Aug 2024 12:35:29 +0530 Subject: [PATCH 19/22] Added test for drag and drop error message --- .../app/player/state/StateFragmentTest.kt | 49 +++++++++++++++++-- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt index 879b6f87878..24cb4906fe5 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt @@ -1119,8 +1119,8 @@ class StateFragmentTest { } @Test - @RunOn(TestPlatform.ESPRESSO) - fun testStateFragment_dragAndDrop_retainStateOnConfigurationChange() { + @RunOn(TestPlatform.ESPRESSO) // TODO(#1612): Enable for Robolectric. + fun testStateFragment_loadDragDropExp_retainStateOnConfigurationChange() { setUpTestWithLanguageSwitchingFeatureOff() launchForExploration(TEST_EXPLORATION_ID_4, shouldSavePartialProgress = false).use { startPlayingExploration() @@ -1138,7 +1138,48 @@ class StateFragmentTest { } @Test - fun testStateFragment_dragAndDrop_mergeFirstTwoItems_retainStateOnConfigurationChange() { + @RunOn(TestPlatform.ESPRESSO) // TODO(#1612): Enable for Robolectric. + fun testStateFragment_loadDragDropExp_mergeTwoItems_dargAndDrop_retainStateOnConfigurationChange() { + setUpTestWithLanguageSwitchingFeatureOff() + launchForExploration(TEST_EXPLORATION_ID_4, shouldSavePartialProgress = false).use { + startPlayingExploration() + mergeDragAndDropItems(position = 0) + dragAndDropItem(fromPosition = 0, toPosition = 2) + rotateToLandscape() + onView( + atPositionOnView( + recyclerViewId = R.id.drag_drop_interaction_recycler_view, + position = 2, + targetViewId = R.id.drag_drop_item_recyclerview + ) + ).check(matches(hasChildCount(2))) + scrollToViewType(DRAG_DROP_SORT_INTERACTION) + onView( + atPositionOnView( + recyclerViewId = R.id.drag_drop_interaction_recycler_view, + position = 2, + targetViewId = R.id.drag_drop_content_text_view + ) + ).check(matches(withText(containsString("a camera at the store")))) + } + } + + @Test + fun testStateFragment_loadDragDropExp_submitTimeError_retainStateOnConfigurationChange(){ + setUpTestWithLanguageSwitchingFeatureOff() + launchForExploration(TEST_EXPLORATION_ID_4, shouldSavePartialProgress = false).use { + startPlayingExploration() + onView(withId(R.id.submit_answer_button)).check(matches(isEnabled())) + clickSubmitAnswerButton() + rotateToLandscape() + onView(withId(R.id.drag_drop_interaction_error)).check( + matches(withText(R.string.drag_and_drop_interaction_empty_input)) + ) + } + } + + @Test + fun testStateFragment_loadDragDropExp_mergeFirstTwoItems_retainStateOnConfigurationChange() { setUpTestWithLanguageSwitchingFeatureOff() launchForExploration(TEST_EXPLORATION_ID_4, shouldSavePartialProgress = false).use { startPlayingExploration() @@ -1360,7 +1401,7 @@ class StateFragmentTest { clickSubmitAnswerButton() rotateToLandscape() onView(withId(R.id.image_input_error)).check( - matches(withText(containsString("Select an image to continue"))) + matches(withText(R.string.image_error_empty_input)) ) } } From 5220eb5bd7f43fa73bb63bb4fd8ae293eb3abc0d Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Wed, 14 Aug 2024 12:36:36 +0530 Subject: [PATCH 20/22] klint --- .../org/oppia/android/app/player/state/StateFragmentTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt index 24cb4906fe5..6bb74d198a5 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt @@ -1139,7 +1139,7 @@ class StateFragmentTest { @Test @RunOn(TestPlatform.ESPRESSO) // TODO(#1612): Enable for Robolectric. - fun testStateFragment_loadDragDropExp_mergeTwoItems_dargAndDrop_retainStateOnConfigurationChange() { + fun testStateFragment_loadDragDropExp_mergeItems_dargAndDrop_retainStateOnConfigurationChange() { setUpTestWithLanguageSwitchingFeatureOff() launchForExploration(TEST_EXPLORATION_ID_4, shouldSavePartialProgress = false).use { startPlayingExploration() @@ -1165,7 +1165,7 @@ class StateFragmentTest { } @Test - fun testStateFragment_loadDragDropExp_submitTimeError_retainStateOnConfigurationChange(){ + fun testStateFragment_loadDragDropExp_submitTimeError_retainStateOnConfigurationChange() { setUpTestWithLanguageSwitchingFeatureOff() launchForExploration(TEST_EXPLORATION_ID_4, shouldSavePartialProgress = false).use { startPlayingExploration() From 3f407f2fdb00c0e4d3d860b76fa884f2cdbd041e Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Sat, 17 Aug 2024 10:50:02 +0530 Subject: [PATCH 21/22] Removed Default region retention --- .../ImageRegionSelectionInteractionView.kt | 1 - ...mageRegionSelectionInteractionViewModel.kt | 18 ++---------------- .../app/utility/ClickableAreasImage.kt | 19 ++----------------- model/src/main/proto/exploration.proto | 10 +--------- 4 files changed, 5 insertions(+), 43 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt b/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt index 803d68fb9b0..e7f2dbe3e2e 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/ImageRegionSelectionInteractionView.kt @@ -132,7 +132,6 @@ class ImageRegionSelectionInteractionView @JvmOverloads constructor( userAnswerState ) areasImage.addRegionViews() - areasImage.maybeSelectDefaultRegion() performAttachment(areasImage) } } diff --git a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt index dd0b9d4278e..6440685f19f 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ImageRegionSelectionInteractionViewModel.kt @@ -6,11 +6,9 @@ import androidx.databinding.ObservableField import org.oppia.android.R import org.oppia.android.app.model.AnswerErrorCategory import org.oppia.android.app.model.ClickOnImage -import org.oppia.android.app.model.ImageInteractionState import org.oppia.android.app.model.ImageWithRegions import org.oppia.android.app.model.Interaction import org.oppia.android.app.model.InteractionObject -import org.oppia.android.app.model.Point2d import org.oppia.android.app.model.UserAnswer import org.oppia.android.app.model.UserAnswerState import org.oppia.android.app.model.WrittenTranslationContext @@ -41,7 +39,6 @@ class ImageRegionSelectionInteractionViewModel private constructor( var errorMessage = ObservableField("") private var isDefaultRegionClicked = false var answerText: CharSequence = "" - private var dafaultRegionCoordinates: Point2d? = null val selectableRegions: List by lazy { val schemaObject = interaction.customizationArgsMap["imageAndRegions"] schemaObject?.customSchemaValue?.imageWithRegions?.labelRegionsList ?: listOf() @@ -84,16 +81,11 @@ class ImageRegionSelectionInteractionViewModel private constructor( override fun onClickableAreaTouched(region: RegionClickedEvent) { when (region) { is DefaultRegionClickedEvent -> { - dafaultRegionCoordinates = Point2d.newBuilder().apply { - x = region.x - y = region.y - }.build() answerText = "" isAnswerAvailable.set(false) isDefaultRegionClicked = true } is NamedRegionClickedEvent -> { - dafaultRegionCoordinates = null answerText = region.regionLabel isAnswerAvailable.set(true) } @@ -128,14 +120,8 @@ class ImageRegionSelectionInteractionViewModel private constructor( override fun getUserAnswerState(): UserAnswerState { return UserAnswerState.newBuilder().apply { - if (answerText.isNotEmpty() || dafaultRegionCoordinates != null) { - this.imageInteractionState = ImageInteractionState.newBuilder().apply { - if (answerText.isNotEmpty()) { - this.imageLabel = answerText.toString() - } else { - this.defaultRegionCoordinates = dafaultRegionCoordinates - } - }.build() + if (answerText.isNotEmpty()) { + this.imageLabel = answerText.toString() } this.answerErrorCategory = answerErrorCetegory }.build() diff --git a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt index 684720a1f48..fa77fa271de 100644 --- a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt +++ b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt @@ -10,7 +10,6 @@ import androidx.core.view.forEachIndexed import androidx.core.view.isVisible import org.oppia.android.R import org.oppia.android.app.model.ImageWithRegions.LabeledRegion -import org.oppia.android.app.model.Point2d import org.oppia.android.app.model.UserAnswerState import org.oppia.android.app.player.state.ImageRegionSelectionInteractionView import org.oppia.android.app.shim.ViewBindingShim @@ -27,20 +26,13 @@ class ClickableAreasImage( userAnswerState: UserAnswerState ) { private var imageLabel: String? = null - private var defaultRegionCoordinates: Point2d? = null - private val defaultRegionView by lazy { bindingInterface.getDefaultRegion(parentView) } init { imageView.initializeShowRegionTouchListener() - if (userAnswerState.hasImageInteractionState()) { - if (userAnswerState.imageInteractionState.imageLabel.isNotBlank()) { - imageLabel = userAnswerState.imageInteractionState.imageLabel - } else { - defaultRegionCoordinates = - userAnswerState.imageInteractionState.defaultRegionCoordinates - } + if (userAnswerState.imageLabel.isNotBlank()) { + imageLabel = userAnswerState.imageLabel } } @@ -90,13 +82,6 @@ class ClickableAreasImage( return imageView.height - imageView.paddingTop - imageView.paddingBottom } - /** Selects default region. */ - fun maybeSelectDefaultRegion() { - defaultRegionCoordinates?.let { - onPhotoTap(it.x, it.y) - } - } - /** Add selectable regions to [FrameLayout]. */ fun addRegionViews() { // Remove all views other than the default region & selectable image. diff --git a/model/src/main/proto/exploration.proto b/model/src/main/proto/exploration.proto index 87ca49b0812..75963b3e366 100644 --- a/model/src/main/proto/exploration.proto +++ b/model/src/main/proto/exploration.proto @@ -441,18 +441,10 @@ message UserAnswerState { // A user's selected list of set of html content ids in drag and drop interaction. ListOfSetsOfTranslatableHtmlContentIds list_of_sets_of_translatable_html_content_ids = 4; // Image region selected by user. - ImageInteractionState image_interaction_state=5; + string image_label=5; } } -// Represents the state of image selection that the user has selected. -message ImageInteractionState{ - // Selected image label. - string image_label=1; - // Selected default region coordinates. - Point2d default_region_coordinates=2; -} - // Represents categories of errors that can be inferred from a pending answer. enum AnswerErrorCategory { // The error is unknown or not specified. From c807bdd5c9c353f2cde8e47cb09ae0ee46e8d617 Mon Sep 17 00:00:00 2001 From: Vishwajith-Shettigar Date: Wed, 21 Aug 2024 08:44:20 +0530 Subject: [PATCH 22/22] Modified comments for better understanding --- model/src/main/proto/exploration.proto | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/model/src/main/proto/exploration.proto b/model/src/main/proto/exploration.proto index 75963b3e366..92b5b40351a 100644 --- a/model/src/main/proto/exploration.proto +++ b/model/src/main/proto/exploration.proto @@ -436,12 +436,12 @@ message UserAnswerState { oneof answer_input_type { // User's selection for selection input interactions. ItemSelectionAnswerState item_selection = 2; - // Raw answer entered by the user in text-based interactions. + // Text answer entered by the user in text-based interactions. string text_input_answer = 3; - // A user's selected list of set of html content ids in drag and drop interaction. + // A user's selected list of sets of HTML content IDs in drag-and-drop interactions. ListOfSetsOfTranslatableHtmlContentIds list_of_sets_of_translatable_html_content_ids = 4; - // Image region selected by user. - string image_label=5; + // Selected image's label. + string image_label = 5; } }