From 22c35e3beaa675c6f45b3fb9a64f4afa94a9d5b7 Mon Sep 17 00:00:00 2001 From: Shubhadeep_Karmakar Date: Sat, 10 Feb 2024 20:25:18 +0530 Subject: [PATCH 1/2] fix part of #4839 --- .../player/state/StateFragmentPresenter.kt | 21 +++++++++++++++---- .../state/itemviewmodel/ContentViewModel.kt | 13 +++++++++++- .../FractionInteractionViewModel.kt | 12 +++++++++++ .../state/itemviewmodel/StateItemViewModel.kt | 4 ++++ .../itemviewmodel/SubmitButtonViewModel.kt | 14 ++++++++++++- 5 files changed, 58 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/player/state/StateFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/state/StateFragmentPresenter.kt index 9aabc25f075..4a0c98dd4a7 100755 --- a/app/src/main/java/org/oppia/android/app/player/state/StateFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/StateFragmentPresenter.kt @@ -54,6 +54,7 @@ import org.oppia.android.util.gcsresource.DefaultResourceBucketName import org.oppia.android.util.parser.html.ExplorationHtmlParserEntityType import org.oppia.android.util.system.OppiaClock import javax.inject.Inject +import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel const val STATE_FRAGMENT_PROFILE_ID_ARGUMENT_KEY = "StateFragmentPresenter.state_fragment_profile_id" @@ -304,6 +305,14 @@ class StateFragmentPresenter @Inject constructor( } } + private fun areListsTheSame(l: List, r: List): Boolean { + if (l.size != r.size) { + return false + } + + return l.zip(r).all { (x, y) -> x.areContentsTheSame(y) } + } + private fun processEphemeralState(ephemeralState: EphemeralState) { explorationCheckpointState = ephemeralState.checkpointState val shouldSplit = splitScreenManager.shouldSplitScreen(ephemeralState.state.interaction.id) @@ -329,10 +338,14 @@ class StateFragmentPresenter @Inject constructor( shouldSplit ) - viewModel.itemList.clear() - viewModel.itemList += dataPair.first - viewModel.rightItemList.clear() - viewModel.rightItemList += dataPair.second + if (!areListsTheSame(viewModel.itemList, dataPair.first)) { + viewModel.itemList.clear() + viewModel.itemList += dataPair.first + } + if (!areListsTheSame(viewModel.rightItemList, dataPair.second)) { + viewModel.rightItemList.clear() + viewModel.rightItemList += dataPair.second + } if (isInNewState) { (binding.stateRecyclerView.layoutManager as LinearLayoutManager).scrollToPositionWithOffset( diff --git a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ContentViewModel.kt b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ContentViewModel.kt index 5a581ea586b..b09c294246e 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ContentViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/ContentViewModel.kt @@ -7,4 +7,15 @@ class ContentViewModel( val hasConversationView: Boolean, val isSplitView: Boolean, val supportsConceptCards: Boolean -) : StateItemViewModel(ViewType.CONTENT) +) : StateItemViewModel(ViewType.CONTENT) { + override fun areContentsTheSame(other: StateItemViewModel): Boolean { + if (this === other) return true + if (other !is ContentViewModel) return false + + return htmlContent == other.htmlContent && + gcsEntityId == other.gcsEntityId && + hasConversationView == other.hasConversationView && + isSplitView == other.isSplitView && + supportsConceptCards == other.supportsConceptCards + } +} diff --git a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/FractionInteractionViewModel.kt b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/FractionInteractionViewModel.kt index 193248effe7..3afed42bc2d 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/FractionInteractionViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/FractionInteractionViewModel.kt @@ -56,6 +56,18 @@ class FractionInteractionViewModel private constructor( ) } + override fun areContentsTheSame(other: StateItemViewModel): Boolean { + if (this === other) return true + if (other !is FractionInteractionViewModel) return false + + return ( + hasConversationView == other.hasConversationView && + isSplitView == other.isSplitView && + pendingAnswerError == other.pendingAnswerError && + hintText == other.hintText + ) + } + override fun getPendingAnswer(): UserAnswer = UserAnswer.newBuilder().apply { if (answerText.isNotEmpty()) { val answerTextString = answerText.toString() diff --git a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/StateItemViewModel.kt b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/StateItemViewModel.kt index 3d93249cf7c..c077cc5b402 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/StateItemViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/StateItemViewModel.kt @@ -61,4 +61,8 @@ abstract class StateItemViewModel(val viewType: ViewType) : ObservableViewModel( timeToStartNoticeAnimationMs: Long? ): StateItemViewModel } + + open fun areContentsTheSame(other: StateItemViewModel): Boolean { + return false + } } diff --git a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/SubmitButtonViewModel.kt b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/SubmitButtonViewModel.kt index 073adea0828..7b191140074 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/SubmitButtonViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/SubmitButtonViewModel.kt @@ -12,4 +12,16 @@ class SubmitButtonViewModel( val previousNavigationButtonListener: PreviousNavigationButtonListener, val submitNavigationButtonListener: SubmitNavigationButtonListener, val isSplitView: Boolean -) : StateItemViewModel(ViewType.SUBMIT_ANSWER_BUTTON) +) : StateItemViewModel(ViewType.SUBMIT_ANSWER_BUTTON) { + override fun areContentsTheSame(other: StateItemViewModel): Boolean { + if (this === other) return true + if (other !is SubmitButtonViewModel) return false + + return ( + canSubmitAnswer.get() == other.canSubmitAnswer.get() && + hasConversationView == other.hasConversationView && + hasPreviousButton == other.hasPreviousButton && + isSplitView == other.isSplitView + ) + } +} From 8dd89f831306c8435342fd82b9a94c5906f40953 Mon Sep 17 00:00:00 2001 From: Shubhadeep_Karmakar Date: Sat, 10 Feb 2024 23:15:51 +0530 Subject: [PATCH 2/2] lint --- .../app/player/state/StateFragmentPresenter.kt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/player/state/StateFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/state/StateFragmentPresenter.kt index 4a0c98dd4a7..c9bb86f6a47 100755 --- a/app/src/main/java/org/oppia/android/app/player/state/StateFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/StateFragmentPresenter.kt @@ -33,6 +33,7 @@ import org.oppia.android.app.player.audio.AudioUiManager import org.oppia.android.app.player.state.ConfettiConfig.LARGE_CONFETTI_BURST import org.oppia.android.app.player.state.ConfettiConfig.MEDIUM_CONFETTI_BURST import org.oppia.android.app.player.state.ConfettiConfig.MINI_CONFETTI_BURST +import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel import org.oppia.android.app.player.state.listener.RouteToHintsAndSolutionListener import org.oppia.android.app.player.stopplaying.StopStatePlayingSessionWithSavedProgressListener import org.oppia.android.app.survey.SurveyWelcomeDialogFragment @@ -54,7 +55,6 @@ import org.oppia.android.util.gcsresource.DefaultResourceBucketName import org.oppia.android.util.parser.html.ExplorationHtmlParserEntityType import org.oppia.android.util.system.OppiaClock import javax.inject.Inject -import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel const val STATE_FRAGMENT_PROFILE_ID_ARGUMENT_KEY = "StateFragmentPresenter.state_fragment_profile_id" @@ -259,7 +259,9 @@ class StateFragmentPresenter @Inject constructor( ) .addHintsAndSolutionsSupport() .addAudioVoiceoverSupport( - explorationId, viewModel.currentStateName, viewModel.isAudioBarVisible, + explorationId, + viewModel.currentStateName, + viewModel.isAudioBarVisible, this::getAudioUiManager ) .addConceptCardSupport() @@ -413,7 +415,9 @@ class StateFragmentPresenter @Inject constructor( return when (ephemeralStateResult) { is AsyncResult.Failure -> { oppiaLogger.e( - "StateFragment", "Failed to retrieve answer outcome", ephemeralStateResult.error + "StateFragment", + "Failed to retrieve answer outcome", + ephemeralStateResult.error ) AnswerOutcome.getDefaultInstance() } @@ -478,7 +482,6 @@ class StateFragmentPresenter @Inject constructor( } private fun showHintsAndSolutions(helpIndex: HelpIndex, isCurrentStatePendingState: Boolean) { - if (!isCurrentStatePendingState) { // If current state is not the pending top state, hide the hint bulb. setHintOpenedAndUnRevealed(false) @@ -512,7 +515,6 @@ class StateFragmentPresenter @Inject constructor( private fun setHintOpenedAndUnRevealed(isHintUnrevealed: Boolean) { viewModel.setHintOpenedAndUnRevealedVisibility(isHintUnrevealed) if (isHintUnrevealed) { - val hintBulbAnimation = AnimationUtils.loadAnimation( context, R.anim.hint_bulb_animation