Skip to content

Commit

Permalink
Fix #1593: Landscape support for Hints & Solution (#1615)
Browse files Browse the repository at this point in the history
* fix landscape crash

* fix visibility issues

* fix collapse expanded items on click other item

* fix ktlint
  • Loading branch information
anandwana001 authored Aug 15, 2020
1 parent c554fe0 commit 3fb2b1a
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,13 @@ package org.oppia.app.hintsandsolution
* This mainly helps to maintain the state during configuration change.
*/
interface ExpandedHintListIndexListener {

/** Manage expanded list icon */
fun onExpandListIconClicked(index: Int?)

/** Manage reveal hint button visibility while orientation change */
fun onRevealHintClicked(index: Int?, isHintRevealed: Boolean?)

/** Manage reveal solution button visibility while orientation change */
fun onRevealSolutionClicked(solutionIndex: Int?, isSolutionRevealed: Boolean?)
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ class HintsAndSolutionAdapter(
private val explorationId: String?,
private val htmlParserFactory: HtmlParser.Factory,
private val resourceBucketName: String,
private val entityType: String
private val entityType: String,
private val hintIndex: Int?,
private val isHintRevealed: Boolean?,
private val solutionIndex: Int?,
private val isSolutionRevealed: Boolean?
) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {

Expand Down Expand Up @@ -94,6 +98,15 @@ class HintsAndSolutionAdapter(
isHintListVisible = currentExpandedHintListIndex!! == position
}
binding.isListExpanded = isHintListVisible

hintIndex?.let {
isHintRevealed?.let {
if (hintIndex == position && isHintRevealed) {
hintsViewModel.isHintRevealed.set(true)
}
}
}

binding.viewModel = hintsViewModel

if (hintsViewModel.isHintRevealed.get()!!) {
Expand All @@ -114,14 +127,19 @@ class HintsAndSolutionAdapter(
binding.root.visibility = View.VISIBLE
binding.revealHintButton.setOnClickListener {
hintsViewModel.isHintRevealed.set(true)
expandedHintListIndexListener.onRevealHintClicked(position, /* isHintRevealed= */ true)
(fragment.requireActivity() as? RevealHintListener)?.revealHint(true, position)
val previousIndex: Int? = currentExpandedHintListIndex
currentExpandedHintListIndex =
if (currentExpandedHintListIndex != null && currentExpandedHintListIndex == position) {
null
} else {
position
}
expandedHintListIndexListener.onExpandListIconClicked(currentExpandedHintListIndex)
if (previousIndex != null && previousIndex != currentExpandedHintListIndex) {
notifyItemChanged(previousIndex)
}
}
}

Expand Down Expand Up @@ -161,6 +179,15 @@ class HintsAndSolutionAdapter(
isHintListVisible = currentExpandedHintListIndex!! == position
}
binding.isListExpanded = isHintListVisible

solutionIndex?.let {
isSolutionRevealed?.let {
if (solutionIndex == position && isSolutionRevealed) {
solutionViewModel.isSolutionRevealed.set(true)
}
}
}

binding.viewModel = solutionViewModel
binding.root.visibility = View.GONE
binding.solutionTitle.text = solutionViewModel.title.get()!!.capitalize()
Expand Down Expand Up @@ -226,8 +253,24 @@ class HintsAndSolutionAdapter(
if (itemList[itemList.size - 1] is SolutionViewModel) {
val solutionViewModel = itemList[itemList.size - 1] as SolutionViewModel
solutionViewModel.isSolutionRevealed.set(saveUserChoice)
expandedHintListIndexListener.onRevealSolutionClicked(
/* solutionIndex= */ itemList.size - 1,
/* isSolutionRevealed= */ true
)
(fragment.requireActivity() as? RevealSolutionInterface)?.revealSolution(saveUserChoice)
notifyItemChanged(itemList.size - 1)
val previousIndex: Int? = currentExpandedHintListIndex
currentExpandedHintListIndex =
if (currentExpandedHintListIndex != null &&
currentExpandedHintListIndex == itemList.size - 1
) {
null
} else {
itemList.size - 1
}
expandedHintListIndexListener.onExpandListIconClicked(currentExpandedHintListIndex)
if (previousIndex != null && previousIndex != currentExpandedHintListIndex) {
notifyItemChanged(previousIndex)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import org.oppia.app.model.State
import javax.inject.Inject

private const val CURRENT_EXPANDED_LIST_INDEX_SAVED_KEY = "CURRENT_EXPANDED_LIST_INDEX"
private const val STATE_SAVED_KEY = "STATE_SAVED_KEY"
private const val HINT_INDEX_SAVED_KEY = "HINT_INDEX_SAVED_KEY"
private const val IS_HINT_REVEALED_SAVED_KEY = "IS_HINT_REVEALED_SAVED_KEY"
private const val SOLUTION_INDEX_SAVED_KEY = "SOLUTION_INDEX_SAVED_KEY"
private const val IS_SOLUTION_REVEALED_SAVED_KEY = "IS_SOLUTION_REVEALED_SAVED_KEY"

/* Fragment that displays a fullscreen dialog for Hints and Solutions. */
class HintsAndSolutionDialogFragment :
Expand All @@ -25,6 +30,11 @@ class HintsAndSolutionDialogFragment :

private var currentExpandedHintListIndex: Int? = null

private var index: Int? = null
private var isHintRevealed: Boolean? = null
private var solutionIndex: Int? = null
private var isSolutionRevealed: Boolean? = null

companion object {

internal const val ID_ARGUMENT_KEY = "ID"
Expand Down Expand Up @@ -74,6 +84,13 @@ class HintsAndSolutionDialogFragment :
if (currentExpandedHintListIndex == -1) {
currentExpandedHintListIndex = null
}
state = State.parseFrom(savedInstanceState.getByteArray(STATE_SAVED_KEY)!!)
index = savedInstanceState.getInt(HINT_INDEX_SAVED_KEY, -1)
if (index == -1) index = null
isHintRevealed = savedInstanceState.getBoolean(IS_HINT_REVEALED_SAVED_KEY, false)
solutionIndex = savedInstanceState.getInt(SOLUTION_INDEX_SAVED_KEY, -1)
if (solutionIndex == -1) solutionIndex = null
isSolutionRevealed = savedInstanceState.getBoolean(IS_SOLUTION_REVEALED_SAVED_KEY, false)
}
val args =
checkNotNull(
Expand All @@ -100,7 +117,11 @@ class HintsAndSolutionDialogFragment :
currentExpandedHintListIndex,
newAvailableHintIndex,
allHintsExhausted,
this as ExpandedHintListIndexListener
this as ExpandedHintListIndexListener,
index,
isHintRevealed,
solutionIndex,
isSolutionRevealed
)
}

Expand All @@ -114,6 +135,19 @@ class HintsAndSolutionDialogFragment :
if (currentExpandedHintListIndex != null) {
outState.putInt(CURRENT_EXPANDED_LIST_INDEX_SAVED_KEY, currentExpandedHintListIndex!!)
}
if (index != null) {
outState.putInt(HINT_INDEX_SAVED_KEY, index!!)
}
if (isHintRevealed != null) {
outState.putBoolean(IS_HINT_REVEALED_SAVED_KEY, isHintRevealed!!)
}
if (solutionIndex != null) {
outState.putInt(SOLUTION_INDEX_SAVED_KEY, solutionIndex!!)
}
if (isSolutionRevealed != null) {
outState.putBoolean(IS_SOLUTION_REVEALED_SAVED_KEY, isSolutionRevealed!!)
}
outState.putByteArray(STATE_SAVED_KEY, state.toByteArray())
}

override fun onExpandListIconClicked(index: Int?) {
Expand All @@ -125,6 +159,21 @@ class HintsAndSolutionDialogFragment :
hintsAndSolutionDialogFragmentPresenter.handleRevealSolution(saveUserChoice)
}

override fun onRevealHintClicked(index: Int?, isHintRevealed: Boolean?) {
this.index = index
this.isHintRevealed = isHintRevealed
hintsAndSolutionDialogFragmentPresenter.onRevealHintClicked(index, isHintRevealed)
}

override fun onRevealSolutionClicked(solutionIndex: Int?, isSolutionRevealed: Boolean?) {
this.solutionIndex = solutionIndex
this.isSolutionRevealed = isSolutionRevealed
hintsAndSolutionDialogFragmentPresenter.onRevealSolutionClicked(
solutionIndex,
isSolutionRevealed
)
}

fun loadState(state: State) {
this.state = state
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import org.oppia.app.fragment.FragmentScope
import org.oppia.app.model.State
import org.oppia.app.viewmodel.ViewModelProvider
import org.oppia.util.gcsresource.DefaultResourceBucketName
import org.oppia.util.logging.ConsoleLogger
import org.oppia.util.parser.ExplorationHtmlParserEntityType
import org.oppia.util.parser.HtmlParser
import javax.inject.Inject
Expand All @@ -21,12 +20,15 @@ class HintsAndSolutionDialogFragmentPresenter @Inject constructor(
private val fragment: Fragment,
private val viewModelProvider: ViewModelProvider<HintsViewModel>,
private val htmlParserFactory: HtmlParser.Factory,
private val logger: ConsoleLogger,
@DefaultResourceBucketName private val resourceBucketName: String,
@ExplorationHtmlParserEntityType private val entityType: String
) {

private var currentExpandedHintListIndex: Int? = null
private var index: Int? = null
private var isHintRevealed: Boolean? = null
private var solutionIndex: Int? = null
private var isSolutionRevealed: Boolean? = null
private lateinit var expandedHintListIndexListener: ExpandedHintListIndexListener
private lateinit var hintsAndSolutionAdapter: HintsAndSolutionAdapter
private lateinit var binding: HintsAndSolutionFragmentBinding
Expand All @@ -48,13 +50,21 @@ class HintsAndSolutionDialogFragmentPresenter @Inject constructor(
currentExpandedHintListIndex: Int?,
newAvailableHintIndex: Int,
allHintsExhausted: Boolean,
expandedHintListIndexListener: ExpandedHintListIndexListener
expandedHintListIndexListener: ExpandedHintListIndexListener,
index: Int?,
isHintRevealed: Boolean?,
solutionIndex: Int?,
isSolutionRevealed: Boolean?
): View? {

binding =
HintsAndSolutionFragmentBinding.inflate(inflater, container, /* attachToRoot= */ false)
this.currentExpandedHintListIndex = currentExpandedHintListIndex
this.expandedHintListIndexListener = expandedHintListIndexListener
this.index = index
this.isHintRevealed = isHintRevealed
this.solutionIndex = solutionIndex
this.isSolutionRevealed = isSolutionRevealed
binding.hintsAndSolutionToolbar.setNavigationIcon(R.drawable.ic_close_white_24dp)
binding.hintsAndSolutionToolbar.setNavigationOnClickListener {
(fragment.requireActivity() as? HintsAndSolutionListener)?.dismiss()
Expand Down Expand Up @@ -89,7 +99,11 @@ class HintsAndSolutionDialogFragmentPresenter @Inject constructor(
viewModel.explorationId.get(),
htmlParserFactory,
resourceBucketName,
entityType
entityType,
index,
isHintRevealed,
solutionIndex,
isSolutionRevealed
)

binding.hintsAndSolutionRecyclerView.apply {
Expand Down Expand Up @@ -125,4 +139,14 @@ class HintsAndSolutionDialogFragmentPresenter @Inject constructor(
if (index != null)
hintsAndSolutionAdapter.notifyItemChanged(index)
}

fun onRevealHintClicked(index: Int?, isHintRevealed: Boolean?) {
this.index = index
this.isHintRevealed = isHintRevealed
}

fun onRevealSolutionClicked(solutionIndex: Int?, isSolutionRevealed: Boolean?) {
this.solutionIndex = solutionIndex
this.isSolutionRevealed = isSolutionRevealed
}
}
6 changes: 6 additions & 0 deletions app/src/main/res/layout/state_fragment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

<FrameLayout
android:id="@+id/hints_and_solution_fragment_placeholder"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>

<FrameLayout
android:id="@+id/hints_and_solution_fragment_container"
android:layout_width="wrap_content"
Expand Down

0 comments on commit 3fb2b1a

Please sign in to comment.