From fa56d1a32ed3bce54498379e2a9ace4a62f896d6 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sun, 1 May 2022 01:14:16 +0530
Subject: [PATCH 001/138] first approach
---
.../ExplorationCheckpointController.kt | 1 +
.../spotlight/SpotlightStateController.kt | 127 ++++++++++++++++++
model/src/main/proto/spotlight.proto | 47 +++++++
3 files changed, 175 insertions(+)
create mode 100644 domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
create mode 100644 model/src/main/proto/spotlight.proto
diff --git a/domain/src/main/java/org/oppia/android/domain/exploration/lightweightcheckpointing/ExplorationCheckpointController.kt b/domain/src/main/java/org/oppia/android/domain/exploration/lightweightcheckpointing/ExplorationCheckpointController.kt
index 21bf8e7767b..c1e3acf365d 100644
--- a/domain/src/main/java/org/oppia/android/domain/exploration/lightweightcheckpointing/ExplorationCheckpointController.kt
+++ b/domain/src/main/java/org/oppia/android/domain/exploration/lightweightcheckpointing/ExplorationCheckpointController.kt
@@ -16,6 +16,7 @@ import org.oppia.android.util.data.DataProviders
import org.oppia.android.util.data.DataProviders.Companion.transformAsync
import javax.inject.Inject
import javax.inject.Singleton
+import org.oppia.android.app.model.OnboardingActivitySpotlight
private const val CACHE_NAME = "exploration_checkpoint_database"
private const val RETRIEVE_EXPLORATION_CHECKPOINT_DATA_PROVIDER_ID =
diff --git a/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt b/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
new file mode 100644
index 00000000000..150154abc86
--- /dev/null
+++ b/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
@@ -0,0 +1,127 @@
+package org.oppia.android.domain.spotlight
+
+import javax.inject.Inject
+import javax.inject.Singleton
+import kotlinx.coroutines.Deferred
+import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.model.SpotlightCheckpointDatabase
+import org.oppia.android.app.model.SpotlightState
+import org.oppia.android.data.persistence.PersistentCacheStore
+import org.oppia.android.domain.oppialogger.OppiaLogger
+import org.oppia.android.util.data.AsyncResult
+import org.oppia.android.util.data.DataProvider
+import org.oppia.android.util.data.DataProviders
+import org.oppia.android.util.data.DataProviders.Companion.transformAsync
+
+private const val SPOTLIGHT_STATE_DATA_PROVIDER_ID = "spotlight_state_data_provider_id"
+private const val CACHE_NAME = "spotlight_checkpoint_database"
+private const val RECORD_SPOTLIGHT_CHECKPOINT_DATA_PROVIDER_ID =
+ "record_spotlight_checkpoint_provider_id"
+private const val RETRIEVE_SPOTLIGHT_CHECKPOINT_DATA_PROVIDER_ID =
+ "retrieve_spotlight_checkpoint_provider_id"
+
+@Singleton
+class SpotlightStateController @Inject constructor(
+ private val cacheStoreFactory: PersistentCacheStore.Factory,
+ private val oppiaLogger: OppiaLogger,
+ private val dataProviders: DataProviders,
+) {
+
+ class SpotlightStateNotFoundException(message: String) : Exception(message)
+
+ private val cacheStoreMap =
+ mutableMapOf>()
+
+ private fun recordSpotlightStateAsync(
+ profileId: ProfileId,
+ spotlightState: SpotlightState,
+ spotlightActivity: SpotlightActivity
+ ): Deferred {
+ return retrieveCacheStore(profileId).storeDataWithCustomChannelAsync(
+ updateInMemoryCache = true
+ ) {
+ val spotlightCheckpointDatabaseBuilder = it.toBuilder()
+
+ val checkpoint = spotlightCheckpointDatabaseBuilder
+ .setOnboardingSpotlightCheckpoint(
+
+ )
+
+
+ val spotlightCheckpointDatabase = spotlightCheckpointDatabaseBuilder.build()
+
+ Pair(spotlightCheckpointDatabase, checkpoint)
+ }
+ }
+
+ fun recordSpotlightState(
+ profileId: ProfileId,
+ spotlightState: SpotlightState,
+ spotlightActivity: SpotlightActivity
+ ): DataProvider {
+ val deferred = recordSpotlightStateAsync(
+ profileId,
+ spotlightState,
+ spotlightActivity
+ )
+ return dataProviders.createInMemoryDataProviderAsync(
+ RECORD_SPOTLIGHT_CHECKPOINT_DATA_PROVIDER_ID
+ ) {
+ return@createInMemoryDataProviderAsync AsyncResult.Success(deferred.await())
+ }
+ }
+
+ fun retrieveSpotlightState(
+ profileId: ProfileId,
+ explorationId: String,
+ spotlightActivity: SpotlightActivity
+ ): DataProvider {
+ return retrieveCacheStore(profileId)
+ .transformAsync(
+ RETRIEVE_SPOTLIGHT_CHECKPOINT_DATA_PROVIDER_ID
+ ) {
+
+ val checkpoint = it.onboardingSpotlightCheckpoint.spotlightState
+
+ if (checkpoint != null) {
+ AsyncResult.Success(checkpoint)
+ } else {
+ AsyncResult.Failure(SpotlightStateNotFoundException("State not found "))
+ }
+
+ }
+ }
+
+ private fun retrieveCacheStore(
+ profileId: ProfileId
+ ): PersistentCacheStore {
+ val cacheStore = if (profileId in cacheStoreMap) {
+ cacheStoreMap[profileId]!!
+ } else {
+ val cacheStore =
+ cacheStoreFactory.createPerProfile(
+ CACHE_NAME,
+ SpotlightCheckpointDatabase.getDefaultInstance(),
+ profileId
+ )
+ cacheStoreMap[profileId] = cacheStore
+ cacheStore
+ }
+
+ cacheStore.primeCacheAsync().invokeOnCompletion { throwable ->
+ throwable?.let {
+ oppiaLogger.e(
+ "SpotlightCheckpointController",
+ "Failed to prime cache ahead of data retrieval for SpotlightCheckpointController.",
+ it
+ )
+ }
+ }
+ return cacheStore
+ }
+}
+
+enum class SpotlightActivity {
+ ONBOARDING_ACTIVITY,
+ PROFILE_ACTIVITY
+}
\ No newline at end of file
diff --git a/model/src/main/proto/spotlight.proto b/model/src/main/proto/spotlight.proto
new file mode 100644
index 00000000000..1ea480badbd
--- /dev/null
+++ b/model/src/main/proto/spotlight.proto
@@ -0,0 +1,47 @@
+syntax = "proto3";
+
+package model;
+
+option java_package = "org.oppia.android.app.model";
+option java_multiple_files = true;
+
+message OnboardingActivitySpotlight{
+ SpotlightState spotlight_state = 1;
+
+ enum LastScreenViewed{
+ ONBOARDING_SCREEN_1 = 0;
+ ONBOARDING_SCREEN_2 = 1;
+ ONBOARDING_SCREEN_3 = 2;
+ ONBOARDING_SCREEN_4 = 3;
+ }
+
+ LastScreenViewed last_screen_viewed = 2;
+}
+
+enum SpotlightState{
+ SPOTLIGHT_STATE_COMPLETED = 0;
+ SPOTLIGHT_STATE_PARTIAL = 1;
+ SPOTLIGHT_STATE_DISMISSED = 2;
+ SPOTLIGHT_STATE_UNSPECIFIED = 3;
+}
+
+message ProfileActivitySpotlight{
+ SpotlightState spotlight_state = 1;
+
+ enum LastScreenViewed{
+ PROFILE_SCREEN_1 = 0;
+ PROFILE_SCREEN_2 = 1;
+ PROFILE_SCREEN_3 = 2;
+ }
+
+ LastScreenViewed last_screen_viewed = 2;
+}
+
+message SpotlightCheckpointDatabase {
+ OnboardingActivitySpotlight onboarding_spotlight_checkpoint = 1;
+ ProfileActivitySpotlight profile_spotlight_checkpoint = 2;
+}
+
+
+
+}
\ No newline at end of file
From 230420a40425a84359137d271c3e6d88bafa607d Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sun, 1 May 2022 16:11:06 +0530
Subject: [PATCH 002/138] before starting top down.
---
.../spotlight/SpotlightStateController.kt | 11 +++--
model/src/main/proto/spotlight.proto | 48 ++++++++-----------
2 files changed, 27 insertions(+), 32 deletions(-)
diff --git a/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt b/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
index 150154abc86..8e1307635cd 100644
--- a/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
+++ b/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
@@ -42,10 +42,15 @@ class SpotlightStateController @Inject constructor(
) {
val spotlightCheckpointDatabaseBuilder = it.toBuilder()
- val checkpoint = spotlightCheckpointDatabaseBuilder
- .setOnboardingSpotlightCheckpoint(
+ val checkpoint : SpotlightState = when (spotlightActivity) {
+ SpotlightActivity.ONBOARDING_ACTIVITY -> {
+ spotlightCheckpointDatabaseBuilder.onboardingSpotlightCheckpoint.spotlightState
+ }
+ SpotlightActivity.PROFILE_ACTIVITY -> {
+ spotlightCheckpointDatabaseBuilder.profileSpotlightCheckpoint.spotlightState
+ }
+ }
- )
val spotlightCheckpointDatabase = spotlightCheckpointDatabaseBuilder.build()
diff --git a/model/src/main/proto/spotlight.proto b/model/src/main/proto/spotlight.proto
index 1ea480badbd..85173ff4b42 100644
--- a/model/src/main/proto/spotlight.proto
+++ b/model/src/main/proto/spotlight.proto
@@ -5,43 +5,33 @@ package model;
option java_package = "org.oppia.android.app.model";
option java_multiple_files = true;
-message OnboardingActivitySpotlight{
- SpotlightState spotlight_state = 1;
+message SpotlightCheckpointDatabase{
+ OnboardingSpotlightCheckpoint onboarding_spotlight_checkpoint = 1 ;
+ ProfileSpotlightCheckpoint profile_spotlight_checkpoint = 2 ;
+}
- enum LastScreenViewed{
- ONBOARDING_SCREEN_1 = 0;
- ONBOARDING_SCREEN_2 = 1;
- ONBOARDING_SCREEN_3 = 2;
- ONBOARDING_SCREEN_4 = 3;
+message OnboardingSpotlightCheckpoint{
+ SpotlightState spotlight_state = 1 ;
+ enum LastScreenViewed {
+ ONBOARDING1 = 0;
+ ONBOARDING2 = 1;
}
-
LastScreenViewed last_screen_viewed = 2;
}
-enum SpotlightState{
- SPOTLIGHT_STATE_COMPLETED = 0;
- SPOTLIGHT_STATE_PARTIAL = 1;
- SPOTLIGHT_STATE_DISMISSED = 2;
- SPOTLIGHT_STATE_UNSPECIFIED = 3;
-}
-
-message ProfileActivitySpotlight{
- SpotlightState spotlight_state = 1;
-
- enum LastScreenViewed{
- PROFILE_SCREEN_1 = 0;
- PROFILE_SCREEN_2 = 1;
- PROFILE_SCREEN_3 = 2;
+message ProfileSpotlightCheckpoint{
+ SpotlightState spotlight_state = 1 ;
+ enum LastScreenViewed {
+ PROFILE1 = 0;
+ PROFILE2 = 1;
}
-
LastScreenViewed last_screen_viewed = 2;
}
-message SpotlightCheckpointDatabase {
- OnboardingActivitySpotlight onboarding_spotlight_checkpoint = 1;
- ProfileActivitySpotlight profile_spotlight_checkpoint = 2;
+enum SpotlightState{
+ SPOTLIGHT_STATE_UNKNOWN = 0 ;
+ SPOTLIGHT_STATE_PARTIAL = 1 ;
+ SPOTLIGHT_STATE_DISMISSED = 2 ;
+ SPOTLIGHT_STATE_COMPLETED = 3 ;
}
-
-
-}
\ No newline at end of file
From 38e9372e3f6001f32c7eac4967cc9e0e7beb88f6 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 2 May 2022 03:18:12 +0530
Subject: [PATCH 003/138] binding for spotlight onboarding
---
.../onboarding/OnboardingFragmentPresenter.kt | 62 +++++++++++++++++++
.../main/res/layout/onboarding_fragment.xml | 1 +
app/src/main/res/layout/overlay.xml | 60 ++++++++++++++++++
.../ExplorationCheckpointController.kt | 1 -
4 files changed, 123 insertions(+), 1 deletion(-)
create mode 100644 app/src/main/res/layout/overlay.xml
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index f359a4348c7..d19b4cc0968 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -3,11 +3,18 @@ package org.oppia.android.app.onboarding
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.view.animation.DecelerateInterpolator
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.viewpager2.widget.ViewPager2
+import com.takusemba.spotlight.OnSpotlightListener
+import com.takusemba.spotlight.OnTargetListener
+import com.takusemba.spotlight.Spotlight
+import com.takusemba.spotlight.Target
+import com.takusemba.spotlight.shape.Circle
+import java.util.*
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.recyclerview.BindableAdapter
@@ -18,6 +25,7 @@ import org.oppia.android.databinding.OnboardingSlideBinding
import org.oppia.android.databinding.OnboardingSlideFinalBinding
import org.oppia.android.util.statusbar.StatusBarColor
import javax.inject.Inject
+import org.oppia.android.databinding.OverlayBinding
/** The presenter for [OnboardingFragment]. */
@FragmentScope
@@ -30,6 +38,7 @@ class OnboardingFragmentPresenter @Inject constructor(
) : OnboardingNavigationListener {
private val dotsList = ArrayList()
private lateinit var binding: OnboardingFragmentBinding
+ private lateinit var overlayBinding: OverlayBinding
fun handleCreateView(inflater: LayoutInflater, container: ViewGroup?): View? {
binding = OnboardingFragmentBinding.inflate(
@@ -46,6 +55,7 @@ class OnboardingFragmentPresenter @Inject constructor(
}
setUpViewPager()
addDots()
+ startSpotlight(inflater, container)
return binding.root
}
@@ -213,4 +223,56 @@ class OnboardingFragmentPresenter @Inject constructor(
dotsList[index].alpha = alphaValue
}
}
+
+ private fun startSpotlight(inflater: LayoutInflater, container: ViewGroup?) {
+ val targets = ArrayList()
+
+// val firstRoot = FrameLayout(fragment.requireContext())
+// val first = fragment.layoutInflater.inflate(overlayBinding, firstRoot)
+
+ overlayBinding = OverlayBinding.inflate(inflater, container, false)
+
+ val firstTarget = Target.Builder()
+ .setAnchor(binding.onboardingFragmentNextImageView)
+ .setShape(Circle(100f))
+ .setOverlay(overlayBinding.root)
+ .setOnTargetListener(object : OnTargetListener {
+ override fun onStarted() {
+
+ }
+
+ override fun onEnded() {
+
+ }
+ })
+ .build()
+
+ targets.add(firstTarget)
+
+ // create spotlight
+ val spotlight = Spotlight.Builder(activity)
+ .setTargets(targets)
+ .setBackgroundColorRes(R.color.spotlightBackground)
+ .setDuration(1000L)
+ .setAnimation(DecelerateInterpolator(2f))
+ .setOnSpotlightListener(object : OnSpotlightListener {
+ override fun onStarted() {
+
+
+ }
+
+ override fun onEnded() {
+
+
+ }
+ })
+ .build()
+
+ spotlight.start()
+
+
+
+ binding.onboardingFragmentConstraintLayout?.setOnClickListener { spotlight.finish() }
+ }
}
+
diff --git a/app/src/main/res/layout/onboarding_fragment.xml b/app/src/main/res/layout/onboarding_fragment.xml
index 3fa73866ebb..0a1988f1448 100644
--- a/app/src/main/res/layout/onboarding_fragment.xml
+++ b/app/src/main/res/layout/onboarding_fragment.xml
@@ -16,6 +16,7 @@
diff --git a/app/src/main/res/layout/overlay.xml b/app/src/main/res/layout/overlay.xml
new file mode 100644
index 00000000000..b482d81711b
--- /dev/null
+++ b/app/src/main/res/layout/overlay.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/domain/src/main/java/org/oppia/android/domain/exploration/lightweightcheckpointing/ExplorationCheckpointController.kt b/domain/src/main/java/org/oppia/android/domain/exploration/lightweightcheckpointing/ExplorationCheckpointController.kt
index c1e3acf365d..21bf8e7767b 100644
--- a/domain/src/main/java/org/oppia/android/domain/exploration/lightweightcheckpointing/ExplorationCheckpointController.kt
+++ b/domain/src/main/java/org/oppia/android/domain/exploration/lightweightcheckpointing/ExplorationCheckpointController.kt
@@ -16,7 +16,6 @@ import org.oppia.android.util.data.DataProviders
import org.oppia.android.util.data.DataProviders.Companion.transformAsync
import javax.inject.Inject
import javax.inject.Singleton
-import org.oppia.android.app.model.OnboardingActivitySpotlight
private const val CACHE_NAME = "exploration_checkpoint_database"
private const val RETRIEVE_EXPLORATION_CHECKPOINT_DATA_PROVIDER_ID =
From e8910195f820212a77419654dcbae37d219d5f02 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 2 May 2022 03:22:01 +0530
Subject: [PATCH 004/138] add dependency
---
app/build.gradle | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/build.gradle b/app/build.gradle
index bfecf8b032b..64908295e46 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -176,6 +176,7 @@ dependencies {
'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1',
'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1',
'org.mockito:mockito-core:2.7.22',
+ 'com.github.takusemba:spotlight:2.0.5'
)
compileOnly(
'jakarta.xml.bind:jakarta.xml.bind-api:2.3.2',
From d08a69eff3c497defa12cab0834db7e7025f1d98 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Tue, 3 May 2022 01:36:10 +0530
Subject: [PATCH 005/138] onboarding spotlight activated
---
.../onboarding/OnboardingFragmentPresenter.kt | 138 ++++++++++++++----
.../app/onboarding/OnboardingViewModel.kt | 25 +++-
.../onboarding/SpotlightNavigationListener.kt | 8 +
app/src/main/res/layout/overlay.xml | 42 +++---
app/src/main/res/values/colors_migrating.xml | 1 +
.../spotlight/SpotlightStateController.kt | 54 ++++---
model/src/main/proto/spotlight.proto | 2 +-
7 files changed, 192 insertions(+), 78 deletions(-)
create mode 100644 app/src/main/java/org/oppia/android/app/onboarding/SpotlightNavigationListener.kt
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index d19b4cc0968..9ffff335f6b 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -8,6 +8,8 @@ import android.widget.ImageView
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.Observer
import androidx.viewpager2.widget.ViewPager2
import com.takusemba.spotlight.OnSpotlightListener
import com.takusemba.spotlight.OnTargetListener
@@ -15,30 +17,79 @@ import com.takusemba.spotlight.Spotlight
import com.takusemba.spotlight.Target
import com.takusemba.spotlight.shape.Circle
import java.util.*
+import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
+import org.oppia.android.app.model.OnboardingSpotlightCheckpoint
+import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.model.SpotlightState
import org.oppia.android.app.recyclerview.BindableAdapter
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.OnboardingFragmentBinding
import org.oppia.android.databinding.OnboardingSlideBinding
import org.oppia.android.databinding.OnboardingSlideFinalBinding
-import org.oppia.android.util.statusbar.StatusBarColor
-import javax.inject.Inject
import org.oppia.android.databinding.OverlayBinding
+import org.oppia.android.domain.spotlight.SpotlightActivity
+import org.oppia.android.domain.spotlight.SpotlightStateController
+import org.oppia.android.util.data.AsyncResult
+import org.oppia.android.util.data.DataProviders.Companion.toLiveData
+import org.oppia.android.util.statusbar.StatusBarColor
/** The presenter for [OnboardingFragment]. */
@FragmentScope
class OnboardingFragmentPresenter @Inject constructor(
+ private val spotlightStateController: SpotlightStateController,
private val activity: AppCompatActivity,
private val fragment: Fragment,
private val viewModelProvider: ViewModelProvider,
private val viewModelProviderFinalSlide: ViewModelProvider,
private val resourceHandler: AppLanguageResourceHandler
-) : OnboardingNavigationListener {
+) : OnboardingNavigationListener, SpotlightNavigationListener {
private val dotsList = ArrayList()
private lateinit var binding: OnboardingFragmentBinding
private lateinit var overlayBinding: OverlayBinding
+ private lateinit var spotlight: Spotlight
+
+ private val firstTarget by lazy {
+ Target.Builder()
+ .setAnchor(binding.onboardingFragmentNextImageView)
+ .setShape(Circle(60f))
+ .setOverlay(overlayBinding.root)
+ .setOnTargetListener(object : OnTargetListener {
+ override fun onStarted() {
+
+ }
+
+ override fun onEnded() {
+ getOnboardingViewModel().recordSpotlightCheckpoint(
+ OnboardingSpotlightCheckpoint.LastScreenViewed.ONBOARDING1,
+ SpotlightState.SPOTLIGHT_STATE_PARTIAL
+ )
+ }
+ })
+ .build()
+ }
+
+ private val secondTarget by lazy {
+ Target.Builder()
+ .setAnchor(binding.skipTextView)
+ .setShape(Circle(60f))
+ .setOverlay(overlayBinding.root)
+ .setOnTargetListener(object : OnTargetListener {
+ override fun onStarted() {
+
+ }
+
+ override fun onEnded() {
+ getOnboardingViewModel().recordSpotlightCheckpoint(
+ OnboardingSpotlightCheckpoint.LastScreenViewed.ONBOARDING2,
+ SpotlightState.SPOTLIGHT_STATE_COMPLETED
+ )
+ }
+ })
+ .build()
+ }
fun handleCreateView(inflater: LayoutInflater, container: ViewGroup?): View? {
binding = OnboardingFragmentBinding.inflate(
@@ -53,9 +104,15 @@ class OnboardingFragmentPresenter @Inject constructor(
it.presenter = this
it.viewModel = getOnboardingViewModel()
}
+ overlayBinding = OverlayBinding.inflate(inflater, container, false)
+ overlayBinding.let {
+ it.lifecycleOwner = fragment
+ it.presenter = this
+ it.viewModel = getOnboardingViewModel()
+ }
setUpViewPager()
addDots()
- startSpotlight(inflater, container)
+ computeLastSpotlightCheckpoint()
return binding.root
}
@@ -174,6 +231,17 @@ class OnboardingFragmentPresenter @Inject constructor(
binding.onboardingSlideViewPager.currentItem = TOTAL_NUMBER_OF_SLIDES - 1
}
+ override fun clickOnDismiss() {
+ spotlight.finish()
+ }
+
+ override fun clickOnNextTip() {
+ // use this interface to start the next tip
+
+ spotlight.next()
+
+ }
+
override fun clickOnNext() {
val position: Int = binding.onboardingSlideViewPager.currentItem + 1
binding.onboardingSlideViewPager.currentItem = position
@@ -224,33 +292,45 @@ class OnboardingFragmentPresenter @Inject constructor(
}
}
- private fun startSpotlight(inflater: LayoutInflater, container: ViewGroup?) {
+ private fun computeLastSpotlightCheckpoint() {
val targets = ArrayList()
-// val firstRoot = FrameLayout(fragment.requireContext())
-// val first = fragment.layoutInflater.inflate(overlayBinding, firstRoot)
-
- overlayBinding = OverlayBinding.inflate(inflater, container, false)
-
- val firstTarget = Target.Builder()
- .setAnchor(binding.onboardingFragmentNextImageView)
- .setShape(Circle(100f))
- .setOverlay(overlayBinding.root)
- .setOnTargetListener(object : OnTargetListener {
- override fun onStarted() {
-
+ val profileId = ProfileId.newBuilder()
+ .setInternalId(123)
+ .build()
+ val checkpointLiveData = spotlightStateController.retrieveSpotlightCheckpoint(
+ profileId,
+ SpotlightActivity.ONBOARDING_ACTIVITY
+ ).toLiveData()
+
+ checkpointLiveData.observe(fragment,
+ object : Observer> {
+ override fun onChanged(it: AsyncResult?) {
+ if (it is AsyncResult.Success) {
+ checkpointLiveData.removeObserver(this)
+ val spotlightState = (it.value as OnboardingSpotlightCheckpoint).spotlightState
+ if (spotlightState == SpotlightState.SPOTLIGHT_STATE_COMPLETED || spotlightState == SpotlightState.SPOTLIGHT_STATE_DISMISSED) {
+ return
+ } else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_PARTIAL) {
+ val lastScreenViewed = (it.value as OnboardingSpotlightCheckpoint).lastScreenViewed
+ when (lastScreenViewed) {
+ OnboardingSpotlightCheckpoint.LastScreenViewed.ONBOARDING1 -> {
+ targets.add(secondTarget)
+ startSpotlight(targets)
+ }
+ }
+ } else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_UNKNOWN) {
+ targets.add(firstTarget)
+ targets.add(secondTarget)
+ startSpotlight(targets)
+ }
+ }
}
- override fun onEnded() {
-
- }
})
- .build()
-
- targets.add(firstTarget)
-
- // create spotlight
- val spotlight = Spotlight.Builder(activity)
+ }
+ private fun startSpotlight(targets: ArrayList){
+ spotlight = Spotlight.Builder(activity)
.setTargets(targets)
.setBackgroundColorRes(R.color.spotlightBackground)
.setDuration(1000L)
@@ -258,21 +338,15 @@ class OnboardingFragmentPresenter @Inject constructor(
.setOnSpotlightListener(object : OnSpotlightListener {
override fun onStarted() {
-
}
override fun onEnded() {
-
}
})
.build()
spotlight.start()
-
-
-
- binding.onboardingFragmentConstraintLayout?.setOnClickListener { spotlight.finish() }
}
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt
index f7f80e412cb..37ecb40beb7 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt
@@ -2,16 +2,21 @@ package org.oppia.android.app.onboarding
import androidx.databinding.ObservableField
import androidx.lifecycle.ViewModel
+import javax.inject.Inject
import org.oppia.android.R
+import org.oppia.android.app.model.OnboardingSpotlightCheckpoint
+import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.model.SpotlightState
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ObservableViewModel
-import javax.inject.Inject
+import org.oppia.android.domain.spotlight.SpotlightStateController
private const val INITIAL_SLIDE_NUMBER = 0
/** [ViewModel] for [OnboardingFragment]. */
class OnboardingViewModel @Inject constructor(
- private val resourceHandler: AppLanguageResourceHandler
+ private val resourceHandler: AppLanguageResourceHandler,
+ private val spotlightStateController: SpotlightStateController
) : ObservableViewModel() {
val slideNumber = ObservableField(INITIAL_SLIDE_NUMBER)
val totalNumberOfSlides = TOTAL_NUMBER_OF_SLIDES
@@ -32,4 +37,20 @@ class OnboardingViewModel @Inject constructor(
totalNumberOfSlides.toString()
)
}
+
+ fun recordSpotlightCheckpoint(
+ lastScreenViewed: OnboardingSpotlightCheckpoint.LastScreenViewed,
+ spotlightState: SpotlightState
+ ) {
+ val checkpoint = OnboardingSpotlightCheckpoint.newBuilder()
+ .setLastScreenViewed(lastScreenViewed)
+ .setSpotlightState(spotlightState)
+ .build()
+
+ val profileId = ProfileId.newBuilder()
+ .setInternalId(123)
+ .build()
+ spotlightStateController.recordSpotlightCheckpoint(profileId, checkpoint)
+ }
+
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/SpotlightNavigationListener.kt b/app/src/main/java/org/oppia/android/app/onboarding/SpotlightNavigationListener.kt
new file mode 100644
index 00000000000..73ef73a95b0
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/onboarding/SpotlightNavigationListener.kt
@@ -0,0 +1,8 @@
+package org.oppia.android.app.onboarding
+
+interface SpotlightNavigationListener {
+
+ fun clickOnDismiss()
+
+ fun clickOnNextTip()
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/overlay.xml b/app/src/main/res/layout/overlay.xml
index b482d81711b..4cf68e89ae9 100644
--- a/app/src/main/res/layout/overlay.xml
+++ b/app/src/main/res/layout/overlay.xml
@@ -6,7 +6,7 @@
+ type="org.oppia.android.app.onboarding.SpotlightNavigationListener" />
-
+ app:layout_constraintTop_toTopOf="parent" />
-
+ android:layout_marginStart="10dp"
+ android:layout_marginTop="50dp"
+ android:text="dismiss"
+ android:textColor="#FFFFFF"
+ android:textSize="20sp"
+ android:textStyle="bold"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
\ No newline at end of file
diff --git a/app/src/main/res/values/colors_migrating.xml b/app/src/main/res/values/colors_migrating.xml
index b60e98afe83..a8d14e6f4f1 100644
--- a/app/src/main/res/values/colors_migrating.xml
+++ b/app/src/main/res/values/colors_migrating.xml
@@ -114,4 +114,5 @@
#A5D3EC
#674172
#7659B6
+ #BF000000
diff --git a/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt b/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
index 8e1307635cd..66bef9ac1c1 100644
--- a/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
+++ b/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
@@ -3,9 +3,10 @@ package org.oppia.android.domain.spotlight
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.Deferred
+import org.oppia.android.app.model.OnboardingSpotlightCheckpoint
import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.model.ProfileSpotlightCheckpoint
import org.oppia.android.app.model.SpotlightCheckpointDatabase
-import org.oppia.android.app.model.SpotlightState
import org.oppia.android.data.persistence.PersistentCacheStore
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.util.data.AsyncResult
@@ -34,40 +35,38 @@ class SpotlightStateController @Inject constructor(
private fun recordSpotlightStateAsync(
profileId: ProfileId,
- spotlightState: SpotlightState,
- spotlightActivity: SpotlightActivity
- ): Deferred {
+ checkpoint: Any,
+ ): Deferred {
return retrieveCacheStore(profileId).storeDataWithCustomChannelAsync(
updateInMemoryCache = true
) {
val spotlightCheckpointDatabaseBuilder = it.toBuilder()
- val checkpoint : SpotlightState = when (spotlightActivity) {
- SpotlightActivity.ONBOARDING_ACTIVITY -> {
- spotlightCheckpointDatabaseBuilder.onboardingSpotlightCheckpoint.spotlightState
+ val newCheckpoint : Any = when (checkpoint) {
+ is OnboardingSpotlightCheckpoint -> {
+ spotlightCheckpointDatabaseBuilder.setOnboardingSpotlightCheckpoint(checkpoint)
}
- SpotlightActivity.PROFILE_ACTIVITY -> {
- spotlightCheckpointDatabaseBuilder.profileSpotlightCheckpoint.spotlightState
+ is ProfileSpotlightCheckpoint -> {
+ spotlightCheckpointDatabaseBuilder.setProfileSpotlightCheckpoint(checkpoint)
+ }
+ else -> {
+ // throw exception
}
}
-
-
val spotlightCheckpointDatabase = spotlightCheckpointDatabaseBuilder.build()
- Pair(spotlightCheckpointDatabase, checkpoint)
+ Pair(spotlightCheckpointDatabase, newCheckpoint)
}
}
- fun recordSpotlightState(
+ fun recordSpotlightCheckpoint(
profileId: ProfileId,
- spotlightState: SpotlightState,
- spotlightActivity: SpotlightActivity
+ checkpoint: Any,
): DataProvider {
val deferred = recordSpotlightStateAsync(
profileId,
- spotlightState,
- spotlightActivity
+ checkpoint
)
return dataProviders.createInMemoryDataProviderAsync(
RECORD_SPOTLIGHT_CHECKPOINT_DATA_PROVIDER_ID
@@ -76,21 +75,28 @@ class SpotlightStateController @Inject constructor(
}
}
- fun retrieveSpotlightState(
+ fun retrieveSpotlightCheckpoint(
profileId: ProfileId,
- explorationId: String,
- spotlightActivity: SpotlightActivity
- ): DataProvider {
+ spotlightActivity: SpotlightActivity,
+ ): DataProvider {
return retrieveCacheStore(profileId)
.transformAsync(
RETRIEVE_SPOTLIGHT_CHECKPOINT_DATA_PROVIDER_ID
) {
- val checkpoint = it.onboardingSpotlightCheckpoint.spotlightState
- if (checkpoint != null) {
+ val checkpoint = when (spotlightActivity) {
+ SpotlightActivity.ONBOARDING_ACTIVITY -> {
+ it.onboardingSpotlightCheckpoint
+ }
+ SpotlightActivity.PROFILE_ACTIVITY -> {
+ it.profileSpotlightCheckpoint
+ }
+ }
+
+ if (checkpoint != null){
AsyncResult.Success(checkpoint)
- } else {
+ }else {
AsyncResult.Failure(SpotlightStateNotFoundException("State not found "))
}
diff --git a/model/src/main/proto/spotlight.proto b/model/src/main/proto/spotlight.proto
index 85173ff4b42..ea9b279cd0d 100644
--- a/model/src/main/proto/spotlight.proto
+++ b/model/src/main/proto/spotlight.proto
@@ -32,6 +32,6 @@ enum SpotlightState{
SPOTLIGHT_STATE_UNKNOWN = 0 ;
SPOTLIGHT_STATE_PARTIAL = 1 ;
SPOTLIGHT_STATE_DISMISSED = 2 ;
- SPOTLIGHT_STATE_COMPLETED = 3 ;
+ SPOTLIGHT_STATE_COMPLETED = 3 ; // take this to index 0.
}
From 2294c88cb68ece38c17cc218f7a2ad18db2de2cf Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Tue, 3 May 2022 22:49:13 +0530
Subject: [PATCH 006/138] add platform parameter
---
.../platformparameter/PlatformParameterModule.kt | 10 ++++++++++
.../platformparameter/PlatformParameterConstants.kt | 7 +++++++
2 files changed, 17 insertions(+)
diff --git a/domain/src/main/java/org/oppia/android/domain/platformparameter/PlatformParameterModule.kt b/domain/src/main/java/org/oppia/android/domain/platformparameter/PlatformParameterModule.kt
index c228216d7f0..e02aea37030 100644
--- a/domain/src/main/java/org/oppia/android/domain/platformparameter/PlatformParameterModule.kt
+++ b/domain/src/main/java/org/oppia/android/domain/platformparameter/PlatformParameterModule.kt
@@ -6,7 +6,9 @@ import org.oppia.android.util.platformparameter.CACHE_LATEX_RENDERING
import org.oppia.android.util.platformparameter.CACHE_LATEX_RENDERING_DEFAULT_VALUE
import org.oppia.android.util.platformparameter.CacheLatexRendering
import org.oppia.android.util.platformparameter.ENABLE_LANGUAGE_SELECTION_UI_DEFAULT_VALUE
+import org.oppia.android.util.platformparameter.ENABLE_SPOTLIGHT_UI_DEFAULT_VALUE
import org.oppia.android.util.platformparameter.EnableLanguageSelectionUi
+import org.oppia.android.util.platformparameter.EnableSpotlightUi
import org.oppia.android.util.platformparameter.LEARNER_STUDY_ANALYTICS
import org.oppia.android.util.platformparameter.LEARNER_STUDY_ANALYTICS_DEFAULT_VALUE
import org.oppia.android.util.platformparameter.LearnerStudyAnalytics
@@ -68,4 +70,12 @@ class PlatformParameterModule {
return platformParameterSingleton.getBooleanPlatformParameter(CACHE_LATEX_RENDERING)
?: PlatformParameterValue.createDefaultParameter(CACHE_LATEX_RENDERING_DEFAULT_VALUE)
}
+
+ @Provides
+ @EnableSpotlightUi
+ fun provideEnableSpotlightUi(): PlatformParameterValue {
+ return PlatformParameterValue.createDefaultParameter(
+ ENABLE_SPOTLIGHT_UI_DEFAULT_VALUE
+ )
+ }
}
diff --git a/utility/src/main/java/org/oppia/android/util/platformparameter/PlatformParameterConstants.kt b/utility/src/main/java/org/oppia/android/util/platformparameter/PlatformParameterConstants.kt
index 38d66b30d27..bcac10acfe8 100644
--- a/utility/src/main/java/org/oppia/android/util/platformparameter/PlatformParameterConstants.kt
+++ b/utility/src/main/java/org/oppia/android/util/platformparameter/PlatformParameterConstants.kt
@@ -92,3 +92,10 @@ const val CACHE_LATEX_RENDERING = "cache_latex_rendering"
/** Default value for whether to cache LaTeX rendering using Glide. */
const val CACHE_LATEX_RENDERING_DEFAULT_VALUE = true
+
+/** Qualifier for the feature flag corresponding to enabling the spotlight UI. */
+@Qualifier
+annotation class EnableSpotlightUi
+
+/** Default value for the feature flag corresponding to [EnableSpotlightUi]. */
+const val ENABLE_SPOTLIGHT_UI_DEFAULT_VALUE = true
From 3ee9884dbe2e4771278e0292b069387420e4846b Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Wed, 4 May 2022 04:12:27 +0530
Subject: [PATCH 007/138] topic spotlight activated
---
.../onboarding/OnboardingFragmentPresenter.kt | 1 -
.../oppia/android/app/topic/TopicFragment.kt | 8 +
.../app/topic/TopicFragmentPresenter.kt | 152 +++++++++++++++++-
.../oppia/android/app/topic/TopicViewModel.kt | 23 ++-
app/src/main/res/layout/overlay.xml | 4 +-
.../spotlight/SpotlightStateController.kt | 26 ++-
model/src/main/proto/spotlight.proto | 12 ++
7 files changed, 212 insertions(+), 14 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index 9ffff335f6b..9c1eecd2d0d 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -108,7 +108,6 @@ class OnboardingFragmentPresenter @Inject constructor(
overlayBinding.let {
it.lifecycleOwner = fragment
it.presenter = this
- it.viewModel = getOnboardingViewModel()
}
setUpViewPager()
addDots()
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
index 04d367b089e..5c48fd6c112 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
@@ -39,4 +39,12 @@ class TopicFragment : InjectableFragment() {
isConfigChanged = savedInstanceState != null
)
}
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+
+ super.onViewCreated(view, savedInstanceState)
+ topicFragmentPresenter.computeLastSpotlightCheckpoint()
+
+ }
+
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 102b24cf4ab..a97ee015538 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -3,12 +3,21 @@ package org.oppia.android.app.topic
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.view.animation.DecelerateInterpolator
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
+import androidx.core.view.get
import androidx.fragment.app.Fragment
+import androidx.lifecycle.Observer
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
+import com.takusemba.spotlight.OnSpotlightListener
+import com.takusemba.spotlight.OnTargetListener
+import com.takusemba.spotlight.Spotlight
+import com.takusemba.spotlight.Target
+import com.takusemba.spotlight.shape.Circle
+import java.util.*
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.translation.AppLanguageResourceHandler
@@ -17,6 +26,18 @@ import org.oppia.android.databinding.TopicFragmentBinding
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.util.system.OppiaClock
import javax.inject.Inject
+import org.oppia.android.app.model.OnboardingSpotlightCheckpoint
+import org.oppia.android.app.model.TopicSpotlightCheckpoint
+import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.model.SpotlightState
+import org.oppia.android.app.onboarding.SpotlightNavigationListener
+import org.oppia.android.databinding.OverlayBinding
+import org.oppia.android.domain.spotlight.SpotlightActivity
+import org.oppia.android.domain.spotlight.SpotlightStateController
+import org.oppia.android.util.data.AsyncResult
+import org.oppia.android.util.data.DataProviders.Companion.toLiveData
+import org.oppia.android.util.platformparameter.EnableSpotlightUi
+import org.oppia.android.util.platformparameter.PlatformParameterValue
/** The presenter for [TopicFragment]. */
@FragmentScope
@@ -26,14 +47,66 @@ class TopicFragmentPresenter @Inject constructor(
private val viewModelProvider: ViewModelProvider,
private val oppiaLogger: OppiaLogger,
private val oppiaClock: OppiaClock,
+ private val spotlightStateController: SpotlightStateController,
+ @EnableSpotlightUi private val enableSpotlightUi: PlatformParameterValue,
@EnablePracticeTab private val enablePracticeTab: Boolean,
private val resourceHandler: AppLanguageResourceHandler
-) {
+): SpotlightNavigationListener {
private lateinit var tabLayout: TabLayout
private var internalProfileId: Int = -1
private lateinit var topicId: String
private lateinit var storyId: String
private lateinit var viewPager: ViewPager2
+ private lateinit var overlayBinding: OverlayBinding
+ private lateinit var binding: TopicFragmentBinding
+ private lateinit var spotlight: Spotlight
+
+ private val firstTarget by lazy {
+
+ Target.Builder()
+ .setAnchor(getTab(0))
+ .setShape(Circle(80f))
+ .setOverlay(overlayBinding.root)
+ .setOnTargetListener(object : OnTargetListener {
+ override fun onStarted() {
+
+ }
+
+ override fun onEnded() {
+ getTopicViewModel().recordSpotlightCheckpoint(
+ TopicSpotlightCheckpoint.LastScreenViewed.TOPIC1,
+ SpotlightState.SPOTLIGHT_STATE_PARTIAL
+ )
+ }
+ })
+ .build()
+ }
+
+ private val secondTarget by lazy {
+
+ Target.Builder()
+ .setAnchor(getTab(1))
+ .setShape(Circle(80f))
+ .setOverlay(overlayBinding.root)
+ .setOnTargetListener(object : OnTargetListener {
+ override fun onStarted() {
+
+ }
+
+ override fun onEnded() {
+ getTopicViewModel().recordSpotlightCheckpoint(
+ TopicSpotlightCheckpoint.LastScreenViewed.TOPIC2,
+ SpotlightState.SPOTLIGHT_STATE_COMPLETED
+ )
+ }
+ })
+ .build()
+ }
+
+
+ fun getTab(position: Int): View{
+ return tabLayout.getTabAt(position)!!.view
+ }
fun handleCreateView(
inflater: LayoutInflater,
@@ -43,7 +116,7 @@ class TopicFragmentPresenter @Inject constructor(
storyId: String,
isConfigChanged: Boolean
): View? {
- val binding = TopicFragmentBinding.inflate(
+ binding = TopicFragmentBinding.inflate(
inflater,
container,
/* attachToRoot= */ false
@@ -63,12 +136,21 @@ class TopicFragmentPresenter @Inject constructor(
binding.topicToolbarTitle.isSelected = true
}
+ overlayBinding = OverlayBinding.inflate(inflater, container, false)
+ overlayBinding.let {
+ it.lifecycleOwner = fragment
+ it.presenter = this
+ }
+
val viewModel = getTopicViewModel()
viewModel.setInternalProfileId(internalProfileId)
viewModel.setTopicId(topicId)
binding.viewModel = viewModel
+
+
setUpViewPager(viewPager, topicId, isConfigChanged)
+
return binding.root
}
@@ -131,4 +213,70 @@ class TopicFragmentPresenter @Inject constructor(
oppiaLogger.createOpenRevisionTabContext(topicId)
)
}
+
+ fun computeLastSpotlightCheckpoint() {
+ val targets = ArrayList()
+
+ val profileId = ProfileId.newBuilder()
+ .setInternalId(internalProfileId)
+ .build()
+ val checkpointLiveData = spotlightStateController.retrieveSpotlightCheckpoint(
+ profileId,
+ SpotlightActivity.TOPIC_ACTIVITY
+ ).toLiveData()
+
+ checkpointLiveData.observe(fragment,
+ object : Observer> {
+ override fun onChanged(it: AsyncResult?) {
+ if (it is AsyncResult.Success) {
+ checkpointLiveData.removeObserver(this)
+ val spotlightState = (it.value as TopicSpotlightCheckpoint).spotlightState
+ if (spotlightState == SpotlightState.SPOTLIGHT_STATE_COMPLETED || spotlightState == SpotlightState.SPOTLIGHT_STATE_DISMISSED) {
+ return
+ } else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_PARTIAL) {
+ val lastScreenViewed = (it.value as TopicSpotlightCheckpoint).lastScreenViewed
+ when (lastScreenViewed) {
+ TopicSpotlightCheckpoint.LastScreenViewed.TOPIC1 -> {
+ targets.add(secondTarget)
+ startSpotlight(targets)
+ }
+ }
+ } else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_UNKNOWN) {
+ targets.add(firstTarget)
+ targets.add(secondTarget)
+ startSpotlight(targets)
+ }
+ }
+ }
+
+ })
+ }
+
+ private fun startSpotlight(targets: ArrayList){
+ spotlight = Spotlight.Builder(activity)
+ .setTargets(targets)
+ .setBackgroundColorRes(R.color.spotlightBackground)
+ .setDuration(1000L)
+ .setAnimation(DecelerateInterpolator(2f))
+ .setOnSpotlightListener(object : OnSpotlightListener {
+ override fun onStarted() {
+
+ }
+
+ override fun onEnded() {
+
+ }
+ })
+ .build()
+
+ spotlight.start()
+ }
+
+ override fun clickOnDismiss() {
+ spotlight.finish()
+ }
+
+ override fun clickOnNextTip() {
+ spotlight.next()
+ }
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt b/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
index 46d591d347a..0388648350d 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
@@ -13,13 +13,19 @@ import org.oppia.android.domain.topic.TopicController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import javax.inject.Inject
+import org.oppia.android.app.model.OnboardingSpotlightCheckpoint
+import org.oppia.android.app.model.ProfileSpotlightCheckpoint
+import org.oppia.android.app.model.SpotlightState
+import org.oppia.android.app.model.TopicSpotlightCheckpoint
+import org.oppia.android.domain.spotlight.SpotlightStateController
/** The ObservableViewModel for [TopicFragment]. */
@FragmentScope
class TopicViewModel @Inject constructor(
private val topicController: TopicController,
private val oppiaLogger: OppiaLogger,
- private val resourceHandler: AppLanguageResourceHandler
+ private val resourceHandler: AppLanguageResourceHandler,
+ private val spotlightStateController: SpotlightStateController
) : ObservableViewModel() {
private var internalProfileId: Int = -1
private lateinit var topicId: String
@@ -61,4 +67,19 @@ class TopicViewModel @Inject constructor(
is AsyncResult.Success -> topicResult.value
}
}
+
+ fun recordSpotlightCheckpoint(
+ lastScreenViewed: TopicSpotlightCheckpoint.LastScreenViewed,
+ spotlightState: SpotlightState
+ ) {
+ val checkpoint = TopicSpotlightCheckpoint.newBuilder()
+ .setLastScreenViewed(lastScreenViewed)
+ .setSpotlightState(spotlightState)
+ .build()
+
+ val profileId = ProfileId.newBuilder()
+ .setInternalId(internalProfileId)
+ .build()
+ spotlightStateController.recordSpotlightCheckpoint(profileId, checkpoint)
+ }
}
diff --git a/app/src/main/res/layout/overlay.xml b/app/src/main/res/layout/overlay.xml
index 4cf68e89ae9..2326661084f 100644
--- a/app/src/main/res/layout/overlay.xml
+++ b/app/src/main/res/layout/overlay.xml
@@ -8,9 +8,7 @@
name="presenter"
type="org.oppia.android.app.onboarding.SpotlightNavigationListener" />
-
+
>()
@@ -42,15 +44,19 @@ class SpotlightStateController @Inject constructor(
) {
val spotlightCheckpointDatabaseBuilder = it.toBuilder()
- val newCheckpoint : Any = when (checkpoint) {
+ val newCheckpoint: Any = when (checkpoint) {
is OnboardingSpotlightCheckpoint -> {
spotlightCheckpointDatabaseBuilder.setOnboardingSpotlightCheckpoint(checkpoint)
}
is ProfileSpotlightCheckpoint -> {
spotlightCheckpointDatabaseBuilder.setProfileSpotlightCheckpoint(checkpoint)
}
+ is TopicSpotlightCheckpoint -> {
+ spotlightCheckpointDatabaseBuilder.setTopicSpotlightCheckpoint(checkpoint)
+ }
else -> {
// throw exception
+ throw SpotlightActivityUnrecognizedException("spotlight activity is not one of the recognized types")
}
}
@@ -84,19 +90,24 @@ class SpotlightStateController @Inject constructor(
RETRIEVE_SPOTLIGHT_CHECKPOINT_DATA_PROVIDER_ID
) {
-
val checkpoint = when (spotlightActivity) {
- SpotlightActivity.ONBOARDING_ACTIVITY -> {
+ SpotlightActivity.ONBOARDING_ACTIVITY -> {
it.onboardingSpotlightCheckpoint
}
- SpotlightActivity.PROFILE_ACTIVITY -> {
+ SpotlightActivity.PROFILE_ACTIVITY -> {
it.profileSpotlightCheckpoint
}
+ SpotlightActivity.TOPIC_ACTIVITY -> {
+ it.topicSpotlightCheckpoint
+ }
+ else -> {
+ throw SpotlightActivityUnrecognizedException("spotlight activity is not one of the recognized types")
+ }
}
- if (checkpoint != null){
+ if (checkpoint != null) {
AsyncResult.Success(checkpoint)
- }else {
+ } else {
AsyncResult.Failure(SpotlightStateNotFoundException("State not found "))
}
@@ -134,5 +145,6 @@ class SpotlightStateController @Inject constructor(
enum class SpotlightActivity {
ONBOARDING_ACTIVITY,
- PROFILE_ACTIVITY
+ PROFILE_ACTIVITY,
+ TOPIC_ACTIVITY
}
\ No newline at end of file
diff --git a/model/src/main/proto/spotlight.proto b/model/src/main/proto/spotlight.proto
index ea9b279cd0d..c82d4ad891c 100644
--- a/model/src/main/proto/spotlight.proto
+++ b/model/src/main/proto/spotlight.proto
@@ -8,6 +8,7 @@ option java_multiple_files = true;
message SpotlightCheckpointDatabase{
OnboardingSpotlightCheckpoint onboarding_spotlight_checkpoint = 1 ;
ProfileSpotlightCheckpoint profile_spotlight_checkpoint = 2 ;
+ TopicSpotlightCheckpoint topic_spotlight_checkpoint = 3 ;
}
message OnboardingSpotlightCheckpoint{
@@ -28,6 +29,17 @@ message ProfileSpotlightCheckpoint{
LastScreenViewed last_screen_viewed = 2;
}
+message TopicSpotlightCheckpoint{
+ SpotlightState spotlight_state = 1 ;
+ enum LastScreenViewed {
+ TOPIC1 = 0;
+ TOPIC2 = 1;
+ TOPIC3 = 2;
+ TOPIC4 = 3;
+ }
+ LastScreenViewed last_screen_viewed = 2;
+}
+
enum SpotlightState{
SPOTLIGHT_STATE_UNKNOWN = 0 ;
SPOTLIGHT_STATE_PARTIAL = 1 ;
From 3eadee3d48b1ea86039b90a384d731c50b5c6280 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Wed, 4 May 2022 18:29:58 +0530
Subject: [PATCH 008/138] refactored and ready to document
---
.../onboarding/OnboardingFragmentPresenter.kt | 6 +--
.../oppia/android/app/topic/TopicFragment.kt | 5 +-
.../app/topic/TopicFragmentPresenter.kt | 53 ++++++++-----------
.../oppia/android/app/topic/TopicViewModel.kt | 8 +--
.../spotlight/SpotlightStateController.kt | 24 +++++++++
model/src/main/proto/spotlight.proto | 29 ++++++----
6 files changed, 75 insertions(+), 50 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index 9c1eecd2d0d..1717d4892ca 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -63,7 +63,7 @@ class OnboardingFragmentPresenter @Inject constructor(
override fun onEnded() {
getOnboardingViewModel().recordSpotlightCheckpoint(
- OnboardingSpotlightCheckpoint.LastScreenViewed.ONBOARDING1,
+ OnboardingSpotlightCheckpoint.LastScreenViewed.NEXT_BUTTON_SPOTLIGHT,
SpotlightState.SPOTLIGHT_STATE_PARTIAL
)
}
@@ -83,7 +83,7 @@ class OnboardingFragmentPresenter @Inject constructor(
override fun onEnded() {
getOnboardingViewModel().recordSpotlightCheckpoint(
- OnboardingSpotlightCheckpoint.LastScreenViewed.ONBOARDING2,
+ OnboardingSpotlightCheckpoint.LastScreenViewed.SKIP_BUTTON_SPOTLIGHT,
SpotlightState.SPOTLIGHT_STATE_COMPLETED
)
}
@@ -313,7 +313,7 @@ class OnboardingFragmentPresenter @Inject constructor(
} else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_PARTIAL) {
val lastScreenViewed = (it.value as OnboardingSpotlightCheckpoint).lastScreenViewed
when (lastScreenViewed) {
- OnboardingSpotlightCheckpoint.LastScreenViewed.ONBOARDING1 -> {
+ OnboardingSpotlightCheckpoint.LastScreenViewed.NEXT_BUTTON_SPOTLIGHT -> {
targets.add(secondTarget)
startSpotlight(targets)
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
index 5c48fd6c112..5b5685d6626 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
@@ -41,10 +41,11 @@ class TopicFragment : InjectableFragment() {
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-
super.onViewCreated(view, savedInstanceState)
- topicFragmentPresenter.computeLastSpotlightCheckpoint()
+ if (topicFragmentPresenter.enableSpotlightUi.value){
+ topicFragmentPresenter.retrieveCheckpointAndInitializeSpotlight()
+ }
}
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index a97ee015538..74881d281b2 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -6,7 +6,6 @@ import android.view.ViewGroup
import android.view.animation.DecelerateInterpolator
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
-import androidx.core.view.get
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.viewpager2.widget.ViewPager2
@@ -18,26 +17,25 @@ import com.takusemba.spotlight.Spotlight
import com.takusemba.spotlight.Target
import com.takusemba.spotlight.shape.Circle
import java.util.*
+import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
-import org.oppia.android.app.translation.AppLanguageResourceHandler
-import org.oppia.android.app.viewmodel.ViewModelProvider
-import org.oppia.android.databinding.TopicFragmentBinding
-import org.oppia.android.domain.oppialogger.OppiaLogger
-import org.oppia.android.util.system.OppiaClock
-import javax.inject.Inject
-import org.oppia.android.app.model.OnboardingSpotlightCheckpoint
-import org.oppia.android.app.model.TopicSpotlightCheckpoint
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.SpotlightState
+import org.oppia.android.app.model.TopicSpotlightCheckpoint
import org.oppia.android.app.onboarding.SpotlightNavigationListener
+import org.oppia.android.app.translation.AppLanguageResourceHandler
+import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.OverlayBinding
+import org.oppia.android.databinding.TopicFragmentBinding
+import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.spotlight.SpotlightActivity
import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.platformparameter.EnableSpotlightUi
import org.oppia.android.util.platformparameter.PlatformParameterValue
+import org.oppia.android.util.system.OppiaClock
/** The presenter for [TopicFragment]. */
@FragmentScope
@@ -48,10 +46,10 @@ class TopicFragmentPresenter @Inject constructor(
private val oppiaLogger: OppiaLogger,
private val oppiaClock: OppiaClock,
private val spotlightStateController: SpotlightStateController,
- @EnableSpotlightUi private val enableSpotlightUi: PlatformParameterValue,
+ @EnableSpotlightUi val enableSpotlightUi: PlatformParameterValue,
@EnablePracticeTab private val enablePracticeTab: Boolean,
private val resourceHandler: AppLanguageResourceHandler
-): SpotlightNavigationListener {
+) : SpotlightNavigationListener {
private lateinit var tabLayout: TabLayout
private var internalProfileId: Int = -1
private lateinit var topicId: String
@@ -61,31 +59,28 @@ class TopicFragmentPresenter @Inject constructor(
private lateinit var binding: TopicFragmentBinding
private lateinit var spotlight: Spotlight
- private val firstTarget by lazy {
-
+ private val infoTabSpotlightTarget by lazy {
Target.Builder()
- .setAnchor(getTab(0))
+ .setAnchor(getTab(TopicTab.INFO))
.setShape(Circle(80f))
.setOverlay(overlayBinding.root)
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
}
-
override fun onEnded() {
getTopicViewModel().recordSpotlightCheckpoint(
- TopicSpotlightCheckpoint.LastScreenViewed.TOPIC1,
- SpotlightState.SPOTLIGHT_STATE_PARTIAL
+ TopicSpotlightCheckpoint.LastScreenViewed.INFO_TAB_SPOTLIGHT,
)
}
})
.build()
}
- private val secondTarget by lazy {
+ private val lessonsTabSpotlightTarget by lazy {
Target.Builder()
- .setAnchor(getTab(1))
+ .setAnchor(getTab(TopicTab.LESSONS))
.setShape(Circle(80f))
.setOverlay(overlayBinding.root)
.setOnTargetListener(object : OnTargetListener {
@@ -95,17 +90,15 @@ class TopicFragmentPresenter @Inject constructor(
override fun onEnded() {
getTopicViewModel().recordSpotlightCheckpoint(
- TopicSpotlightCheckpoint.LastScreenViewed.TOPIC2,
- SpotlightState.SPOTLIGHT_STATE_COMPLETED
+ TopicSpotlightCheckpoint.LastScreenViewed.LESSONS_TAB_SPOTLIGHT,
)
}
})
.build()
}
-
- fun getTab(position: Int): View{
- return tabLayout.getTabAt(position)!!.view
+ private fun getTab(tab: TopicTab): View {
+ return tabLayout.getTabAt(tab.ordinal)!!.view
}
fun handleCreateView(
@@ -214,7 +207,7 @@ class TopicFragmentPresenter @Inject constructor(
)
}
- fun computeLastSpotlightCheckpoint() {
+ fun retrieveCheckpointAndInitializeSpotlight() {
val targets = ArrayList()
val profileId = ProfileId.newBuilder()
@@ -236,14 +229,14 @@ class TopicFragmentPresenter @Inject constructor(
} else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_PARTIAL) {
val lastScreenViewed = (it.value as TopicSpotlightCheckpoint).lastScreenViewed
when (lastScreenViewed) {
- TopicSpotlightCheckpoint.LastScreenViewed.TOPIC1 -> {
- targets.add(secondTarget)
+ TopicSpotlightCheckpoint.LastScreenViewed.INFO_TAB_SPOTLIGHT -> {
+ targets.add(lessonsTabSpotlightTarget)
startSpotlight(targets)
}
}
} else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_UNKNOWN) {
- targets.add(firstTarget)
- targets.add(secondTarget)
+ targets.add(infoTabSpotlightTarget)
+ targets.add(lessonsTabSpotlightTarget)
startSpotlight(targets)
}
}
@@ -252,7 +245,7 @@ class TopicFragmentPresenter @Inject constructor(
})
}
- private fun startSpotlight(targets: ArrayList){
+ private fun startSpotlight(targets: ArrayList) {
spotlight = Spotlight.Builder(activity)
.setTargets(targets)
.setBackgroundColorRes(R.color.spotlightBackground)
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt b/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
index 0388648350d..33f5d5d985c 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
@@ -13,9 +13,6 @@ import org.oppia.android.domain.topic.TopicController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import javax.inject.Inject
-import org.oppia.android.app.model.OnboardingSpotlightCheckpoint
-import org.oppia.android.app.model.ProfileSpotlightCheckpoint
-import org.oppia.android.app.model.SpotlightState
import org.oppia.android.app.model.TopicSpotlightCheckpoint
import org.oppia.android.domain.spotlight.SpotlightStateController
@@ -69,12 +66,11 @@ class TopicViewModel @Inject constructor(
}
fun recordSpotlightCheckpoint(
- lastScreenViewed: TopicSpotlightCheckpoint.LastScreenViewed,
- spotlightState: SpotlightState
+ lastScreenViewed: TopicSpotlightCheckpoint.LastScreenViewed
) {
val checkpoint = TopicSpotlightCheckpoint.newBuilder()
.setLastScreenViewed(lastScreenViewed)
- .setSpotlightState(spotlightState)
+ .setSpotlightState(spotlightStateController.computeSpotlightState(lastScreenViewed))
.build()
val profileId = ProfileId.newBuilder()
diff --git a/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt b/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
index a34be1911e7..5b12ac39958 100644
--- a/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
+++ b/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
@@ -7,6 +7,7 @@ import org.oppia.android.app.model.OnboardingSpotlightCheckpoint
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.ProfileSpotlightCheckpoint
import org.oppia.android.app.model.SpotlightCheckpointDatabase
+import org.oppia.android.app.model.SpotlightState
import org.oppia.android.app.model.TopicSpotlightCheckpoint
import org.oppia.android.data.persistence.PersistentCacheStore
import org.oppia.android.domain.oppialogger.OppiaLogger
@@ -141,6 +142,29 @@ class SpotlightStateController @Inject constructor(
}
return cacheStore
}
+
+ fun computeSpotlightState(lastScreenViewed: Any): SpotlightState {
+ return when (lastScreenViewed) {
+ is OnboardingSpotlightCheckpoint.LastScreenViewed -> {
+ if (lastScreenViewed.ordinal == OnboardingSpotlightCheckpoint.LastScreenViewed.values().size - 1)
+ SpotlightState.SPOTLIGHT_STATE_COMPLETED
+ else SpotlightState.SPOTLIGHT_STATE_PARTIAL
+ }
+ is ProfileSpotlightCheckpoint.LastScreenViewed -> {
+ if (lastScreenViewed.ordinal == ProfileSpotlightCheckpoint.LastScreenViewed.values().size - 1)
+ SpotlightState.SPOTLIGHT_STATE_COMPLETED
+ else SpotlightState.SPOTLIGHT_STATE_PARTIAL
+ }
+ is TopicSpotlightCheckpoint.LastScreenViewed -> {
+ if (lastScreenViewed.ordinal == TopicSpotlightCheckpoint.LastScreenViewed.values().size - 1)
+ SpotlightState.SPOTLIGHT_STATE_COMPLETED
+ else SpotlightState.SPOTLIGHT_STATE_PARTIAL
+ }
+ else -> {
+ throw SpotlightStateNotFoundException("couldn't find spotlight state")
+ }
+ }
+ }
}
enum class SpotlightActivity {
diff --git a/model/src/main/proto/spotlight.proto b/model/src/main/proto/spotlight.proto
index c82d4ad891c..e54362d6185 100644
--- a/model/src/main/proto/spotlight.proto
+++ b/model/src/main/proto/spotlight.proto
@@ -9,13 +9,15 @@ message SpotlightCheckpointDatabase{
OnboardingSpotlightCheckpoint onboarding_spotlight_checkpoint = 1 ;
ProfileSpotlightCheckpoint profile_spotlight_checkpoint = 2 ;
TopicSpotlightCheckpoint topic_spotlight_checkpoint = 3 ;
+ HomeSpotlightCheckpoint home_spotlight_checkpoint = 4;
+ ExplorationSpotlightCheckpoint exploration_spotlight_checkpoint = 5 ;
}
message OnboardingSpotlightCheckpoint{
SpotlightState spotlight_state = 1 ;
enum LastScreenViewed {
- ONBOARDING1 = 0;
- ONBOARDING2 = 1;
+ NEXT_BUTTON_SPOTLIGHT = 0;
+ SKIP_BUTTON_SPOTLIGHT = 1;
}
LastScreenViewed last_screen_viewed = 2;
}
@@ -23,8 +25,9 @@ message OnboardingSpotlightCheckpoint{
message ProfileSpotlightCheckpoint{
SpotlightState spotlight_state = 1 ;
enum LastScreenViewed {
- PROFILE1 = 0;
- PROFILE2 = 1;
+ NEW_PROFILE_BUTTON_SPOTLIGHT= 0;
+ ENTER_NAME_SPOTLIGHT = 1;
+ ADD_PIN_SPOTLIGHT = 2;
}
LastScreenViewed last_screen_viewed = 2;
}
@@ -32,18 +35,26 @@ message ProfileSpotlightCheckpoint{
message TopicSpotlightCheckpoint{
SpotlightState spotlight_state = 1 ;
enum LastScreenViewed {
- TOPIC1 = 0;
- TOPIC2 = 1;
- TOPIC3 = 2;
- TOPIC4 = 3;
+ INFO_TAB_SPOTLIGHT = 0;
+ LESSONS_TAB_SPOTLIGHT = 1;
+ PRACTICE_TAB_SPOTLIGHT = 2;
+ REVISION_TAB_SPOTLIGHT = 3;
}
LastScreenViewed last_screen_viewed = 2;
}
+message HomeSpotlightCheckpoint{
+
+}
+
+message ExplorationSpotlightCheckpoint{
+
+}
+
enum SpotlightState{
SPOTLIGHT_STATE_UNKNOWN = 0 ;
SPOTLIGHT_STATE_PARTIAL = 1 ;
SPOTLIGHT_STATE_DISMISSED = 2 ;
- SPOTLIGHT_STATE_COMPLETED = 3 ; // take this to index 0.
+ SPOTLIGHT_STATE_COMPLETED = 3 ;
}
From b4cad925683c79a68122aa669d0c5e7e80a61dd9 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Wed, 4 May 2022 19:29:29 +0530
Subject: [PATCH 009/138] refactored and ready to document
---
.../app/topic/TopicFragmentPresenter.kt | 53 ++++++++++++++++++-
1 file changed, 52 insertions(+), 1 deletion(-)
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 74881d281b2..dab47b7f8c4 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -66,7 +66,7 @@ class TopicFragmentPresenter @Inject constructor(
.setOverlay(overlayBinding.root)
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
-
+ // any additional behaviour
}
override fun onEnded() {
getTopicViewModel().recordSpotlightCheckpoint(
@@ -97,6 +97,46 @@ class TopicFragmentPresenter @Inject constructor(
.build()
}
+ private val practiceTabSpotlightTarget by lazy {
+
+ Target.Builder()
+ .setAnchor(getTab(TopicTab.PRACTICE))
+ .setShape(Circle(80f))
+ .setOverlay(overlayBinding.root)
+ .setOnTargetListener(object : OnTargetListener {
+ override fun onStarted() {
+
+ }
+
+ override fun onEnded() {
+ getTopicViewModel().recordSpotlightCheckpoint(
+ TopicSpotlightCheckpoint.LastScreenViewed.PRACTICE_TAB_SPOTLIGHT,
+ )
+ }
+ })
+ .build()
+ }
+
+ private val revisionTabSpotlightTarget by lazy {
+
+ Target.Builder()
+ .setAnchor(getTab(TopicTab.REVISION))
+ .setShape(Circle(80f))
+ .setOverlay(overlayBinding.root)
+ .setOnTargetListener(object : OnTargetListener {
+ override fun onStarted() {
+
+ }
+
+ override fun onEnded() {
+ getTopicViewModel().recordSpotlightCheckpoint(
+ TopicSpotlightCheckpoint.LastScreenViewed.REVISION_TAB_SPOTLIGHT,
+ )
+ }
+ })
+ .build()
+ }
+
private fun getTab(tab: TopicTab): View {
return tabLayout.getTabAt(tab.ordinal)!!.view
}
@@ -231,6 +271,17 @@ class TopicFragmentPresenter @Inject constructor(
when (lastScreenViewed) {
TopicSpotlightCheckpoint.LastScreenViewed.INFO_TAB_SPOTLIGHT -> {
targets.add(lessonsTabSpotlightTarget)
+ targets.add(practiceTabSpotlightTarget)
+ targets.add(revisionTabSpotlightTarget)
+ startSpotlight(targets)
+ }
+ TopicSpotlightCheckpoint.LastScreenViewed.LESSONS_TAB_SPOTLIGHT -> {
+ targets.add(practiceTabSpotlightTarget)
+ targets.add(revisionTabSpotlightTarget)
+ startSpotlight(targets)
+ }
+ TopicSpotlightCheckpoint.LastScreenViewed.PRACTICE_TAB_SPOTLIGHT -> {
+ targets.add(revisionTabSpotlightTarget)
startSpotlight(targets)
}
}
From 6c860d73289a73c95f45c81ac9b5283db3d743f1 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sun, 8 May 2022 03:36:22 +0530
Subject: [PATCH 010/138] refactored and ready to document
---
.../onboarding/OnboardingFragmentPresenter.kt | 20 ++++++-----------
.../app/onboarding/OnboardingViewModel.kt | 3 +--
.../onboarding/SpotlightNavigationListener.kt | 2 +-
.../oppia/android/app/topic/TopicFragment.kt | 3 +--
.../app/topic/TopicFragmentPresenter.kt | 22 ++++++++-----------
.../oppia/android/app/topic/TopicViewModel.kt | 4 ++--
app/src/main/res/layout/overlay.xml | 2 --
.../spotlight/SpotlightStateController.kt | 10 +++------
8 files changed, 24 insertions(+), 42 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index 1717d4892ca..177aa15d4c1 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -8,7 +8,6 @@ import android.widget.ImageView
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
-import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.viewpager2.widget.ViewPager2
import com.takusemba.spotlight.OnSpotlightListener
@@ -16,8 +15,6 @@ import com.takusemba.spotlight.OnTargetListener
import com.takusemba.spotlight.Spotlight
import com.takusemba.spotlight.Target
import com.takusemba.spotlight.shape.Circle
-import java.util.*
-import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.OnboardingSpotlightCheckpoint
@@ -35,6 +32,8 @@ import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.statusbar.StatusBarColor
+import java.util.*
+import javax.inject.Inject
/** The presenter for [OnboardingFragment]. */
@FragmentScope
@@ -58,7 +57,6 @@ class OnboardingFragmentPresenter @Inject constructor(
.setOverlay(overlayBinding.root)
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
-
}
override fun onEnded() {
@@ -78,7 +76,6 @@ class OnboardingFragmentPresenter @Inject constructor(
.setOverlay(overlayBinding.root)
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
-
}
override fun onEnded() {
@@ -238,7 +235,6 @@ class OnboardingFragmentPresenter @Inject constructor(
// use this interface to start the next tip
spotlight.next()
-
}
override fun clickOnNext() {
@@ -302,7 +298,8 @@ class OnboardingFragmentPresenter @Inject constructor(
SpotlightActivity.ONBOARDING_ACTIVITY
).toLiveData()
- checkpointLiveData.observe(fragment,
+ checkpointLiveData.observe(
+ fragment,
object : Observer> {
override fun onChanged(it: AsyncResult?) {
if (it is AsyncResult.Success) {
@@ -325,10 +322,10 @@ class OnboardingFragmentPresenter @Inject constructor(
}
}
}
-
- })
+ }
+ )
}
- private fun startSpotlight(targets: ArrayList){
+ private fun startSpotlight(targets: ArrayList) {
spotlight = Spotlight.Builder(activity)
.setTargets(targets)
.setBackgroundColorRes(R.color.spotlightBackground)
@@ -336,11 +333,9 @@ class OnboardingFragmentPresenter @Inject constructor(
.setAnimation(DecelerateInterpolator(2f))
.setOnSpotlightListener(object : OnSpotlightListener {
override fun onStarted() {
-
}
override fun onEnded() {
-
}
})
.build()
@@ -348,4 +343,3 @@ class OnboardingFragmentPresenter @Inject constructor(
spotlight.start()
}
}
-
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt
index 37ecb40beb7..c253d77a193 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt
@@ -2,7 +2,6 @@ package org.oppia.android.app.onboarding
import androidx.databinding.ObservableField
import androidx.lifecycle.ViewModel
-import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.model.OnboardingSpotlightCheckpoint
import org.oppia.android.app.model.ProfileId
@@ -10,6 +9,7 @@ import org.oppia.android.app.model.SpotlightState
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ObservableViewModel
import org.oppia.android.domain.spotlight.SpotlightStateController
+import javax.inject.Inject
private const val INITIAL_SLIDE_NUMBER = 0
@@ -52,5 +52,4 @@ class OnboardingViewModel @Inject constructor(
.build()
spotlightStateController.recordSpotlightCheckpoint(profileId, checkpoint)
}
-
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/SpotlightNavigationListener.kt b/app/src/main/java/org/oppia/android/app/onboarding/SpotlightNavigationListener.kt
index 73ef73a95b0..814d78f0588 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/SpotlightNavigationListener.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/SpotlightNavigationListener.kt
@@ -5,4 +5,4 @@ interface SpotlightNavigationListener {
fun clickOnDismiss()
fun clickOnNextTip()
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
index 5b5685d6626..7369c9851bf 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
@@ -43,9 +43,8 @@ class TopicFragment : InjectableFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- if (topicFragmentPresenter.enableSpotlightUi.value){
+ if (topicFragmentPresenter.enableSpotlightUi.value) {
topicFragmentPresenter.retrieveCheckpointAndInitializeSpotlight()
}
}
-
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index dab47b7f8c4..fd86b848d06 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -16,8 +16,6 @@ import com.takusemba.spotlight.OnTargetListener
import com.takusemba.spotlight.Spotlight
import com.takusemba.spotlight.Target
import com.takusemba.spotlight.shape.Circle
-import java.util.*
-import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.ProfileId
@@ -36,6 +34,8 @@ import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.platformparameter.EnableSpotlightUi
import org.oppia.android.util.platformparameter.PlatformParameterValue
import org.oppia.android.util.system.OppiaClock
+import java.util.*
+import javax.inject.Inject
/** The presenter for [TopicFragment]. */
@FragmentScope
@@ -67,6 +67,7 @@ class TopicFragmentPresenter @Inject constructor(
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
// any additional behaviour
+ overlayBinding.closeTarget.requestFocus()
}
override fun onEnded() {
getTopicViewModel().recordSpotlightCheckpoint(
@@ -85,7 +86,6 @@ class TopicFragmentPresenter @Inject constructor(
.setOverlay(overlayBinding.root)
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
-
}
override fun onEnded() {
@@ -105,7 +105,6 @@ class TopicFragmentPresenter @Inject constructor(
.setOverlay(overlayBinding.root)
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
-
}
override fun onEnded() {
@@ -125,7 +124,6 @@ class TopicFragmentPresenter @Inject constructor(
.setOverlay(overlayBinding.root)
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
-
}
override fun onEnded() {
@@ -180,8 +178,6 @@ class TopicFragmentPresenter @Inject constructor(
viewModel.setTopicId(topicId)
binding.viewModel = viewModel
-
-
setUpViewPager(viewPager, topicId, isConfigChanged)
return binding.root
@@ -258,13 +254,15 @@ class TopicFragmentPresenter @Inject constructor(
SpotlightActivity.TOPIC_ACTIVITY
).toLiveData()
- checkpointLiveData.observe(fragment,
+ checkpointLiveData.observe(
+ fragment,
object : Observer> {
override fun onChanged(it: AsyncResult?) {
if (it is AsyncResult.Success) {
checkpointLiveData.removeObserver(this)
val spotlightState = (it.value as TopicSpotlightCheckpoint).spotlightState
- if (spotlightState == SpotlightState.SPOTLIGHT_STATE_COMPLETED || spotlightState == SpotlightState.SPOTLIGHT_STATE_DISMISSED) {
+ if (spotlightState == SpotlightState.SPOTLIGHT_STATE_COMPLETED ||
+ spotlightState == SpotlightState.SPOTLIGHT_STATE_DISMISSED) {
return
} else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_PARTIAL) {
val lastScreenViewed = (it.value as TopicSpotlightCheckpoint).lastScreenViewed
@@ -292,8 +290,8 @@ class TopicFragmentPresenter @Inject constructor(
}
}
}
-
- })
+ }
+ )
}
private fun startSpotlight(targets: ArrayList) {
@@ -304,11 +302,9 @@ class TopicFragmentPresenter @Inject constructor(
.setAnimation(DecelerateInterpolator(2f))
.setOnSpotlightListener(object : OnSpotlightListener {
override fun onStarted() {
-
}
override fun onEnded() {
-
}
})
.build()
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt b/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
index 33f5d5d985c..79fcf14f0df 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
@@ -6,15 +6,15 @@ import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.Topic
+import org.oppia.android.app.model.TopicSpotlightCheckpoint
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ObservableViewModel
import org.oppia.android.domain.oppialogger.OppiaLogger
+import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.domain.topic.TopicController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import javax.inject.Inject
-import org.oppia.android.app.model.TopicSpotlightCheckpoint
-import org.oppia.android.domain.spotlight.SpotlightStateController
/** The ObservableViewModel for [TopicFragment]. */
@FragmentScope
diff --git a/app/src/main/res/layout/overlay.xml b/app/src/main/res/layout/overlay.xml
index 2326661084f..18e8e8dbed5 100644
--- a/app/src/main/res/layout/overlay.xml
+++ b/app/src/main/res/layout/overlay.xml
@@ -7,8 +7,6 @@
-
-
{
- // throw exception
throw SpotlightActivityUnrecognizedException("spotlight activity is not one of the recognized types")
}
}
-
val spotlightCheckpointDatabase = spotlightCheckpointDatabaseBuilder.build()
-
Pair(spotlightCheckpointDatabase, newCheckpoint)
}
}
@@ -111,7 +108,6 @@ class SpotlightStateController @Inject constructor(
} else {
AsyncResult.Failure(SpotlightStateNotFoundException("State not found "))
}
-
}
}
@@ -171,4 +167,4 @@ enum class SpotlightActivity {
ONBOARDING_ACTIVITY,
PROFILE_ACTIVITY,
TOPIC_ACTIVITY
-}
\ No newline at end of file
+}
From 98a086cbdfa54b598a3bd4162745b5c46d44768d Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sat, 25 Jun 2022 00:50:50 +0530
Subject: [PATCH 011/138] multiple overlay res added and partially working
---
.../SpotlightOverlayPositionAutomator.kt | 154 +++++++++
.../app/topic/TopicFragmentPresenter.kt | 309 ++++++++++++++++--
app/src/main/res/drawable/ic_arrow.xml | 7 +
.../drawable/ic_rounded_arrow_up_right.xml | 5 +
app/src/main/res/drawable/ic_roundedarrow.xml | 5 +
app/src/main/res/layout/overlay.xml | 22 +-
app/src/main/res/layout/overlay_over_left.xml | 68 ++++
.../main/res/layout/overlay_over_right.xml | 68 ++++
.../main/res/layout/overlay_under_left.xml | 68 ++++
.../main/res/layout/overlay_under_right.xml | 68 ++++
app/src/main/res/values/dimens.xml | 2 +
11 files changed, 738 insertions(+), 38 deletions(-)
create mode 100644 app/src/main/java/org/oppia/android/app/spotlight/SpotlightOverlayPositionAutomator.kt
create mode 100644 app/src/main/res/drawable/ic_arrow.xml
create mode 100644 app/src/main/res/drawable/ic_rounded_arrow_up_right.xml
create mode 100644 app/src/main/res/drawable/ic_roundedarrow.xml
create mode 100644 app/src/main/res/layout/overlay_over_left.xml
create mode 100644 app/src/main/res/layout/overlay_over_right.xml
create mode 100644 app/src/main/res/layout/overlay_under_left.xml
create mode 100644 app/src/main/res/layout/overlay_under_right.xml
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightOverlayPositionAutomator.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightOverlayPositionAutomator.kt
new file mode 100644
index 00000000000..667f8b57736
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightOverlayPositionAutomator.kt
@@ -0,0 +1,154 @@
+package org.oppia.android.app.spotlight
+
+import android.view.View
+import androidx.constraintlayout.widget.ConstraintSet
+import org.oppia.android.databinding.OverlayBinding
+
+class SpotlightOverlayPositionAutomator(private val anchor: View) {
+
+ // these will determine what arrow resource we will use (top, bottom, left, right facing)
+ private lateinit var overlayHintVerticalPosition: OverlayHintVerticalPosition
+ private lateinit var overlayHintHorizontalPosition: OverlayHintHorizontalPosition
+
+ private fun getAnchorTopMargin(): Int {
+ return anchor.top
+ }
+
+ private fun getAnchorBottomMargin(): Int {
+ return anchor.bottom
+ }
+
+ private fun getAnchorLeftMargin(): Int {
+ return anchor.left
+ }
+
+ private fun getAnchorRightMargin(): Int {
+ return anchor.right
+ }
+
+ private fun getAnchorHeight(): Int {
+ return anchor.height
+ }
+
+ private fun getAnchorWidth(): Int {
+ return anchor.width
+ }
+
+// private fun getArrowTopMargin(): Int {
+// return 0
+// TODO: this is only possible after reources can be accessed from this class. Not a necessity currently
+// }
+
+// private fun getArrowHeight(): Int{
+// resources.getDimensionPixelSize(R.dimen.arrow_height)
+// }
+
+ private fun calculateOverlayVerticalHintPosition() {
+ overlayHintVerticalPosition = if (getAnchorBottomMargin() > getAnchorTopMargin()) {
+ OverlayHintVerticalPosition.UNDER
+ } else OverlayHintVerticalPosition.OVER
+ }
+
+ private fun calculateOverlayHorizontalHintPosition() {
+ overlayHintHorizontalPosition = if (getAnchorLeftMargin() > getAnchorRightMargin()) {
+ OverlayHintHorizontalPosition.RIGHT
+ } else OverlayHintHorizontalPosition.LEFT
+ }
+
+ fun calculateArrowTopMargin(): Int {
+ calculateOverlayVerticalHintPosition()
+ return if (overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER) {
+ getAnchorTopMargin() + getAnchorHeight()
+ } else {
+ getAnchorBottomMargin() + getAnchorHeight()
+ }
+ }
+
+ fun setConstraints(binding: OverlayBinding) {
+ val set = ConstraintSet()
+
+ if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT && overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER){
+ set.connect(
+ binding.customText.id,
+ ConstraintSet.RIGHT,
+ binding.arrow.id,
+ ConstraintSet.RIGHT,
+ 0
+ )
+ set.connect(
+ binding.customText.id,
+ ConstraintSet.BOTTOM,
+ binding.arrow.id,
+ ConstraintSet.TOP,
+ 0
+ )
+ }
+ if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT && overlayHintVerticalPosition == OverlayHintVerticalPosition.OVER){
+ set.connect(
+ binding.customText.id,
+ ConstraintSet.RIGHT,
+ binding.arrow.id,
+ ConstraintSet.RIGHT,
+ 0
+ )
+ set.connect(
+ binding.customText.id,
+ ConstraintSet.TOP,
+ binding.arrow.id,
+ ConstraintSet.BOTTOM,
+ 0
+ )
+ }
+ if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.LEFT || overlayHintVerticalPosition == OverlayHintVerticalPosition.OVER){
+ set.connect(
+ binding.customText.id,
+ ConstraintSet.LEFT,
+ binding.arrow.id,
+ ConstraintSet.LEFT,
+ 0
+ )
+ set.connect(
+ binding.customText.id,
+ ConstraintSet.BOTTOM,
+ binding.arrow.id,
+ ConstraintSet.BOTTOM,
+ 0
+ )
+ }
+ if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.LEFT || overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER){
+ set.connect(
+ binding.customText.id,
+ ConstraintSet.LEFT,
+ binding.arrow.id,
+ ConstraintSet.LEFT,
+ 0
+ )
+ set.connect(
+ binding.customText.id,
+ ConstraintSet.BOTTOM,
+ binding.arrow.id,
+ ConstraintSet.TOP,
+ 0
+ )
+ }
+ }
+
+ fun calculateArrowLeftMargin(): Int {
+ calculateOverlayHorizontalHintPosition()
+ return if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT) {
+ getAnchorLeftMargin() + getAnchorWidth()
+ } else {
+ getAnchorLeftMargin() + 10
+ }
+ }
+
+ sealed class OverlayHintVerticalPosition {
+ object OVER : OverlayHintVerticalPosition()
+ object UNDER : OverlayHintVerticalPosition()
+ }
+
+ sealed class OverlayHintHorizontalPosition {
+ object RIGHT : OverlayHintHorizontalPosition()
+ object LEFT : OverlayHintHorizontalPosition()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index fd86b848d06..229eac99f67 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -1,10 +1,13 @@
package org.oppia.android.app.topic
+import android.content.res.Resources
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.DecelerateInterpolator
+import androidx.annotation.NonNull
import androidx.appcompat.app.AppCompatActivity
+import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
@@ -16,6 +19,9 @@ import com.takusemba.spotlight.OnTargetListener
import com.takusemba.spotlight.Spotlight
import com.takusemba.spotlight.Target
import com.takusemba.spotlight.shape.Circle
+import com.takusemba.spotlight.shape.RoundedRectangle
+import java.util.*
+import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.ProfileId
@@ -25,6 +31,10 @@ import org.oppia.android.app.onboarding.SpotlightNavigationListener
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.OverlayBinding
+import org.oppia.android.databinding.OverlayOverLeftBinding
+import org.oppia.android.databinding.OverlayOverRightBinding
+import org.oppia.android.databinding.OverlayUnderLeftBinding
+import org.oppia.android.databinding.OverlayUnderRightBinding
import org.oppia.android.databinding.TopicFragmentBinding
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.spotlight.SpotlightActivity
@@ -34,8 +44,6 @@ import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.platformparameter.EnableSpotlightUi
import org.oppia.android.util.platformparameter.PlatformParameterValue
import org.oppia.android.util.system.OppiaClock
-import java.util.*
-import javax.inject.Inject
/** The presenter for [TopicFragment]. */
@FragmentScope
@@ -55,43 +63,52 @@ class TopicFragmentPresenter @Inject constructor(
private lateinit var topicId: String
private lateinit var storyId: String
private lateinit var viewPager: ViewPager2
- private lateinit var overlayBinding: OverlayBinding
+ private lateinit var overlayBinding: Any
private lateinit var binding: TopicFragmentBinding
private lateinit var spotlight: Spotlight
+ private lateinit var anchor: View
+
private val infoTabSpotlightTarget by lazy {
+ anchor = getTab(TopicTab.INFO)
+
Target.Builder()
- .setAnchor(getTab(TopicTab.INFO))
- .setShape(Circle(80f))
- .setOverlay(overlayBinding.root)
+ .setAnchor(anchor)
+ .setShape(RoundedRectangle(anchor.height.toFloat(), anchor.width.toFloat(), 24f))
+ .setOverlay(getSpotlightOverlay()!!)
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
// any additional behaviour
- overlayBinding.closeTarget.requestFocus()
+
+// setConstraints()
+
}
+
override fun onEnded() {
- getTopicViewModel().recordSpotlightCheckpoint(
- TopicSpotlightCheckpoint.LastScreenViewed.INFO_TAB_SPOTLIGHT,
- )
+// getTopicViewModel().recordSpotlightCheckpoint(
+// TopicSpotlightCheckpoint.LastScreenViewed.INFO_TAB_SPOTLIGHT,
+// )
}
})
.build()
}
private val lessonsTabSpotlightTarget by lazy {
+ val anchor = getTab(TopicTab.LESSONS)
Target.Builder()
.setAnchor(getTab(TopicTab.LESSONS))
- .setShape(Circle(80f))
- .setOverlay(overlayBinding.root)
+ .setShape(RoundedRectangle(anchor.height.toFloat(), anchor.width.toFloat(), 24f))
+ .setOverlay(getSpotlightOverlay()!!)
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
+
}
override fun onEnded() {
- getTopicViewModel().recordSpotlightCheckpoint(
- TopicSpotlightCheckpoint.LastScreenViewed.LESSONS_TAB_SPOTLIGHT,
- )
+// getTopicViewModel().recordSpotlightCheckpoint(
+// TopicSpotlightCheckpoint.LastScreenViewed.LESSONS_TAB_SPOTLIGHT,
+// )
}
})
.build()
@@ -101,16 +118,16 @@ class TopicFragmentPresenter @Inject constructor(
Target.Builder()
.setAnchor(getTab(TopicTab.PRACTICE))
- .setShape(Circle(80f))
- .setOverlay(overlayBinding.root)
+ .setShape(RoundedRectangle(anchor.height.toFloat(), anchor.width.toFloat(), 24f))
+ .setOverlay(getSpotlightOverlay()!!)
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
}
override fun onEnded() {
- getTopicViewModel().recordSpotlightCheckpoint(
- TopicSpotlightCheckpoint.LastScreenViewed.PRACTICE_TAB_SPOTLIGHT,
- )
+// getTopicViewModel().recordSpotlightCheckpoint(
+// TopicSpotlightCheckpoint.LastScreenViewed.PRACTICE_TAB_SPOTLIGHT,
+// )
}
})
.build()
@@ -120,16 +137,16 @@ class TopicFragmentPresenter @Inject constructor(
Target.Builder()
.setAnchor(getTab(TopicTab.REVISION))
- .setShape(Circle(80f))
- .setOverlay(overlayBinding.root)
+ .setShape(RoundedRectangle(anchor.height.toFloat(), anchor.width.toFloat(), 24f))
+ .setOverlay(getSpotlightOverlay()!!)
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
}
override fun onEnded() {
- getTopicViewModel().recordSpotlightCheckpoint(
- TopicSpotlightCheckpoint.LastScreenViewed.REVISION_TAB_SPOTLIGHT,
- )
+// getTopicViewModel().recordSpotlightCheckpoint(
+// TopicSpotlightCheckpoint.LastScreenViewed.REVISION_TAB_SPOTLIGHT,
+// )
}
})
.build()
@@ -167,11 +184,7 @@ class TopicFragmentPresenter @Inject constructor(
binding.topicToolbarTitle.isSelected = true
}
- overlayBinding = OverlayBinding.inflate(inflater, container, false)
- overlayBinding.let {
- it.lifecycleOwner = fragment
- it.presenter = this
- }
+
val viewModel = getTopicViewModel()
viewModel.setInternalProfileId(internalProfileId)
@@ -262,7 +275,8 @@ class TopicFragmentPresenter @Inject constructor(
checkpointLiveData.removeObserver(this)
val spotlightState = (it.value as TopicSpotlightCheckpoint).spotlightState
if (spotlightState == SpotlightState.SPOTLIGHT_STATE_COMPLETED ||
- spotlightState == SpotlightState.SPOTLIGHT_STATE_DISMISSED) {
+ spotlightState == SpotlightState.SPOTLIGHT_STATE_DISMISSED
+ ) {
return
} else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_PARTIAL) {
val lastScreenViewed = (it.value as TopicSpotlightCheckpoint).lastScreenViewed
@@ -319,4 +333,237 @@ class TopicFragmentPresenter @Inject constructor(
override fun clickOnNextTip() {
spotlight.next()
}
+
+ val Int.dp: Int
+ get() = (this * Resources.getSystem().displayMetrics.density + 0.5f).toInt()
+
+ private lateinit var overlayHintVerticalPosition: OverlayHintVerticalPosition
+ private lateinit var overlayHintHorizontalPosition: OverlayHintHorizontalPosition
+
+ private fun getAnchorTopMargin(): Int {
+ return anchor.top
+ }
+
+ private fun getAnchorBottomMargin(): Int {
+ return anchor.bottom
+ }
+
+ private fun getAnchorLeftMargin(): Int {
+ return anchor.left
+ }
+
+ private fun getAnchorRightMargin(): Int {
+ return anchor.right
+ }
+
+ private fun getAnchorHeight(): Int {
+ return anchor.height
+ }
+
+ private fun getAnchorWidth(): Int {
+ return anchor.width
+ }
+
+// private fun getArrowTopMargin(): Int {
+// return 0
+// TODO: this is only possible after reources can be accessed from this class. Not a necessity currently
+// }
+
+// private fun getArrowHeight(): Int{
+// resources.getDimensionPixelSize(R.dimen.arrow_height)
+// }
+
+ private fun calculateOverlayVerticalHintPosition() {
+ overlayHintVerticalPosition = if (getAnchorBottomMargin() > getAnchorTopMargin()) {
+ OverlayHintVerticalPosition.UNDER
+ } else OverlayHintVerticalPosition.OVER
+ }
+
+ private fun calculateOverlayHorizontalHintPosition() {
+ overlayHintHorizontalPosition = if (getAnchorLeftMargin() > getAnchorRightMargin()) {
+ OverlayHintHorizontalPosition.RIGHT
+ } else OverlayHintHorizontalPosition.LEFT
+ }
+
+ private fun getSpotlightOverlay(): View? {
+
+ calculateOverlayHorizontalHintPosition()
+ calculateOverlayVerticalHintPosition()
+
+
+ if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT && overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER) {
+ overlayBinding = OverlayUnderRightBinding.inflate(fragment.layoutInflater)
+ (overlayBinding as OverlayUnderRightBinding).let {
+ it.lifecycleOwner = fragment
+ it.presenter = this
+ }
+ val arrowParams = (overlayBinding as OverlayUnderRightBinding).arrow.layoutParams as ViewGroup.MarginLayoutParams
+ arrowParams.setMargins(
+ calculateArrowLeftMargin().dp,
+ calculateArrowTopMargin().dp,
+ 10.dp,
+ 10.dp
+ )
+ (overlayBinding as OverlayUnderRightBinding).arrow.layoutParams = arrowParams
+
+ return (overlayBinding as OverlayUnderRightBinding).root
+ }
+
+ if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT && overlayHintVerticalPosition == OverlayHintVerticalPosition.OVER) {
+ overlayBinding = OverlayOverRightBinding.inflate(fragment.layoutInflater)
+ (overlayBinding as OverlayOverRightBinding).let {
+ it.lifecycleOwner = fragment
+ it.presenter = this
+ }
+
+ val arrowParams = (overlayBinding as OverlayOverRightBinding).arrow.layoutParams as ViewGroup.MarginLayoutParams
+ arrowParams.setMargins(
+ calculateArrowLeftMargin().dp,
+ calculateArrowTopMargin().dp,
+ 10.dp,
+ 10.dp
+ )
+ (overlayBinding as OverlayOverRightBinding).arrow.layoutParams = arrowParams
+
+ return (overlayBinding as OverlayOverRightBinding).root
+ }
+
+ if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.LEFT || overlayHintVerticalPosition == OverlayHintVerticalPosition.OVER) {
+ overlayBinding = OverlayOverLeftBinding.inflate(fragment.layoutInflater)
+ (overlayBinding as OverlayOverLeftBinding).let {
+ it.lifecycleOwner = fragment
+ it.presenter = this
+ }
+
+ val arrowParams = (overlayBinding as OverlayOverLeftBinding).arrow.layoutParams as ViewGroup.MarginLayoutParams
+ arrowParams.setMargins(
+ calculateArrowLeftMargin().dp,
+ calculateArrowTopMargin().dp,
+ 10.dp,
+ 10.dp
+ )
+ (overlayBinding as OverlayOverLeftBinding).arrow.layoutParams = arrowParams
+
+ return (overlayBinding as OverlayOverLeftBinding).root
+ }
+
+ if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.LEFT || overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER) {
+ overlayBinding = OverlayUnderLeftBinding.inflate(fragment.layoutInflater)
+ (overlayBinding as OverlayUnderLeftBinding).let {
+ it.lifecycleOwner = fragment
+ it.presenter = this
+ }
+
+ val arrowParams = (overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams as ViewGroup.MarginLayoutParams
+ arrowParams.setMargins(
+ calculateArrowLeftMargin().dp,
+ calculateArrowTopMargin().dp,
+ 10.dp,
+ 10.dp
+ )
+ (overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams = arrowParams
+
+ return (overlayBinding as OverlayUnderLeftBinding).root
+ }
+ return null
+ }
+
+ fun calculateArrowTopMargin(): Int {
+ calculateOverlayVerticalHintPosition()
+ return if (overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER) {
+ getAnchorTopMargin() + getAnchorHeight()
+ } else {
+ getAnchorBottomMargin() + getAnchorHeight()
+ }
+ }
+
+ fun setConstraints() {
+ val set = ConstraintSet()
+
+// if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT && overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER){
+// set.connect(
+// overlayBinding.customText.id,
+// ConstraintSet.RIGHT,
+// overlayBinding.arrow.id,
+// ConstraintSet.RIGHT,
+// 0
+// )
+// set.connect(
+// overlayBinding.customText.id,
+// ConstraintSet.BOTTOM,
+// overlayBinding.arrow.id,
+// ConstraintSet.TOP,
+// 0
+// )
+// }
+// if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT && overlayHintVerticalPosition == OverlayHintVerticalPosition.OVER){
+// set.connect(
+// overlayBinding.customText.id,
+// ConstraintSet.RIGHT,
+// overlayBinding.arrow.id,
+// ConstraintSet.RIGHT,
+// 0
+// )
+// set.connect(
+// overlayBinding.customText.id,
+// ConstraintSet.TOP,
+// overlayBinding.arrow.id,
+// ConstraintSet.BOTTOM,
+// 0
+// )
+// }
+// if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.LEFT || overlayHintVerticalPosition == OverlayHintVerticalPosition.OVER){
+// set.connect(
+// overlayBinding.customText.id,
+// ConstraintSet.LEFT,
+// overlayBinding.arrow.id,
+// ConstraintSet.LEFT,
+// 0
+// )
+// set.connect(
+// overlayBinding.customText.id,
+// ConstraintSet.BOTTOM,
+// overlayBinding.arrow.id,
+// ConstraintSet.BOTTOM,
+// 0
+// )
+// }
+// if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.LEFT || overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER){
+// set.connect(
+// overlayBinding.customText.id,
+// ConstraintSet.LEFT,
+// overlayBinding.arrow.id,
+// ConstraintSet.LEFT,
+// 0
+// )
+// set.connect(
+// overlayBinding.customText.id,
+// ConstraintSet.BOTTOM,
+// overlayBinding.arrow.id,
+// ConstraintSet.TOP,
+// 0
+// )
+// }
+
+// set.applyTo(overlayBinding.overlayConstraintLayout)
+ }
+
+ fun calculateArrowLeftMargin(): Int {
+ calculateOverlayHorizontalHintPosition()
+ return if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT) {
+ getAnchorLeftMargin() + getAnchorWidth()
+ } else {
+ getAnchorLeftMargin() + 10
+ }
+ }
+
+ sealed class OverlayHintVerticalPosition {
+ object OVER : OverlayHintVerticalPosition()
+ object UNDER : OverlayHintVerticalPosition()
+ }
+
+ sealed class OverlayHintHorizontalPosition {
+ object RIGHT : OverlayHintHorizontalPosition()
+ object LEFT : OverlayHintHorizontalPosition()
+ }
}
diff --git a/app/src/main/res/drawable/ic_arrow.xml b/app/src/main/res/drawable/ic_arrow.xml
new file mode 100644
index 00000000000..df1f0931b3e
--- /dev/null
+++ b/app/src/main/res/drawable/ic_arrow.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_rounded_arrow_up_right.xml b/app/src/main/res/drawable/ic_rounded_arrow_up_right.xml
new file mode 100644
index 00000000000..3d0adcd41ed
--- /dev/null
+++ b/app/src/main/res/drawable/ic_rounded_arrow_up_right.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_roundedarrow.xml b/app/src/main/res/drawable/ic_roundedarrow.xml
new file mode 100644
index 00000000000..7bbb1f2b141
--- /dev/null
+++ b/app/src/main/res/drawable/ic_roundedarrow.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/layout/overlay.xml b/app/src/main/res/layout/overlay.xml
index 18e8e8dbed5..0a2db44aaec 100644
--- a/app/src/main/res/layout/overlay.xml
+++ b/app/src/main/res/layout/overlay.xml
@@ -1,34 +1,42 @@
-
+
+
+
+
+ app:layout_constraintStart_toStartOf="@+id/arrow"
+ app:layout_constraintTop_toBottomOf="@id/arrow" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/overlay_over_right.xml b/app/src/main/res/layout/overlay_over_right.xml
new file mode 100644
index 00000000000..381c976a2cd
--- /dev/null
+++ b/app/src/main/res/layout/overlay_over_right.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/overlay_under_left.xml b/app/src/main/res/layout/overlay_under_left.xml
new file mode 100644
index 00000000000..05945c71e35
--- /dev/null
+++ b/app/src/main/res/layout/overlay_under_left.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/overlay_under_right.xml b/app/src/main/res/layout/overlay_under_right.xml
new file mode 100644
index 00000000000..7c22a5eabd9
--- /dev/null
+++ b/app/src/main/res/layout/overlay_under_right.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 3deaa804156..5f7ed332515 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -1,6 +1,8 @@
+ 57dp
+ 21dp
16dp
16dp
24dp
From 492392cc081862d7661cff3b0f84153868ee564f Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sun, 26 Jun 2022 04:11:46 +0530
Subject: [PATCH 012/138] using single overlay. Calculate screen size method
---
.../app/spotlight/OverlayPositionAutomator.kt | 179 +++++++++++
.../SpotlightOverlayPositionAutomator.kt | 275 ++++++++++-------
.../app/topic/TopicFragmentPresenter.kt | 283 ++----------------
app/src/main/res/layout/overlay.xml | 4 +-
app/src/main/res/layout/overlay_over_left.xml | 2 +-
.../main/res/layout/overlay_over_right.xml | 2 +-
.../main/res/layout/overlay_under_left.xml | 2 +-
.../main/res/layout/overlay_under_right.xml | 2 +-
8 files changed, 369 insertions(+), 380 deletions(-)
create mode 100644 app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt b/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
new file mode 100644
index 00000000000..969b0a6da30
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
@@ -0,0 +1,179 @@
+package org.oppia.android.app.spotlight
+
+import android.app.Activity
+import android.content.res.Resources
+import android.util.DisplayMetrics
+import android.util.Log
+import android.view.View
+import android.view.animation.DecelerateInterpolator
+import androidx.fragment.app.Fragment
+import com.takusemba.spotlight.OnSpotlightListener
+import com.takusemba.spotlight.Spotlight
+import com.takusemba.spotlight.Target
+import java.util.*
+import org.oppia.android.R
+import org.oppia.android.app.onboarding.SpotlightNavigationListener
+import org.oppia.android.databinding.OverlayBinding
+
+class OverlayPositionAutomator(private val activity: Activity, private val fragment: Fragment) :
+ SpotlightNavigationListener {
+ private lateinit var spotlight: Spotlight
+ private var screenHeight: Int = 0
+ private var screenWidth: Int = 0
+ private val overlay = "overlay"
+
+ private lateinit var anchorPosition: AnchorPosition
+ private lateinit var overlayBinding: OverlayBinding
+ private lateinit var anchor: View
+
+ init {
+ val displayMetrics = DisplayMetrics()
+ activity.windowManager.defaultDisplay.getMetrics(displayMetrics)
+
+ screenHeight = displayMetrics.heightPixels
+ screenWidth = displayMetrics.widthPixels
+ }
+
+ private fun getArrowHeight(): Float {
+ return fragment.resources.getDimension(R.dimen.arrow_height)
+ }
+
+ private fun getArrowWidth(): Float {
+ return fragment.resources.getDimension(R.dimen.arrow_width)
+ }
+
+ private fun initialiseAnchor(itemToSpotlight: View) {
+ anchor = itemToSpotlight
+ }
+
+ private fun getAnchorLeft(): Float {
+ return anchor.x
+ }
+
+ private fun getAnchorTop(): Float {
+ return anchor.y
+ }
+
+ private fun getAnchorBottom(): Float {
+ return anchor.bottom.dp.toFloat()
+ }
+
+ private fun getAnchorHeight(): Int {
+ return anchor.height
+ }
+
+ private fun getAnchorWidth(): Int {
+ return anchor.width
+ }
+
+ private fun getAnchorCentreX(): Float {
+ Log.d(overlay + "anchorCentre X ", (getAnchorLeft() + getAnchorWidth() / 2).toString())
+ return getAnchorLeft() + getAnchorWidth() / 2
+ }
+
+ private fun getAnchorCentreY(): Float {
+ Log.d(overlay + "anchorCentre Y ", (getAnchorTop() + getAnchorHeight() / 2).toString())
+ return getAnchorTop() + getAnchorHeight() / 2
+ }
+
+ private fun getScreenCentreX(): Int {
+ Log.d("overlay screenCentre X" , (screenHeight / 2).toString())
+ return screenWidth / 2
+ }
+
+ private fun getScreenCentreY(): Int {
+ Log.d("overlay screenCentre Y" , (screenHeight / 2).toString())
+ return screenHeight / 2
+ }
+
+ private fun calculateAnchorPosition() {
+ anchorPosition = if (getAnchorCentreX() > getScreenCentreX()) {
+ if (getAnchorCentreY() > getScreenCentreY()) {
+ AnchorPosition.BottomRight
+ } else {
+ AnchorPosition.TopRight
+ }
+ } else if (getAnchorCentreY() > getScreenCentreY()) {
+ AnchorPosition.BottomLeft
+ } else {
+ AnchorPosition.TopLeft
+ }
+
+ Log.d(overlay, anchorPosition.toString())
+ }
+
+ private fun setOverlayPosition() {
+ calculateAnchorPosition()
+
+ when (anchorPosition) {
+ AnchorPosition.TopLeft -> {
+ overlayBinding.arrow.x = getAnchorLeft()
+ overlayBinding.arrow.y = getAnchorBottom()
+ overlayBinding.customText.x = getAnchorLeft()
+ overlayBinding.customText.y =
+ getAnchorBottom() + getArrowHeight()
+ }
+ AnchorPosition.TopRight -> {
+ overlayBinding.arrow.x = getAnchorLeft() + getAnchorWidth() - getArrowWidth()
+ overlayBinding.arrow.y = getAnchorBottom()
+ overlayBinding.customText.right = (getAnchorLeft() + getAnchorWidth()).toInt()
+ overlayBinding.customText.y =
+ getAnchorBottom() + getArrowHeight()
+ }
+ else -> {
+
+ }
+ }
+ }
+
+ fun getSpotlightOverlay(anchor: View): View {
+ initialiseAnchor(anchor)
+
+ overlayBinding = OverlayBinding.inflate(fragment.layoutInflater)
+ overlayBinding.let {
+ it.lifecycleOwner = fragment
+ it.presenter = this
+ }
+
+ setOverlayPosition()
+
+ return overlayBinding.root
+ }
+
+ sealed class AnchorPosition {
+ object TopLeft : AnchorPosition()
+ object TopRight : AnchorPosition()
+ object BottomLeft : AnchorPosition()
+ object BottomRight : AnchorPosition()
+ }
+
+ fun startSpotlight(targets: ArrayList) {
+ spotlight = Spotlight.Builder(activity)
+ .setTargets(targets)
+ .setBackgroundColorRes(R.color.spotlightBackground)
+ .setDuration(1000L)
+ .setAnimation(DecelerateInterpolator(2f))
+ .setOnSpotlightListener(object : OnSpotlightListener {
+ override fun onStarted() {
+ }
+
+ override fun onEnded() {
+ }
+ })
+ .build()
+
+ spotlight.start()
+ }
+
+ override fun clickOnDismiss() {
+ spotlight.finish()
+ }
+
+ override fun clickOnNextTip() {
+ spotlight.next()
+ }
+
+ val Int.dp: Int
+ get() = (this * Resources.getSystem().displayMetrics.density + 0.5f).toInt()
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightOverlayPositionAutomator.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightOverlayPositionAutomator.kt
index 667f8b57736..647b7ad2212 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightOverlayPositionAutomator.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightOverlayPositionAutomator.kt
@@ -1,145 +1,173 @@
package org.oppia.android.app.spotlight
+import android.app.Activity
+import android.content.res.Resources
+import android.util.DisplayMetrics
import android.view.View
-import androidx.constraintlayout.widget.ConstraintSet
-import org.oppia.android.databinding.OverlayBinding
-
-class SpotlightOverlayPositionAutomator(private val anchor: View) {
+import android.view.ViewGroup
+import android.view.animation.DecelerateInterpolator
+import androidx.fragment.app.Fragment
+import com.takusemba.spotlight.OnSpotlightListener
+import com.takusemba.spotlight.Spotlight
+import com.takusemba.spotlight.Target
+import java.util.*
+import org.oppia.android.R
+import org.oppia.android.app.onboarding.SpotlightNavigationListener
+import org.oppia.android.databinding.OverlayOverLeftBinding
+import org.oppia.android.databinding.OverlayOverRightBinding
+import org.oppia.android.databinding.OverlayUnderLeftBinding
+import org.oppia.android.databinding.OverlayUnderRightBinding
+
+class SpotlightOverlayPositionAutomator(
+ private val fragment: Fragment,
+ private val activity: Activity
+) : SpotlightNavigationListener {
+
+ private lateinit var overlayBinding: Any
+ private lateinit var spotlight: Spotlight
// these will determine what arrow resource we will use (top, bottom, left, right facing)
private lateinit var overlayHintVerticalPosition: OverlayHintVerticalPosition
private lateinit var overlayHintHorizontalPosition: OverlayHintHorizontalPosition
- private fun getAnchorTopMargin(): Int {
- return anchor.top
- }
-
- private fun getAnchorBottomMargin(): Int {
- return anchor.bottom
+ private fun getAnchorTopMargin(anchor: View): Int {
+ return anchor.y.toInt()
}
- private fun getAnchorLeftMargin(): Int {
- return anchor.left
+ private fun getAnchorLeftMargin(anchor: View): Int {
+ return anchor.x.toInt()
}
- private fun getAnchorRightMargin(): Int {
- return anchor.right
- }
-
- private fun getAnchorHeight(): Int {
+ private fun getAnchorHeight(anchor: View): Int {
return anchor.height
}
- private fun getAnchorWidth(): Int {
+ private fun getAnchorWidth(anchor: View): Int {
return anchor.width
}
-// private fun getArrowTopMargin(): Int {
-// return 0
-// TODO: this is only possible after reources can be accessed from this class. Not a necessity currently
-// }
+ private fun calculateOverlayVerticalHintPosition(anchor: View) {
+ val displayMetrics = DisplayMetrics()
+ activity.windowManager.defaultDisplay.getMetrics(displayMetrics)
+
+ val screenHeight = displayMetrics.heightPixels
+ val screenWidth = displayMetrics.widthPixels
-// private fun getArrowHeight(): Int{
-// resources.getDimensionPixelSize(R.dimen.arrow_height)
-// }
- private fun calculateOverlayVerticalHintPosition() {
- overlayHintVerticalPosition = if (getAnchorBottomMargin() > getAnchorTopMargin()) {
- OverlayHintVerticalPosition.UNDER
- } else OverlayHintVerticalPosition.OVER
+ overlayHintVerticalPosition =
+ if ((screenHeight / 2).toInt() > (getAnchorTopMargin(anchor) + getAnchorHeight(anchor) / 2).toInt()) {
+ OverlayHintVerticalPosition.UNDER
+ } else OverlayHintVerticalPosition.OVER
}
- private fun calculateOverlayHorizontalHintPosition() {
- overlayHintHorizontalPosition = if (getAnchorLeftMargin() > getAnchorRightMargin()) {
- OverlayHintHorizontalPosition.RIGHT
- } else OverlayHintHorizontalPosition.LEFT
+ private fun calculateOverlayHorizontalHintPosition(anchor: View) {
+ val displayMetrics = DisplayMetrics()
+ activity.windowManager.defaultDisplay.getMetrics(displayMetrics)
+
+ val screenWidth = displayMetrics.widthPixels
+
+ overlayHintHorizontalPosition =
+ if ((getAnchorLeftMargin(anchor) + getAnchorWidth(anchor) / 2).toInt() > (screenWidth / 2).toInt()) {
+ OverlayHintHorizontalPosition.RIGHT
+ } else OverlayHintHorizontalPosition.LEFT
}
- fun calculateArrowTopMargin(): Int {
- calculateOverlayVerticalHintPosition()
+ private fun calculateArrowTopMargin(anchor: View): Int {
+
+ calculateOverlayVerticalHintPosition(anchor)
return if (overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER) {
- getAnchorTopMargin() + getAnchorHeight()
+ getAnchorTopMargin(anchor) + getAnchorHeight(anchor)
} else {
- getAnchorBottomMargin() + getAnchorHeight()
+ getAnchorTopMargin(anchor) - fragment.resources.getDimension(R.dimen.arrow_height).toInt()
}
}
- fun setConstraints(binding: OverlayBinding) {
- val set = ConstraintSet()
-
- if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT && overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER){
- set.connect(
- binding.customText.id,
- ConstraintSet.RIGHT,
- binding.arrow.id,
- ConstraintSet.RIGHT,
- 0
- )
- set.connect(
- binding.customText.id,
- ConstraintSet.BOTTOM,
- binding.arrow.id,
- ConstraintSet.TOP,
- 0
- )
- }
- if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT && overlayHintVerticalPosition == OverlayHintVerticalPosition.OVER){
- set.connect(
- binding.customText.id,
- ConstraintSet.RIGHT,
- binding.arrow.id,
- ConstraintSet.RIGHT,
- 0
- )
- set.connect(
- binding.customText.id,
- ConstraintSet.TOP,
- binding.arrow.id,
- ConstraintSet.BOTTOM,
- 0
- )
- }
- if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.LEFT || overlayHintVerticalPosition == OverlayHintVerticalPosition.OVER){
- set.connect(
- binding.customText.id,
- ConstraintSet.LEFT,
- binding.arrow.id,
- ConstraintSet.LEFT,
- 0
- )
- set.connect(
- binding.customText.id,
- ConstraintSet.BOTTOM,
- binding.arrow.id,
- ConstraintSet.BOTTOM,
- 0
- )
- }
- if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.LEFT || overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER){
- set.connect(
- binding.customText.id,
- ConstraintSet.LEFT,
- binding.arrow.id,
- ConstraintSet.LEFT,
- 0
- )
- set.connect(
- binding.customText.id,
- ConstraintSet.BOTTOM,
- binding.arrow.id,
- ConstraintSet.TOP,
- 0
- )
+ private fun calculateArrowLeftMargin(anchor: View): Int {
+ calculateOverlayHorizontalHintPosition(anchor)
+ return if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT) {
+ getAnchorLeftMargin(anchor) + getAnchorWidth(anchor)
+ } else {
+ getAnchorLeftMargin(anchor)
}
}
- fun calculateArrowLeftMargin(): Int {
- calculateOverlayHorizontalHintPosition()
- return if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT) {
- getAnchorLeftMargin() + getAnchorWidth()
- } else {
- getAnchorLeftMargin() + 10
+ fun getSpotlightOverlay(anchor: View): View? {
+
+ calculateOverlayHorizontalHintPosition(anchor)
+ calculateOverlayVerticalHintPosition(anchor)
+
+
+ when {
+ overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT &&
+ overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER
+ -> {
+ overlayBinding = OverlayUnderRightBinding.inflate(fragment.layoutInflater)
+ (overlayBinding as OverlayUnderRightBinding).let {
+ it.lifecycleOwner = fragment
+ it.presenter = this
+ }
+
+ (overlayBinding as OverlayUnderRightBinding).arrow.x = anchor.right.dp.toFloat()
+ (overlayBinding as OverlayUnderRightBinding).arrow.y = anchor.bottom.dp.toFloat()
+ (overlayBinding as OverlayUnderRightBinding).customText.x = anchor.x
+ (overlayBinding as OverlayUnderRightBinding).customText.y = anchor.bottom.dp.toFloat()
+
+ return (overlayBinding as OverlayUnderRightBinding).root
+ }
+ overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT &&
+ overlayHintVerticalPosition == OverlayHintVerticalPosition.OVER
+ -> {
+ overlayBinding = OverlayOverRightBinding.inflate(fragment.layoutInflater)
+ (overlayBinding as OverlayOverRightBinding).let {
+ it.lifecycleOwner = fragment
+ it.presenter = this
+ }
+
+ (overlayBinding as OverlayUnderLeftBinding).arrow.x = anchor.x
+ (overlayBinding as OverlayUnderLeftBinding).arrow.y = anchor.bottom.dp.toFloat()
+ (overlayBinding as OverlayUnderLeftBinding).customText.x = anchor.x
+ (overlayBinding as OverlayUnderLeftBinding).customText.y = anchor.bottom.dp.toFloat()
+
+ return (overlayBinding as OverlayOverRightBinding).root
+ }
+ overlayHintHorizontalPosition == OverlayHintHorizontalPosition.LEFT &&
+ overlayHintVerticalPosition == OverlayHintVerticalPosition.OVER
+ -> {
+ overlayBinding = OverlayOverLeftBinding.inflate(fragment.layoutInflater)
+ (overlayBinding as OverlayOverLeftBinding).let {
+ it.lifecycleOwner = fragment
+ it.presenter = this
+ }
+
+ (overlayBinding as OverlayOverLeftBinding).arrow.x = anchor.x
+ (overlayBinding as OverlayOverLeftBinding).arrow.y = anchor.bottom.dp.toFloat()
+ (overlayBinding as OverlayOverLeftBinding).customText.x = anchor.x
+ (overlayBinding as OverlayOverLeftBinding).customText.y = anchor.bottom.dp.toFloat()
+
+ return (overlayBinding as OverlayOverLeftBinding).root
+ }
+ overlayHintHorizontalPosition == OverlayHintHorizontalPosition.LEFT &&
+ overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER
+ -> {
+ overlayBinding = OverlayUnderLeftBinding.inflate(fragment.layoutInflater)
+ (overlayBinding as OverlayUnderLeftBinding).let {
+ it.lifecycleOwner = fragment
+ it.presenter = this
+ }
+
+
+ // translate x is used because it changes the positions of views after they have been layed out.
+ // layout margin using
+ (overlayBinding as OverlayUnderLeftBinding).arrow.x = anchor.x
+ (overlayBinding as OverlayUnderLeftBinding).arrow.y = anchor.bottom.dp.toFloat()
+ (overlayBinding as OverlayUnderLeftBinding).customText.x = anchor.x
+ (overlayBinding as OverlayUnderLeftBinding).customText.y = anchor.bottom.dp.toFloat()
+
+ return (overlayBinding as OverlayUnderLeftBinding).root
+ }
+ else -> return null
}
+
}
sealed class OverlayHintVerticalPosition {
@@ -151,4 +179,33 @@ class SpotlightOverlayPositionAutomator(private val anchor: View) {
object RIGHT : OverlayHintHorizontalPosition()
object LEFT : OverlayHintHorizontalPosition()
}
+
+ val Int.dp: Int
+ get() = (this * Resources.getSystem().displayMetrics.density + 0.5f).toInt()
+
+ override fun clickOnDismiss() {
+ spotlight.finish()
+ }
+
+ override fun clickOnNextTip() {
+ spotlight.next()
+ }
+
+ fun startSpotlight(targets: ArrayList) {
+ spotlight = Spotlight.Builder(activity)
+ .setTargets(targets)
+ .setBackgroundColorRes(R.color.spotlightBackground)
+ .setDuration(1000L)
+ .setAnimation(DecelerateInterpolator(2f))
+ .setOnSpotlightListener(object : OnSpotlightListener {
+ override fun onStarted() {
+ }
+
+ override fun onEnded() {
+ }
+ })
+ .build()
+
+ spotlight.start()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 229eac99f67..25f70b4b8b9 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -28,6 +28,8 @@ import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.SpotlightState
import org.oppia.android.app.model.TopicSpotlightCheckpoint
import org.oppia.android.app.onboarding.SpotlightNavigationListener
+import org.oppia.android.app.spotlight.OverlayPositionAutomator
+import org.oppia.android.app.spotlight.SpotlightOverlayPositionAutomator
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.OverlayBinding
@@ -57,7 +59,7 @@ class TopicFragmentPresenter @Inject constructor(
@EnableSpotlightUi val enableSpotlightUi: PlatformParameterValue,
@EnablePracticeTab private val enablePracticeTab: Boolean,
private val resourceHandler: AppLanguageResourceHandler
-) : SpotlightNavigationListener {
+) {
private lateinit var tabLayout: TabLayout
private var internalProfileId: Int = -1
private lateinit var topicId: String
@@ -65,8 +67,9 @@ class TopicFragmentPresenter @Inject constructor(
private lateinit var viewPager: ViewPager2
private lateinit var overlayBinding: Any
private lateinit var binding: TopicFragmentBinding
- private lateinit var spotlight: Spotlight
+
private lateinit var anchor: View
+ private lateinit var spotlightOverlayPositionAutomator: OverlayPositionAutomator
private val infoTabSpotlightTarget by lazy {
@@ -75,7 +78,7 @@ class TopicFragmentPresenter @Inject constructor(
Target.Builder()
.setAnchor(anchor)
.setShape(RoundedRectangle(anchor.height.toFloat(), anchor.width.toFloat(), 24f))
- .setOverlay(getSpotlightOverlay()!!)
+ .setOverlay(spotlightOverlayPositionAutomator.getSpotlightOverlay(anchor)!!)
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
// any additional behaviour
@@ -99,7 +102,7 @@ class TopicFragmentPresenter @Inject constructor(
Target.Builder()
.setAnchor(getTab(TopicTab.LESSONS))
.setShape(RoundedRectangle(anchor.height.toFloat(), anchor.width.toFloat(), 24f))
- .setOverlay(getSpotlightOverlay()!!)
+ .setOverlay(spotlightOverlayPositionAutomator.getSpotlightOverlay(anchor)!!)
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
@@ -115,11 +118,12 @@ class TopicFragmentPresenter @Inject constructor(
}
private val practiceTabSpotlightTarget by lazy {
+ val anchor = getTab(TopicTab.PRACTICE)
Target.Builder()
.setAnchor(getTab(TopicTab.PRACTICE))
.setShape(RoundedRectangle(anchor.height.toFloat(), anchor.width.toFloat(), 24f))
- .setOverlay(getSpotlightOverlay()!!)
+ .setOverlay(spotlightOverlayPositionAutomator.getSpotlightOverlay(anchor)!!)
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
}
@@ -134,11 +138,12 @@ class TopicFragmentPresenter @Inject constructor(
}
private val revisionTabSpotlightTarget by lazy {
+ val anchor = getTab(TopicTab.REVISION)
Target.Builder()
.setAnchor(getTab(TopicTab.REVISION))
.setShape(RoundedRectangle(anchor.height.toFloat(), anchor.width.toFloat(), 24f))
- .setOverlay(getSpotlightOverlay()!!)
+ .setOverlay(spotlightOverlayPositionAutomator.getSpotlightOverlay(anchor)!!)
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
}
@@ -185,6 +190,7 @@ class TopicFragmentPresenter @Inject constructor(
}
+ spotlightOverlayPositionAutomator = OverlayPositionAutomator(activity, fragment)
val viewModel = getTopicViewModel()
viewModel.setInternalProfileId(internalProfileId)
@@ -285,22 +291,24 @@ class TopicFragmentPresenter @Inject constructor(
targets.add(lessonsTabSpotlightTarget)
targets.add(practiceTabSpotlightTarget)
targets.add(revisionTabSpotlightTarget)
- startSpotlight(targets)
+ spotlightOverlayPositionAutomator.startSpotlight(targets)
}
TopicSpotlightCheckpoint.LastScreenViewed.LESSONS_TAB_SPOTLIGHT -> {
targets.add(practiceTabSpotlightTarget)
targets.add(revisionTabSpotlightTarget)
- startSpotlight(targets)
+ spotlightOverlayPositionAutomator.startSpotlight(targets)
}
TopicSpotlightCheckpoint.LastScreenViewed.PRACTICE_TAB_SPOTLIGHT -> {
targets.add(revisionTabSpotlightTarget)
- startSpotlight(targets)
+ spotlightOverlayPositionAutomator.startSpotlight(targets)
}
}
} else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_UNKNOWN) {
targets.add(infoTabSpotlightTarget)
targets.add(lessonsTabSpotlightTarget)
- startSpotlight(targets)
+ targets.add(practiceTabSpotlightTarget)
+ targets.add(revisionTabSpotlightTarget)
+ spotlightOverlayPositionAutomator.startSpotlight(targets)
}
}
}
@@ -308,262 +316,7 @@ class TopicFragmentPresenter @Inject constructor(
)
}
- private fun startSpotlight(targets: ArrayList) {
- spotlight = Spotlight.Builder(activity)
- .setTargets(targets)
- .setBackgroundColorRes(R.color.spotlightBackground)
- .setDuration(1000L)
- .setAnimation(DecelerateInterpolator(2f))
- .setOnSpotlightListener(object : OnSpotlightListener {
- override fun onStarted() {
- }
- override fun onEnded() {
- }
- })
- .build()
-
- spotlight.start()
- }
-
- override fun clickOnDismiss() {
- spotlight.finish()
- }
-
- override fun clickOnNextTip() {
- spotlight.next()
- }
-
- val Int.dp: Int
- get() = (this * Resources.getSystem().displayMetrics.density + 0.5f).toInt()
-
- private lateinit var overlayHintVerticalPosition: OverlayHintVerticalPosition
- private lateinit var overlayHintHorizontalPosition: OverlayHintHorizontalPosition
-
- private fun getAnchorTopMargin(): Int {
- return anchor.top
- }
-
- private fun getAnchorBottomMargin(): Int {
- return anchor.bottom
- }
-
- private fun getAnchorLeftMargin(): Int {
- return anchor.left
- }
-
- private fun getAnchorRightMargin(): Int {
- return anchor.right
- }
-
- private fun getAnchorHeight(): Int {
- return anchor.height
- }
-
- private fun getAnchorWidth(): Int {
- return anchor.width
- }
-
-// private fun getArrowTopMargin(): Int {
-// return 0
-// TODO: this is only possible after reources can be accessed from this class. Not a necessity currently
-// }
-
-// private fun getArrowHeight(): Int{
-// resources.getDimensionPixelSize(R.dimen.arrow_height)
-// }
-
- private fun calculateOverlayVerticalHintPosition() {
- overlayHintVerticalPosition = if (getAnchorBottomMargin() > getAnchorTopMargin()) {
- OverlayHintVerticalPosition.UNDER
- } else OverlayHintVerticalPosition.OVER
- }
-
- private fun calculateOverlayHorizontalHintPosition() {
- overlayHintHorizontalPosition = if (getAnchorLeftMargin() > getAnchorRightMargin()) {
- OverlayHintHorizontalPosition.RIGHT
- } else OverlayHintHorizontalPosition.LEFT
- }
- private fun getSpotlightOverlay(): View? {
- calculateOverlayHorizontalHintPosition()
- calculateOverlayVerticalHintPosition()
-
-
- if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT && overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER) {
- overlayBinding = OverlayUnderRightBinding.inflate(fragment.layoutInflater)
- (overlayBinding as OverlayUnderRightBinding).let {
- it.lifecycleOwner = fragment
- it.presenter = this
- }
- val arrowParams = (overlayBinding as OverlayUnderRightBinding).arrow.layoutParams as ViewGroup.MarginLayoutParams
- arrowParams.setMargins(
- calculateArrowLeftMargin().dp,
- calculateArrowTopMargin().dp,
- 10.dp,
- 10.dp
- )
- (overlayBinding as OverlayUnderRightBinding).arrow.layoutParams = arrowParams
-
- return (overlayBinding as OverlayUnderRightBinding).root
- }
-
- if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT && overlayHintVerticalPosition == OverlayHintVerticalPosition.OVER) {
- overlayBinding = OverlayOverRightBinding.inflate(fragment.layoutInflater)
- (overlayBinding as OverlayOverRightBinding).let {
- it.lifecycleOwner = fragment
- it.presenter = this
- }
-
- val arrowParams = (overlayBinding as OverlayOverRightBinding).arrow.layoutParams as ViewGroup.MarginLayoutParams
- arrowParams.setMargins(
- calculateArrowLeftMargin().dp,
- calculateArrowTopMargin().dp,
- 10.dp,
- 10.dp
- )
- (overlayBinding as OverlayOverRightBinding).arrow.layoutParams = arrowParams
-
- return (overlayBinding as OverlayOverRightBinding).root
- }
-
- if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.LEFT || overlayHintVerticalPosition == OverlayHintVerticalPosition.OVER) {
- overlayBinding = OverlayOverLeftBinding.inflate(fragment.layoutInflater)
- (overlayBinding as OverlayOverLeftBinding).let {
- it.lifecycleOwner = fragment
- it.presenter = this
- }
-
- val arrowParams = (overlayBinding as OverlayOverLeftBinding).arrow.layoutParams as ViewGroup.MarginLayoutParams
- arrowParams.setMargins(
- calculateArrowLeftMargin().dp,
- calculateArrowTopMargin().dp,
- 10.dp,
- 10.dp
- )
- (overlayBinding as OverlayOverLeftBinding).arrow.layoutParams = arrowParams
-
- return (overlayBinding as OverlayOverLeftBinding).root
- }
-
- if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.LEFT || overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER) {
- overlayBinding = OverlayUnderLeftBinding.inflate(fragment.layoutInflater)
- (overlayBinding as OverlayUnderLeftBinding).let {
- it.lifecycleOwner = fragment
- it.presenter = this
- }
-
- val arrowParams = (overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams as ViewGroup.MarginLayoutParams
- arrowParams.setMargins(
- calculateArrowLeftMargin().dp,
- calculateArrowTopMargin().dp,
- 10.dp,
- 10.dp
- )
- (overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams = arrowParams
-
- return (overlayBinding as OverlayUnderLeftBinding).root
- }
- return null
- }
-
- fun calculateArrowTopMargin(): Int {
- calculateOverlayVerticalHintPosition()
- return if (overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER) {
- getAnchorTopMargin() + getAnchorHeight()
- } else {
- getAnchorBottomMargin() + getAnchorHeight()
- }
- }
-
- fun setConstraints() {
- val set = ConstraintSet()
-
-// if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT && overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER){
-// set.connect(
-// overlayBinding.customText.id,
-// ConstraintSet.RIGHT,
-// overlayBinding.arrow.id,
-// ConstraintSet.RIGHT,
-// 0
-// )
-// set.connect(
-// overlayBinding.customText.id,
-// ConstraintSet.BOTTOM,
-// overlayBinding.arrow.id,
-// ConstraintSet.TOP,
-// 0
-// )
-// }
-// if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT && overlayHintVerticalPosition == OverlayHintVerticalPosition.OVER){
-// set.connect(
-// overlayBinding.customText.id,
-// ConstraintSet.RIGHT,
-// overlayBinding.arrow.id,
-// ConstraintSet.RIGHT,
-// 0
-// )
-// set.connect(
-// overlayBinding.customText.id,
-// ConstraintSet.TOP,
-// overlayBinding.arrow.id,
-// ConstraintSet.BOTTOM,
-// 0
-// )
-// }
-// if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.LEFT || overlayHintVerticalPosition == OverlayHintVerticalPosition.OVER){
-// set.connect(
-// overlayBinding.customText.id,
-// ConstraintSet.LEFT,
-// overlayBinding.arrow.id,
-// ConstraintSet.LEFT,
-// 0
-// )
-// set.connect(
-// overlayBinding.customText.id,
-// ConstraintSet.BOTTOM,
-// overlayBinding.arrow.id,
-// ConstraintSet.BOTTOM,
-// 0
-// )
-// }
-// if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.LEFT || overlayHintVerticalPosition == OverlayHintVerticalPosition.UNDER){
-// set.connect(
-// overlayBinding.customText.id,
-// ConstraintSet.LEFT,
-// overlayBinding.arrow.id,
-// ConstraintSet.LEFT,
-// 0
-// )
-// set.connect(
-// overlayBinding.customText.id,
-// ConstraintSet.BOTTOM,
-// overlayBinding.arrow.id,
-// ConstraintSet.TOP,
-// 0
-// )
-// }
-
-// set.applyTo(overlayBinding.overlayConstraintLayout)
- }
-
- fun calculateArrowLeftMargin(): Int {
- calculateOverlayHorizontalHintPosition()
- return if (overlayHintHorizontalPosition == OverlayHintHorizontalPosition.RIGHT) {
- getAnchorLeftMargin() + getAnchorWidth()
- } else {
- getAnchorLeftMargin() + 10
- }
- }
-
- sealed class OverlayHintVerticalPosition {
- object OVER : OverlayHintVerticalPosition()
- object UNDER : OverlayHintVerticalPosition()
- }
-
- sealed class OverlayHintHorizontalPosition {
- object RIGHT : OverlayHintHorizontalPosition()
- object LEFT : OverlayHintHorizontalPosition()
- }
}
diff --git a/app/src/main/res/layout/overlay.xml b/app/src/main/res/layout/overlay.xml
index 0a2db44aaec..f50ea283008 100644
--- a/app/src/main/res/layout/overlay.xml
+++ b/app/src/main/res/layout/overlay.xml
@@ -35,8 +35,7 @@
android:textColor="@android:color/white"
android:textSize="24dp"
android:textStyle="bold"
- app:layout_constraintStart_toStartOf="@+id/arrow"
- app:layout_constraintTop_toBottomOf="@id/arrow" />
+ />
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/overlay_over_left.xml b/app/src/main/res/layout/overlay_over_left.xml
index 0a2db44aaec..6b63d0c0d00 100644
--- a/app/src/main/res/layout/overlay_over_left.xml
+++ b/app/src/main/res/layout/overlay_over_left.xml
@@ -36,7 +36,7 @@
android:textSize="24dp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="@+id/arrow"
- app:layout_constraintTop_toBottomOf="@id/arrow" />
+ app:layout_constraintBottom_toTopOf="@id/arrow" />
+ app:layout_constraintBottom_toTopOf="@id/arrow" />
+ app:layout_constraintTop_toBottomOf="@id/arrow" />
Date: Sun, 26 Jun 2022 21:41:27 +0530
Subject: [PATCH 013/138] spotlights in top position are working
---
.../app/spotlight/OverlayPositionAutomator.kt | 179 ++++++++++++++----
.../app/topic/TopicFragmentPresenter.kt | 151 +++------------
app/src/main/res/layout/overlay.xml | 5 +-
.../main/res/layout/overlay_over_right.xml | 2 +
.../main/res/layout/overlay_under_right.xml | 1 +
5 files changed, 182 insertions(+), 156 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt b/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
index 969b0a6da30..0a920333d03 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
@@ -5,15 +5,25 @@ import android.content.res.Resources
import android.util.DisplayMetrics
import android.util.Log
import android.view.View
+import android.view.ViewGroup
import android.view.animation.DecelerateInterpolator
import androidx.fragment.app.Fragment
import com.takusemba.spotlight.OnSpotlightListener
+import com.takusemba.spotlight.OnTargetListener
import com.takusemba.spotlight.Spotlight
import com.takusemba.spotlight.Target
+import com.takusemba.spotlight.shape.Circle
+import com.takusemba.spotlight.shape.RoundedRectangle
+import com.takusemba.spotlight.shape.Shape
import java.util.*
import org.oppia.android.R
import org.oppia.android.app.onboarding.SpotlightNavigationListener
-import org.oppia.android.databinding.OverlayBinding
+import org.oppia.android.databinding.OverlayOverLeftBinding
+import org.oppia.android.databinding.OverlayOverRightBinding
+import org.oppia.android.databinding.OverlayUnderLeftBinding
+import org.oppia.android.databinding.OverlayUnderRightBinding
+
+//todo: check bottom wale
class OverlayPositionAutomator(private val activity: Activity, private val fragment: Fragment) :
SpotlightNavigationListener {
@@ -23,9 +33,12 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
private val overlay = "overlay"
private lateinit var anchorPosition: AnchorPosition
- private lateinit var overlayBinding: OverlayBinding
+ private lateinit var overlayBinding: Any
+
private lateinit var anchor: View
+ private var targetList = ArrayList()
+
init {
val displayMetrics = DisplayMetrics()
activity.windowManager.defaultDisplay.getMetrics(displayMetrics)
@@ -77,12 +90,12 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
}
private fun getScreenCentreX(): Int {
- Log.d("overlay screenCentre X" , (screenHeight / 2).toString())
+ Log.d("overlay screenCentre X", (screenHeight / 2).toString())
return screenWidth / 2
}
private fun getScreenCentreY(): Int {
- Log.d("overlay screenCentre Y" , (screenHeight / 2).toString())
+ Log.d("overlay screenCentre Y", (screenHeight / 2).toString())
return screenHeight / 2
}
@@ -102,54 +115,143 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
Log.d(overlay, anchorPosition.toString())
}
- private fun setOverlayPosition() {
+ private fun setOverlayPosition(): View {
calculateAnchorPosition()
- when (anchorPosition) {
+ return when (anchorPosition) {
AnchorPosition.TopLeft -> {
- overlayBinding.arrow.x = getAnchorLeft()
- overlayBinding.arrow.y = getAnchorBottom()
- overlayBinding.customText.x = getAnchorLeft()
- overlayBinding.customText.y =
- getAnchorBottom() + getArrowHeight()
+ configureTopLeftOverlay()
}
AnchorPosition.TopRight -> {
- overlayBinding.arrow.x = getAnchorLeft() + getAnchorWidth() - getArrowWidth()
- overlayBinding.arrow.y = getAnchorBottom()
- overlayBinding.customText.right = (getAnchorLeft() + getAnchorWidth()).toInt()
- overlayBinding.customText.y =
- getAnchorBottom() + getArrowHeight()
+ configureTopRightOverlay()
}
- else -> {
-
+ AnchorPosition.BottomRight -> {
+ configureBottomRightOverlay()
+ }
+ AnchorPosition.BottomLeft -> {
+ configureBottomLeftOverlay()
}
}
}
- fun getSpotlightOverlay(anchor: View): View {
- initialiseAnchor(anchor)
+ private fun configureBottomLeftOverlay(): View {
+ overlayBinding = OverlayOverLeftBinding.inflate(fragment.layoutInflater)
+ (overlayBinding as OverlayOverLeftBinding).let {
+ it.lifecycleOwner = fragment
+ it.presenter = this
+ }
+
+ val arrowParams = (overlayBinding as OverlayOverLeftBinding).arrow.layoutParams
+ as ViewGroup.MarginLayoutParams
+ arrowParams.setMargins(
+ getAnchorLeft().toInt(),
+ (getAnchorTop().toInt() - getArrowHeight()).toInt(),
+ 10.dp,
+ 10.dp
+ )
+ (overlayBinding as OverlayOverLeftBinding).arrow.layoutParams = arrowParams
+
+ return (overlayBinding as OverlayOverLeftBinding).root
+ }
- overlayBinding = OverlayBinding.inflate(fragment.layoutInflater)
- overlayBinding.let {
+ private fun configureBottomRightOverlay(): View {
+ overlayBinding = OverlayOverRightBinding.inflate(fragment.layoutInflater)
+ (overlayBinding as OverlayOverRightBinding).let {
it.lifecycleOwner = fragment
it.presenter = this
}
- setOverlayPosition()
+ val arrowParams = (overlayBinding as OverlayOverRightBinding).arrow.layoutParams
+ as ViewGroup.MarginLayoutParams
+ arrowParams.setMargins(
+ (getAnchorLeft() + getAnchorWidth() - getArrowWidth()).toInt(),
+ (getAnchorTop().toInt() - getArrowHeight()).toInt(),
+ 10.dp,
+ 10.dp
+ )
+ (overlayBinding as OverlayOverRightBinding).arrow.layoutParams = arrowParams
+
+ return (overlayBinding as OverlayOverRightBinding).root
+ }
- return overlayBinding.root
+ private fun configureTopRightOverlay(): View {
+ overlayBinding = OverlayUnderRightBinding.inflate(fragment.layoutInflater)
+ (overlayBinding as OverlayUnderRightBinding).let {
+ it.lifecycleOwner = fragment
+ it.presenter = this
+ }
+
+ val arrowParams = (overlayBinding as OverlayUnderRightBinding).arrow.layoutParams
+ as ViewGroup.MarginLayoutParams
+ arrowParams.setMargins(
+ (getAnchorLeft() + getAnchorWidth() - getArrowWidth()).toInt(),
+ getAnchorBottom().toInt(),
+ 10.dp,
+ 10.dp
+ )
+ (overlayBinding as OverlayUnderRightBinding).arrow.layoutParams = arrowParams
+
+ return (overlayBinding as OverlayUnderRightBinding).root
}
- sealed class AnchorPosition {
- object TopLeft : AnchorPosition()
- object TopRight : AnchorPosition()
- object BottomLeft : AnchorPosition()
- object BottomRight : AnchorPosition()
+ private fun configureTopLeftOverlay(): View {
+ overlayBinding = OverlayUnderLeftBinding.inflate(fragment.layoutInflater)
+ (overlayBinding as OverlayUnderLeftBinding).let {
+ it.lifecycleOwner = fragment
+ it.presenter = this
+ }
+
+ val arrowParams = (overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams
+ as ViewGroup.MarginLayoutParams
+ arrowParams.setMargins(
+ getAnchorLeft().toInt(),
+ getAnchorBottom().toInt(),
+ 10.dp,
+ 10.dp
+ )
+ (overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams = arrowParams
+
+ return (overlayBinding as OverlayUnderLeftBinding).root
}
- fun startSpotlight(targets: ArrayList) {
+ fun createTarget(anchor: View, shape: SpotlightShape) {
+ initialiseAnchor(anchor)
+
+ val target = Target.Builder()
+ .setAnchor(anchor)
+ .setShape(getShape(shape))
+ .setOverlay(setOverlayPosition())
+ .setOnTargetListener(object : OnTargetListener {
+ override fun onStarted() {
+ }
+
+ override fun onEnded() {
+
+ }
+ })
+ .build()
+
+ targetList.add(target)
+ }
+
+ private fun getShape(shape: SpotlightShape): Shape {
+ return when (shape) {
+ SpotlightShape.RoundedRectangle -> {
+ RoundedRectangle(anchor.height.toFloat(), anchor.width.toFloat(), 24f)
+ }
+ SpotlightShape.Circle -> {
+ return if (getAnchorHeight() > getAnchorWidth()) {
+ Circle((getAnchorHeight() / 2).toFloat())
+ } else {
+ Circle((getAnchorWidth() / 2).toFloat())
+ }
+ }
+ }
+ }
+
+ fun startSpotlight() {
spotlight = Spotlight.Builder(activity)
- .setTargets(targets)
+ .setTargets(targetList)
.setBackgroundColorRes(R.color.spotlightBackground)
.setDuration(1000L)
.setAnimation(DecelerateInterpolator(2f))
@@ -173,7 +275,20 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
spotlight.next()
}
- val Int.dp: Int
+ private val Int.dp: Int
get() = (this * Resources.getSystem().displayMetrics.density + 0.5f).toInt()
+ sealed class AnchorPosition {
+ object TopLeft : AnchorPosition()
+ object TopRight : AnchorPosition()
+ object BottomLeft : AnchorPosition()
+ object BottomRight : AnchorPosition()
+ }
+
+ companion object {
+ sealed class SpotlightShape {
+ object RoundedRectangle : SpotlightShape()
+ object Circle : SpotlightShape()
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 25f70b4b8b9..92a229ef2a8 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -1,25 +1,16 @@
package org.oppia.android.app.topic
-import android.content.res.Resources
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import android.view.animation.DecelerateInterpolator
-import androidx.annotation.NonNull
import androidx.appcompat.app.AppCompatActivity
-import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
-import com.takusemba.spotlight.OnSpotlightListener
-import com.takusemba.spotlight.OnTargetListener
-import com.takusemba.spotlight.Spotlight
import com.takusemba.spotlight.Target
-import com.takusemba.spotlight.shape.Circle
-import com.takusemba.spotlight.shape.RoundedRectangle
import java.util.*
import javax.inject.Inject
import org.oppia.android.R
@@ -27,16 +18,9 @@ import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.SpotlightState
import org.oppia.android.app.model.TopicSpotlightCheckpoint
-import org.oppia.android.app.onboarding.SpotlightNavigationListener
import org.oppia.android.app.spotlight.OverlayPositionAutomator
-import org.oppia.android.app.spotlight.SpotlightOverlayPositionAutomator
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ViewModelProvider
-import org.oppia.android.databinding.OverlayBinding
-import org.oppia.android.databinding.OverlayOverLeftBinding
-import org.oppia.android.databinding.OverlayOverRightBinding
-import org.oppia.android.databinding.OverlayUnderLeftBinding
-import org.oppia.android.databinding.OverlayUnderRightBinding
import org.oppia.android.databinding.TopicFragmentBinding
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.spotlight.SpotlightActivity
@@ -59,7 +43,7 @@ class TopicFragmentPresenter @Inject constructor(
@EnableSpotlightUi val enableSpotlightUi: PlatformParameterValue,
@EnablePracticeTab private val enablePracticeTab: Boolean,
private val resourceHandler: AppLanguageResourceHandler
-) {
+) {
private lateinit var tabLayout: TabLayout
private var internalProfileId: Int = -1
private lateinit var topicId: String
@@ -67,96 +51,8 @@ class TopicFragmentPresenter @Inject constructor(
private lateinit var viewPager: ViewPager2
private lateinit var overlayBinding: Any
private lateinit var binding: TopicFragmentBinding
-
- private lateinit var anchor: View
private lateinit var spotlightOverlayPositionAutomator: OverlayPositionAutomator
-
- private val infoTabSpotlightTarget by lazy {
- anchor = getTab(TopicTab.INFO)
-
- Target.Builder()
- .setAnchor(anchor)
- .setShape(RoundedRectangle(anchor.height.toFloat(), anchor.width.toFloat(), 24f))
- .setOverlay(spotlightOverlayPositionAutomator.getSpotlightOverlay(anchor)!!)
- .setOnTargetListener(object : OnTargetListener {
- override fun onStarted() {
- // any additional behaviour
-
-// setConstraints()
-
- }
-
- override fun onEnded() {
-// getTopicViewModel().recordSpotlightCheckpoint(
-// TopicSpotlightCheckpoint.LastScreenViewed.INFO_TAB_SPOTLIGHT,
-// )
- }
- })
- .build()
- }
-
- private val lessonsTabSpotlightTarget by lazy {
- val anchor = getTab(TopicTab.LESSONS)
-
- Target.Builder()
- .setAnchor(getTab(TopicTab.LESSONS))
- .setShape(RoundedRectangle(anchor.height.toFloat(), anchor.width.toFloat(), 24f))
- .setOverlay(spotlightOverlayPositionAutomator.getSpotlightOverlay(anchor)!!)
- .setOnTargetListener(object : OnTargetListener {
- override fun onStarted() {
-
- }
-
- override fun onEnded() {
-// getTopicViewModel().recordSpotlightCheckpoint(
-// TopicSpotlightCheckpoint.LastScreenViewed.LESSONS_TAB_SPOTLIGHT,
-// )
- }
- })
- .build()
- }
-
- private val practiceTabSpotlightTarget by lazy {
- val anchor = getTab(TopicTab.PRACTICE)
-
- Target.Builder()
- .setAnchor(getTab(TopicTab.PRACTICE))
- .setShape(RoundedRectangle(anchor.height.toFloat(), anchor.width.toFloat(), 24f))
- .setOverlay(spotlightOverlayPositionAutomator.getSpotlightOverlay(anchor)!!)
- .setOnTargetListener(object : OnTargetListener {
- override fun onStarted() {
- }
-
- override fun onEnded() {
-// getTopicViewModel().recordSpotlightCheckpoint(
-// TopicSpotlightCheckpoint.LastScreenViewed.PRACTICE_TAB_SPOTLIGHT,
-// )
- }
- })
- .build()
- }
-
- private val revisionTabSpotlightTarget by lazy {
- val anchor = getTab(TopicTab.REVISION)
-
- Target.Builder()
- .setAnchor(getTab(TopicTab.REVISION))
- .setShape(RoundedRectangle(anchor.height.toFloat(), anchor.width.toFloat(), 24f))
- .setOverlay(spotlightOverlayPositionAutomator.getSpotlightOverlay(anchor)!!)
- .setOnTargetListener(object : OnTargetListener {
- override fun onStarted() {
- }
-
- override fun onEnded() {
-// getTopicViewModel().recordSpotlightCheckpoint(
-// TopicSpotlightCheckpoint.LastScreenViewed.REVISION_TAB_SPOTLIGHT,
-// )
- }
- })
- .build()
- }
-
private fun getTab(tab: TopicTab): View {
return tabLayout.getTabAt(tab.ordinal)!!.view
}
@@ -263,7 +159,7 @@ class TopicFragmentPresenter @Inject constructor(
}
fun retrieveCheckpointAndInitializeSpotlight() {
- val targets = ArrayList()
+// val targets = ArrayList()
val profileId = ProfileId.newBuilder()
.setInternalId(internalProfileId)
@@ -288,27 +184,39 @@ class TopicFragmentPresenter @Inject constructor(
val lastScreenViewed = (it.value as TopicSpotlightCheckpoint).lastScreenViewed
when (lastScreenViewed) {
TopicSpotlightCheckpoint.LastScreenViewed.INFO_TAB_SPOTLIGHT -> {
- targets.add(lessonsTabSpotlightTarget)
- targets.add(practiceTabSpotlightTarget)
- targets.add(revisionTabSpotlightTarget)
- spotlightOverlayPositionAutomator.startSpotlight(targets)
+// targets.add(lessonsTabSpotlightTarget)
+// targets.add(practiceTabSpotlightTarget)
+// targets.add(revisionTabSpotlightTarget)
+// spotlightOverlayPositionAutomator.startSpotlight(targets)
}
TopicSpotlightCheckpoint.LastScreenViewed.LESSONS_TAB_SPOTLIGHT -> {
- targets.add(practiceTabSpotlightTarget)
- targets.add(revisionTabSpotlightTarget)
- spotlightOverlayPositionAutomator.startSpotlight(targets)
+// targets.add(practiceTabSpotlightTarget)
+// targets.add(revisionTabSpotlightTarget)
+// spotlightOverlayPositionAutomator.startSpotlight(targets)
}
TopicSpotlightCheckpoint.LastScreenViewed.PRACTICE_TAB_SPOTLIGHT -> {
- targets.add(revisionTabSpotlightTarget)
- spotlightOverlayPositionAutomator.startSpotlight(targets)
+// targets.add(revisionTabSpotlightTarget)
+// spotlightOverlayPositionAutomator.startSpotlight(targets)
}
}
} else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_UNKNOWN) {
- targets.add(infoTabSpotlightTarget)
- targets.add(lessonsTabSpotlightTarget)
- targets.add(practiceTabSpotlightTarget)
- targets.add(revisionTabSpotlightTarget)
- spotlightOverlayPositionAutomator.startSpotlight(targets)
+ spotlightOverlayPositionAutomator.createTarget(
+ getTab(TopicTab.INFO),
+ OverlayPositionAutomator.Companion.SpotlightShape.RoundedRectangle
+ )
+ spotlightOverlayPositionAutomator.createTarget(
+ getTab(TopicTab.LESSONS),
+ OverlayPositionAutomator.Companion.SpotlightShape.RoundedRectangle
+ )
+ spotlightOverlayPositionAutomator.createTarget(
+ getTab(TopicTab.PRACTICE),
+ OverlayPositionAutomator.Companion.SpotlightShape.RoundedRectangle
+ )
+ spotlightOverlayPositionAutomator.createTarget(
+ getTab(TopicTab.REVISION),
+ OverlayPositionAutomator.Companion.SpotlightShape.RoundedRectangle
+ )
+ spotlightOverlayPositionAutomator.startSpotlight()
}
}
}
@@ -316,7 +224,4 @@ class TopicFragmentPresenter @Inject constructor(
)
}
-
-
-
}
diff --git a/app/src/main/res/layout/overlay.xml b/app/src/main/res/layout/overlay.xml
index f50ea283008..7494af94aae 100644
--- a/app/src/main/res/layout/overlay.xml
+++ b/app/src/main/res/layout/overlay.xml
@@ -35,7 +35,10 @@
android:textColor="@android:color/white"
android:textSize="24dp"
android:textStyle="bold"
- />
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
Date: Sun, 26 Jun 2022 22:43:56 +0530
Subject: [PATCH 014/138] use absolute screen position instead of view.x which
was relative to parent distance
---
.../app/onboarding/OnboardingFragment.kt | 6 ++++
.../onboarding/OnboardingFragmentPresenter.kt | 29 ++++++++++---------
.../app/spotlight/OverlayPositionAutomator.kt | 24 +++++++++------
app/src/main/res/layout/overlay_over_left.xml | 1 +
4 files changed, 38 insertions(+), 22 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
index 081abae41ee..5b54c531b53 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
@@ -26,4 +26,10 @@ class OnboardingFragment : InjectableFragment() {
): View? {
return onboardingFragmentPresenter.handleCreateView(inflater, container)
}
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ onboardingFragmentPresenter.computeLastSpotlightCheckpoint()
+ super.onViewCreated(view, savedInstanceState)
+
+ }
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index 177aa15d4c1..ba04cc2d8b8 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -34,6 +34,7 @@ import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.statusbar.StatusBarColor
import java.util.*
import javax.inject.Inject
+import org.oppia.android.app.spotlight.OverlayPositionAutomator
/** The presenter for [OnboardingFragment]. */
@FragmentScope
@@ -101,14 +102,14 @@ class OnboardingFragmentPresenter @Inject constructor(
it.presenter = this
it.viewModel = getOnboardingViewModel()
}
- overlayBinding = OverlayBinding.inflate(inflater, container, false)
- overlayBinding.let {
- it.lifecycleOwner = fragment
- it.presenter = this
- }
+// overlayBinding = OverlayBinding.inflate(inflater, container, false)
+// overlayBinding.let {
+// it.lifecycleOwner = fragment
+// it.presenter = this
+// }
setUpViewPager()
addDots()
- computeLastSpotlightCheckpoint()
+
return binding.root
}
@@ -287,8 +288,9 @@ class OnboardingFragmentPresenter @Inject constructor(
}
}
- private fun computeLastSpotlightCheckpoint() {
- val targets = ArrayList()
+ fun computeLastSpotlightCheckpoint() {
+
+// val targets = ArrayList()
val profileId = ProfileId.newBuilder()
.setInternalId(123)
@@ -311,14 +313,15 @@ class OnboardingFragmentPresenter @Inject constructor(
val lastScreenViewed = (it.value as OnboardingSpotlightCheckpoint).lastScreenViewed
when (lastScreenViewed) {
OnboardingSpotlightCheckpoint.LastScreenViewed.NEXT_BUTTON_SPOTLIGHT -> {
- targets.add(secondTarget)
- startSpotlight(targets)
+// targets.add(secondTarget)
+// startSpotlight(targets)
}
}
} else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_UNKNOWN) {
- targets.add(firstTarget)
- targets.add(secondTarget)
- startSpotlight(targets)
+ val overlayPositionAutomator = OverlayPositionAutomator(activity, fragment)
+ overlayPositionAutomator.createTarget(binding.onboardingFragmentNextImageView, OverlayPositionAutomator.Companion.SpotlightShape.Circle)
+ overlayPositionAutomator.createTarget(binding.skipTextView, OverlayPositionAutomator.Companion.SpotlightShape.Circle)
+ overlayPositionAutomator.startSpotlight()
}
}
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt b/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
index 0a920333d03..387f2d762c5 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
@@ -35,7 +35,7 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
private lateinit var anchorPosition: AnchorPosition
private lateinit var overlayBinding: Any
- private lateinit var anchor: View
+ private lateinit var itemToSpotlight: View
private var targetList = ArrayList()
@@ -56,27 +56,33 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
}
private fun initialiseAnchor(itemToSpotlight: View) {
- anchor = itemToSpotlight
+ this.itemToSpotlight = itemToSpotlight
}
private fun getAnchorLeft(): Float {
- return anchor.x
+ val location = IntArray(2)
+ itemToSpotlight.getLocationOnScreen(location)
+ val x = location[0]
+ return x.toFloat()
}
private fun getAnchorTop(): Float {
- return anchor.y
+ val location = IntArray(2)
+ itemToSpotlight.getLocationOnScreen(location)
+ val y = location[1]
+ return y.toFloat()
}
private fun getAnchorBottom(): Float {
- return anchor.bottom.dp.toFloat()
+ return itemToSpotlight.bottom.dp.toFloat()
}
private fun getAnchorHeight(): Int {
- return anchor.height
+ return itemToSpotlight.height
}
private fun getAnchorWidth(): Int {
- return anchor.width
+ return itemToSpotlight.width
}
private fun getAnchorCentreX(): Float {
@@ -90,7 +96,7 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
}
private fun getScreenCentreX(): Int {
- Log.d("overlay screenCentre X", (screenHeight / 2).toString())
+ Log.d("overlay screenCentre X", (screenWidth / 2).toString())
return screenWidth / 2
}
@@ -237,7 +243,7 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
private fun getShape(shape: SpotlightShape): Shape {
return when (shape) {
SpotlightShape.RoundedRectangle -> {
- RoundedRectangle(anchor.height.toFloat(), anchor.width.toFloat(), 24f)
+ RoundedRectangle(itemToSpotlight.height.toFloat(), itemToSpotlight.width.toFloat(), 24f)
}
SpotlightShape.Circle -> {
return if (getAnchorHeight() > getAnchorWidth()) {
diff --git a/app/src/main/res/layout/overlay_over_left.xml b/app/src/main/res/layout/overlay_over_left.xml
index 6b63d0c0d00..4a1ee8c6fa7 100644
--- a/app/src/main/res/layout/overlay_over_left.xml
+++ b/app/src/main/res/layout/overlay_over_left.xml
@@ -21,6 +21,7 @@
android:id="@+id/arrow"
android:layout_height="@dimen/arrow_height"
android:layout_width="@dimen/arrow_width"
+ android:rotationX="180"
android:src="@drawable/ic_rounded_arrow_up_right"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
From 95918342d70dd635407914acd458cc32f14cdf73 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 27 Jun 2022 01:43:50 +0530
Subject: [PATCH 015/138] before adding rtl
---
.../android/app/spotlight/OverlayPositionAutomator.kt | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt b/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
index 387f2d762c5..b4b0008fb79 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
@@ -73,10 +73,6 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
return y.toFloat()
}
- private fun getAnchorBottom(): Float {
- return itemToSpotlight.bottom.dp.toFloat()
- }
-
private fun getAnchorHeight(): Int {
return itemToSpotlight.height
}
@@ -191,7 +187,7 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
as ViewGroup.MarginLayoutParams
arrowParams.setMargins(
(getAnchorLeft() + getAnchorWidth() - getArrowWidth()).toInt(),
- getAnchorBottom().toInt(),
+ (getAnchorTop() + getAnchorHeight()).toInt(),
10.dp,
10.dp
)
@@ -211,7 +207,7 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
as ViewGroup.MarginLayoutParams
arrowParams.setMargins(
getAnchorLeft().toInt(),
- getAnchorBottom().toInt(),
+ (getAnchorTop() + getAnchorHeight()).toInt(),
10.dp,
10.dp
)
From ab8183ff47871564582aa0dda079f5dc6dba0b0f Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 27 Jun 2022 21:56:16 +0530
Subject: [PATCH 016/138] rtl support added but not working
---
.../app/spotlight/OverlayPositionAutomator.kt | 24 ++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt b/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
index b4b0008fb79..7a47bf9d434 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
@@ -39,12 +39,22 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
private var targetList = ArrayList()
+ private var isRTL = false
+
init {
val displayMetrics = DisplayMetrics()
activity.windowManager.defaultDisplay.getMetrics(displayMetrics)
screenHeight = displayMetrics.heightPixels
screenWidth = displayMetrics.widthPixels
+
+ isRTL = checkIsRTL()
+ }
+
+ private fun checkIsRTL(): Boolean {
+ val locale = Locale.getDefault()
+ val directionality: Byte = Character.getDirectionality(locale.displayName[0].toInt())
+ return directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT || directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
}
private fun getArrowHeight(): Float {
@@ -122,7 +132,11 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
return when (anchorPosition) {
AnchorPosition.TopLeft -> {
- configureTopLeftOverlay()
+ if (isRTL){
+ configureTopRightOverlay()
+ }else{
+ configureTopLeftOverlay()
+ }
}
AnchorPosition.TopRight -> {
configureTopRightOverlay()
@@ -151,6 +165,8 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
10.dp,
10.dp
)
+// arrowParams.marginStart = getAnchorLeft().toInt()
+// arrowParams.marginEnd = 10.dp
(overlayBinding as OverlayOverLeftBinding).arrow.layoutParams = arrowParams
return (overlayBinding as OverlayOverLeftBinding).root
@@ -171,6 +187,8 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
10.dp,
10.dp
)
+// arrowParams.marginStart = (getAnchorLeft() + getAnchorWidth() - getArrowWidth()).toInt()
+// arrowParams.marginEnd = 10.dp
(overlayBinding as OverlayOverRightBinding).arrow.layoutParams = arrowParams
return (overlayBinding as OverlayOverRightBinding).root
@@ -191,6 +209,8 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
10.dp,
10.dp
)
+// arrowParams.marginStart = (getAnchorLeft() + getAnchorWidth() - getArrowWidth()).toInt()
+// arrowParams.marginEnd = 10.dp
(overlayBinding as OverlayUnderRightBinding).arrow.layoutParams = arrowParams
return (overlayBinding as OverlayUnderRightBinding).root
@@ -211,6 +231,8 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
10.dp,
10.dp
)
+// arrowParams.marginStart = getAnchorLeft().toInt()
+// arrowParams.marginEnd = 10.dp
(overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams = arrowParams
return (overlayBinding as OverlayUnderLeftBinding).root
From 4f21f4dabf33addbb1a47bf0aefea32a78d23652 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 27 Jun 2022 22:55:08 +0530
Subject: [PATCH 017/138] support for hint text workig
---
.../onboarding/OnboardingFragmentPresenter.kt | 4 ++--
.../app/spotlight/OverlayPositionAutomator.kt | 24 ++++++++++++++++---
.../app/topic/TopicFragmentPresenter.kt | 4 ++++
3 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index ba04cc2d8b8..0a148b2b641 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -319,8 +319,8 @@ class OnboardingFragmentPresenter @Inject constructor(
}
} else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_UNKNOWN) {
val overlayPositionAutomator = OverlayPositionAutomator(activity, fragment)
- overlayPositionAutomator.createTarget(binding.onboardingFragmentNextImageView, OverlayPositionAutomator.Companion.SpotlightShape.Circle)
- overlayPositionAutomator.createTarget(binding.skipTextView, OverlayPositionAutomator.Companion.SpotlightShape.Circle)
+ overlayPositionAutomator.createTarget(binding.onboardingFragmentNextImageView, "Next", OverlayPositionAutomator.Companion.SpotlightShape.Circle)
+ overlayPositionAutomator.createTarget(binding.skipTextView, "Skip", OverlayPositionAutomator.Companion.SpotlightShape.Circle)
overlayPositionAutomator.startSpotlight()
}
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt b/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
index 7a47bf9d434..8b3248dbee8 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
@@ -40,6 +40,7 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
private var targetList = ArrayList()
private var isRTL = false
+ private var hintText = ""
init {
val displayMetrics = DisplayMetrics()
@@ -69,6 +70,10 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
this.itemToSpotlight = itemToSpotlight
}
+ private fun initialiseHintText(hintText: String) {
+ this.hintText = hintText
+ }
+
private fun getAnchorLeft(): Float {
val location = IntArray(2)
itemToSpotlight.getLocationOnScreen(location)
@@ -132,9 +137,9 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
return when (anchorPosition) {
AnchorPosition.TopLeft -> {
- if (isRTL){
+ if (isRTL) {
configureTopRightOverlay()
- }else{
+ } else {
configureTopLeftOverlay()
}
}
@@ -157,6 +162,8 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
it.presenter = this
}
+ (overlayBinding as OverlayOverLeftBinding).customText.text = hintText
+
val arrowParams = (overlayBinding as OverlayOverLeftBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
arrowParams.setMargins(
@@ -179,6 +186,8 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
it.presenter = this
}
+ (overlayBinding as OverlayOverRightBinding).customText.text = hintText
+
val arrowParams = (overlayBinding as OverlayOverRightBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
arrowParams.setMargins(
@@ -201,6 +210,8 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
it.presenter = this
}
+ (overlayBinding as OverlayUnderRightBinding).customText.text = hintText
+
val arrowParams = (overlayBinding as OverlayUnderRightBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
arrowParams.setMargins(
@@ -223,6 +234,8 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
it.presenter = this
}
+ (overlayBinding as OverlayUnderLeftBinding).customText.text = hintText
+
val arrowParams = (overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
arrowParams.setMargins(
@@ -238,8 +251,13 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
return (overlayBinding as OverlayUnderLeftBinding).root
}
- fun createTarget(anchor: View, shape: SpotlightShape) {
+ fun createTarget(
+ anchor: View,
+ hintText: String = "",
+ shape: SpotlightShape = SpotlightShape.RoundedRectangle
+ ) {
initialiseAnchor(anchor)
+ initialiseHintText(hintText)
val target = Target.Builder()
.setAnchor(anchor)
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 92a229ef2a8..29affc56e3f 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -202,18 +202,22 @@ class TopicFragmentPresenter @Inject constructor(
} else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_UNKNOWN) {
spotlightOverlayPositionAutomator.createTarget(
getTab(TopicTab.INFO),
+ "INFO tab...",
OverlayPositionAutomator.Companion.SpotlightShape.RoundedRectangle
)
spotlightOverlayPositionAutomator.createTarget(
getTab(TopicTab.LESSONS),
+ "LESSONS tab...",
OverlayPositionAutomator.Companion.SpotlightShape.RoundedRectangle
)
spotlightOverlayPositionAutomator.createTarget(
getTab(TopicTab.PRACTICE),
+ "PRACTICE tab...",
OverlayPositionAutomator.Companion.SpotlightShape.RoundedRectangle
)
spotlightOverlayPositionAutomator.createTarget(
getTab(TopicTab.REVISION),
+ "REVISION tab...",
OverlayPositionAutomator.Companion.SpotlightShape.RoundedRectangle
)
spotlightOverlayPositionAutomator.startSpotlight()
From 287e67a8625a24ec94ac36479d3789cb54832e2d Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Tue, 28 Jun 2022 00:21:09 +0530
Subject: [PATCH 018/138] updated proto structure
---
.../onboarding/OnboardingFragmentPresenter.kt | 30 ++++--------
.../app/spotlight/OverlayPositionAutomator.kt | 4 +-
.../main/res/layout/overlay_under_right.xml | 3 ++
.../spotlight/SpotlightStateController.kt | 3 +-
model/src/main/proto/spotlight.proto | 47 ++++++++++++++++++-
5 files changed, 63 insertions(+), 24 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index 0a148b2b641..e00f38d966f 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -289,9 +289,6 @@ class OnboardingFragmentPresenter @Inject constructor(
}
fun computeLastSpotlightCheckpoint() {
-
-// val targets = ArrayList()
-
val profileId = ProfileId.newBuilder()
.setInternalId(123)
.build()
@@ -300,6 +297,16 @@ class OnboardingFragmentPresenter @Inject constructor(
SpotlightActivity.ONBOARDING_ACTIVITY
).toLiveData()
+ val nextButtonSpotlightCheckpointLiveData = spotlightStateController.retrieveSpotlightCheckpoint(
+ profileId,
+ SpotlightActivity.ONBOARDING_NEXT_BUTTON
+ ).toLiveData()
+
+ nextButtonSpotlightCheckpointLiveData.observe(
+ fragment,
+ object : Observer>
+ )
+
checkpointLiveData.observe(
fragment,
object : Observer> {
@@ -328,21 +335,4 @@ class OnboardingFragmentPresenter @Inject constructor(
}
)
}
- private fun startSpotlight(targets: ArrayList) {
- spotlight = Spotlight.Builder(activity)
- .setTargets(targets)
- .setBackgroundColorRes(R.color.spotlightBackground)
- .setDuration(1000L)
- .setAnimation(DecelerateInterpolator(2f))
- .setOnSpotlightListener(object : OnSpotlightListener {
- override fun onStarted() {
- }
-
- override fun onEnded() {
- }
- })
- .build()
-
- spotlight.start()
- }
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt b/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
index 8b3248dbee8..e5e23b9a1d8 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
@@ -254,7 +254,7 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
fun createTarget(
anchor: View,
hintText: String = "",
- shape: SpotlightShape = SpotlightShape.RoundedRectangle
+ shape: SpotlightShape = SpotlightShape.RoundedRectangle,
) {
initialiseAnchor(anchor)
initialiseHintText(hintText)
@@ -294,7 +294,7 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
fun startSpotlight() {
spotlight = Spotlight.Builder(activity)
.setTargets(targetList)
- .setBackgroundColorRes(R.color.spotlightBackground)
+// .setBackgroundColorRes(R.color.spotlightBackground)
.setDuration(1000L)
.setAnimation(DecelerateInterpolator(2f))
.setOnSpotlightListener(object : OnSpotlightListener {
diff --git a/app/src/main/res/layout/overlay_under_right.xml b/app/src/main/res/layout/overlay_under_right.xml
index 5ea5897e49d..a80d616cb7c 100644
--- a/app/src/main/res/layout/overlay_under_right.xml
+++ b/app/src/main/res/layout/overlay_under_right.xml
@@ -15,6 +15,9 @@
Date: Wed, 29 Jun 2022 23:43:50 +0530
Subject: [PATCH 019/138] updated model and domain layers
---
.../onboarding/OnboardingFragmentPresenter.kt | 6 +-
.../app/topic/TopicFragmentPresenter.kt | 3 +-
.../spotlight/SpotlightStateController.kt | 99 ++++++-------------
model/src/main/proto/spotlight.proto | 86 ++--------------
4 files changed, 41 insertions(+), 153 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index e00f38d966f..1d386642b75 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -3,14 +3,12 @@ package org.oppia.android.app.onboarding
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import android.view.animation.DecelerateInterpolator
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.viewpager2.widget.ViewPager2
-import com.takusemba.spotlight.OnSpotlightListener
import com.takusemba.spotlight.OnTargetListener
import com.takusemba.spotlight.Spotlight
import com.takusemba.spotlight.Target
@@ -292,12 +290,12 @@ class OnboardingFragmentPresenter @Inject constructor(
val profileId = ProfileId.newBuilder()
.setInternalId(123)
.build()
- val checkpointLiveData = spotlightStateController.retrieveSpotlightCheckpoint(
+ val checkpointLiveData = spotlightStateController.retrieveSpotlightViewState(
profileId,
SpotlightActivity.ONBOARDING_ACTIVITY
).toLiveData()
- val nextButtonSpotlightCheckpointLiveData = spotlightStateController.retrieveSpotlightCheckpoint(
+ val nextButtonSpotlightCheckpointLiveData = spotlightStateController.retrieveSpotlightViewState(
profileId,
SpotlightActivity.ONBOARDING_NEXT_BUTTON
).toLiveData()
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 29affc56e3f..2c312249083 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -10,7 +10,6 @@ import androidx.lifecycle.Observer
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
-import com.takusemba.spotlight.Target
import java.util.*
import javax.inject.Inject
import org.oppia.android.R
@@ -164,7 +163,7 @@ class TopicFragmentPresenter @Inject constructor(
val profileId = ProfileId.newBuilder()
.setInternalId(internalProfileId)
.build()
- val checkpointLiveData = spotlightStateController.retrieveSpotlightCheckpoint(
+ val checkpointLiveData = spotlightStateController.retrieveSpotlightViewState(
profileId,
SpotlightActivity.TOPIC_ACTIVITY
).toLiveData()
diff --git a/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt b/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
index 600b3f6cd97..7a92808bee2 100644
--- a/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
+++ b/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
@@ -1,12 +1,7 @@
package org.oppia.android.domain.spotlight
import kotlinx.coroutines.Deferred
-import org.oppia.android.app.model.OnboardingSpotlightCheckpoint
import org.oppia.android.app.model.ProfileId
-import org.oppia.android.app.model.ProfileSpotlightCheckpoint
-import org.oppia.android.app.model.SpotlightCheckpointDatabase
-import org.oppia.android.app.model.SpotlightState
-import org.oppia.android.app.model.TopicSpotlightCheckpoint
import org.oppia.android.data.persistence.PersistentCacheStore
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.util.data.AsyncResult
@@ -15,6 +10,9 @@ import org.oppia.android.util.data.DataProviders
import org.oppia.android.util.data.DataProviders.Companion.transformAsync
import javax.inject.Inject
import javax.inject.Singleton
+import org.oppia.android.app.model.Spotlight
+import org.oppia.android.app.model.SpotlightStateDatabase
+import org.oppia.android.app.model.SpotlightViewState
private const val SPOTLIGHT_STATE_DATA_PROVIDER_ID = "spotlight_state_data_provider_id"
private const val CACHE_NAME = "spotlight_checkpoint_database"
@@ -31,46 +29,46 @@ class SpotlightStateController @Inject constructor(
) {
class SpotlightStateNotFoundException(message: String) : Exception(message)
- class SpotlightActivityUnrecognizedException(message: String) : Exception(message)
+ class SpotlightFeatureUnrecognizedException(message: String) : Exception(message)
private val cacheStoreMap =
- mutableMapOf>()
+ mutableMapOf>()
private fun recordSpotlightStateAsync(
profileId: ProfileId,
- checkpoint: Any,
+ feature: Spotlight.FeatureCase,
+ viewState: SpotlightViewState
): Deferred {
return retrieveCacheStore(profileId).storeDataWithCustomChannelAsync(
updateInMemoryCache = true
) {
- val spotlightCheckpointDatabaseBuilder = it.toBuilder()
+ val spotlightStateDatabaseBuilder = it.toBuilder()
- val newCheckpoint: Any = when (checkpoint) {
- is OnboardingSpotlightCheckpoint -> {
- spotlightCheckpointDatabaseBuilder.setOnboardingSpotlightCheckpoint(checkpoint)
+ val spotlight = when (feature) {
+ Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON -> {
+ spotlightStateDatabaseBuilder.setOnboardingNextButton(viewState)
}
- is ProfileSpotlightCheckpoint -> {
- spotlightCheckpointDatabaseBuilder.setProfileSpotlightCheckpoint(checkpoint)
- }
- is TopicSpotlightCheckpoint -> {
- spotlightCheckpointDatabaseBuilder.setTopicSpotlightCheckpoint(checkpoint)
+ Spotlight.FeatureCase.TOPIC_LESSON_TAB -> {
+ spotlightStateDatabaseBuilder.setTopicLessonTab(viewState)
}
else -> {
- throw SpotlightActivityUnrecognizedException("spotlight activity is not one of the recognized types")
+ throw SpotlightFeatureUnrecognizedException("spotlight feature is not one of the recognized types")
}
}
- val spotlightCheckpointDatabase = spotlightCheckpointDatabaseBuilder.build()
- Pair(spotlightCheckpointDatabase, newCheckpoint)
+ val spotlightStateDatabase = spotlightStateDatabaseBuilder.build()
+ Pair(spotlightStateDatabase, spotlight)
}
}
fun recordSpotlightCheckpoint(
profileId: ProfileId,
- checkpoint: Any,
+ feature: Spotlight.FeatureCase,
+ viewState: SpotlightViewState
): DataProvider {
val deferred = recordSpotlightStateAsync(
profileId,
- checkpoint
+ feature,
+ viewState
)
return dataProviders.createInMemoryDataProviderAsync(
RECORD_SPOTLIGHT_CHECKPOINT_DATA_PROVIDER_ID
@@ -79,32 +77,29 @@ class SpotlightStateController @Inject constructor(
}
}
- fun retrieveSpotlightCheckpoint(
+ fun retrieveSpotlightViewState(
profileId: ProfileId,
- spotlightActivity: SpotlightActivity,
+ feature: Spotlight.FeatureCase,
): DataProvider {
return retrieveCacheStore(profileId)
.transformAsync(
RETRIEVE_SPOTLIGHT_CHECKPOINT_DATA_PROVIDER_ID
) {
- val checkpoint = when (spotlightActivity) {
- SpotlightActivity.ONBOARDING_ACTIVITY -> {
- it.onboardingSpotlightCheckpoint
- }
- SpotlightActivity.PROFILE_ACTIVITY -> {
- it.profileSpotlightCheckpoint
+ val viewState = when (feature) {
+ Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON -> {
+ it.onboardingNextButton
}
- SpotlightActivity.TOPIC_ACTIVITY -> {
- it.topicSpotlightCheckpoint
+ Spotlight.FeatureCase.TOPIC_LESSON_TAB -> {
+ it.topicLessonTab
}
else -> {
- throw SpotlightActivityUnrecognizedException("spotlight activity is not one of the recognized types")
+ throw SpotlightFeatureUnrecognizedException("spotlight activity is not one of the recognized types")
}
}
- if (checkpoint != null) {
- AsyncResult.Success(checkpoint)
+ if (viewState != null) {
+ AsyncResult.Success(viewState)
} else {
AsyncResult.Failure(SpotlightStateNotFoundException("State not found "))
}
@@ -113,14 +108,14 @@ class SpotlightStateController @Inject constructor(
private fun retrieveCacheStore(
profileId: ProfileId
- ): PersistentCacheStore {
+ ): PersistentCacheStore {
val cacheStore = if (profileId in cacheStoreMap) {
cacheStoreMap[profileId]!!
} else {
val cacheStore =
cacheStoreFactory.createPerProfile(
CACHE_NAME,
- SpotlightCheckpointDatabase.getDefaultInstance(),
+ SpotlightStateDatabase.getDefaultInstance(),
profileId
)
cacheStoreMap[profileId] = cacheStore
@@ -138,34 +133,4 @@ class SpotlightStateController @Inject constructor(
}
return cacheStore
}
-
- fun computeSpotlightState(lastScreenViewed: Any): SpotlightState {
- return when (lastScreenViewed) {
- is OnboardingSpotlightCheckpoint.LastScreenViewed -> {
- if (lastScreenViewed.ordinal == OnboardingSpotlightCheckpoint.LastScreenViewed.values().size - 1)
- SpotlightState.SPOTLIGHT_STATE_COMPLETED
- else SpotlightState.SPOTLIGHT_STATE_PARTIAL
- }
- is ProfileSpotlightCheckpoint.LastScreenViewed -> {
- if (lastScreenViewed.ordinal == ProfileSpotlightCheckpoint.LastScreenViewed.values().size - 1)
- SpotlightState.SPOTLIGHT_STATE_COMPLETED
- else SpotlightState.SPOTLIGHT_STATE_PARTIAL
- }
- is TopicSpotlightCheckpoint.LastScreenViewed -> {
- if (lastScreenViewed.ordinal == TopicSpotlightCheckpoint.LastScreenViewed.values().size - 1)
- SpotlightState.SPOTLIGHT_STATE_COMPLETED
- else SpotlightState.SPOTLIGHT_STATE_PARTIAL
- }
- else -> {
- throw SpotlightStateNotFoundException("couldn't find spotlight state")
- }
- }
- }
-}
-
-enum class SpotlightActivity {
- ONBOARDING_ACTIVITY,
- PROFILE_ACTIVITY,
- TOPIC_ACTIVITY,
- ONBOARDING_NEXT_BUTTON
}
diff --git a/model/src/main/proto/spotlight.proto b/model/src/main/proto/spotlight.proto
index b6a3c90fe4c..d1ca4077948 100644
--- a/model/src/main/proto/spotlight.proto
+++ b/model/src/main/proto/spotlight.proto
@@ -5,90 +5,11 @@ package model;
option java_package = "org.oppia.android.app.model";
option java_multiple_files = true;
-message SpotlightCheckpointDatabase{
- OnboardingSpotlightCheckpoint onboarding_spotlight_checkpoint = 1 ;
- ProfileSpotlightCheckpoint profile_spotlight_checkpoint = 2 ;
- TopicSpotlightCheckpoint topic_spotlight_checkpoint = 3 ;
- HomeSpotlightCheckpoint home_spotlight_checkpoint = 4;
- ExplorationSpotlightCheckpoint exploration_spotlight_checkpoint = 5 ;
-
- OnboardingNextButton onboarding_next_button = 6 ;
- OnboardingSkipButton onboarding_skip_button = 7 ;
- HomePromotedStories home_promoted_stories = 8 ;
- TopicLessonsTab topic_lessons_tab = 9 ;
- TopicRevisionsTab topic_revisions_tab = 10 ;
-}
-
-message OnboardingNextButton{
- SpotlightState spotlight_state = 1 ;
-}
-
-message OnboardingSkipButton{
- SpotlightState spotlight_state = 1 ;
-}
-
-message HomePromotedStories{
- SpotlightState spotlight_state = 1 ;
-}
-
-message TopicLessonsTab{
- SpotlightState spotlight_state = 1 ;
-}
-
-message TopicRevisionsTab{
- SpotlightState spotlight_state = 1 ;
-}
-
-message OnboardingSpotlightCheckpoint{
- SpotlightState spotlight_state = 1 ;
- enum LastScreenViewed {
- NEXT_BUTTON_SPOTLIGHT = 0;
- SKIP_BUTTON_SPOTLIGHT = 1;
- }
- LastScreenViewed last_screen_viewed = 2;
-}
-
-message ProfileSpotlightCheckpoint{
- SpotlightState spotlight_state = 1 ;
- enum LastScreenViewed {
- NEW_PROFILE_BUTTON_SPOTLIGHT = 0;
- ENTER_NAME_SPOTLIGHT = 1;
- ADD_PIN_SPOTLIGHT = 2;
- }
- LastScreenViewed last_screen_viewed = 2;
-}
-
-message TopicSpotlightCheckpoint{
- SpotlightState spotlight_state = 1 ;
- enum LastScreenViewed {
- INFO_TAB_SPOTLIGHT = 0;
- LESSONS_TAB_SPOTLIGHT = 1;
- PRACTICE_TAB_SPOTLIGHT = 2;
- REVISION_TAB_SPOTLIGHT = 3;
- }
- LastScreenViewed last_screen_viewed = 2;
-}
-
-message HomeSpotlightCheckpoint{
-
-}
-
-message ExplorationSpotlightCheckpoint{
-
-}
-
-enum SpotlightState{
- SPOTLIGHT_STATE_UNKNOWN = 0 ;
- SPOTLIGHT_STATE_PARTIAL = 1 ;
- SPOTLIGHT_STATE_DISMISSED = 2 ;
- SPOTLIGHT_STATE_COMPLETED = 3 ;
-}
-
-
message Spotlight {
oneof feature {
SpotlightViewState onboarding_next_button = 1;
SpotlightViewState topic_lesson_tab = 2;
+ SpotlightViewState topic_revision_tab = 3;
}
}
@@ -101,5 +22,10 @@ enum SpotlightViewState {
message SpotlightStateDatabase {
SpotlightViewState onboarding_next_button = 1;
SpotlightViewState topic_lesson_tab = 2;
+ SpotlightViewState topic_revision_tab = 3;
}
+
+
+
+
From 0a39ca65d0649b2ae15ee863b459cdebaec2d91c Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 30 Jun 2022 00:21:11 +0530
Subject: [PATCH 020/138] update onboarding and topic packages for new proto
---
.../onboarding/OnboardingFragmentPresenter.kt | 99 +++---------
.../app/onboarding/OnboardingViewModel.kt | 16 --
.../app/spotlight/OverlayPositionAutomator.kt | 2 +-
.../oppia/android/app/topic/TopicFragment.kt | 2 +-
.../app/topic/TopicFragmentPresenter.kt | 145 +++++++++---------
.../oppia/android/app/topic/TopicViewModel.kt | 14 --
6 files changed, 95 insertions(+), 183 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index 1d386642b75..b1f903b3795 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -9,30 +9,25 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.viewpager2.widget.ViewPager2
-import com.takusemba.spotlight.OnTargetListener
import com.takusemba.spotlight.Spotlight
-import com.takusemba.spotlight.Target
-import com.takusemba.spotlight.shape.Circle
+import java.util.*
+import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
-import org.oppia.android.app.model.OnboardingSpotlightCheckpoint
import org.oppia.android.app.model.ProfileId
-import org.oppia.android.app.model.SpotlightState
+import org.oppia.android.app.model.SpotlightViewState
import org.oppia.android.app.recyclerview.BindableAdapter
+import org.oppia.android.app.spotlight.OverlayPositionAutomator
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.OnboardingFragmentBinding
import org.oppia.android.databinding.OnboardingSlideBinding
import org.oppia.android.databinding.OnboardingSlideFinalBinding
import org.oppia.android.databinding.OverlayBinding
-import org.oppia.android.domain.spotlight.SpotlightActivity
import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.statusbar.StatusBarColor
-import java.util.*
-import javax.inject.Inject
-import org.oppia.android.app.spotlight.OverlayPositionAutomator
/** The presenter for [OnboardingFragment]. */
@FragmentScope
@@ -49,44 +44,6 @@ class OnboardingFragmentPresenter @Inject constructor(
private lateinit var overlayBinding: OverlayBinding
private lateinit var spotlight: Spotlight
- private val firstTarget by lazy {
- Target.Builder()
- .setAnchor(binding.onboardingFragmentNextImageView)
- .setShape(Circle(60f))
- .setOverlay(overlayBinding.root)
- .setOnTargetListener(object : OnTargetListener {
- override fun onStarted() {
- }
-
- override fun onEnded() {
- getOnboardingViewModel().recordSpotlightCheckpoint(
- OnboardingSpotlightCheckpoint.LastScreenViewed.NEXT_BUTTON_SPOTLIGHT,
- SpotlightState.SPOTLIGHT_STATE_PARTIAL
- )
- }
- })
- .build()
- }
-
- private val secondTarget by lazy {
- Target.Builder()
- .setAnchor(binding.skipTextView)
- .setShape(Circle(60f))
- .setOverlay(overlayBinding.root)
- .setOnTargetListener(object : OnTargetListener {
- override fun onStarted() {
- }
-
- override fun onEnded() {
- getOnboardingViewModel().recordSpotlightCheckpoint(
- OnboardingSpotlightCheckpoint.LastScreenViewed.SKIP_BUTTON_SPOTLIGHT,
- SpotlightState.SPOTLIGHT_STATE_COMPLETED
- )
- }
- })
- .build()
- }
-
fun handleCreateView(inflater: LayoutInflater, container: ViewGroup?): View? {
binding = OnboardingFragmentBinding.inflate(
inflater,
@@ -290,42 +247,32 @@ class OnboardingFragmentPresenter @Inject constructor(
val profileId = ProfileId.newBuilder()
.setInternalId(123)
.build()
- val checkpointLiveData = spotlightStateController.retrieveSpotlightViewState(
- profileId,
- SpotlightActivity.ONBOARDING_ACTIVITY
- ).toLiveData()
-
- val nextButtonSpotlightCheckpointLiveData = spotlightStateController.retrieveSpotlightViewState(
- profileId,
- SpotlightActivity.ONBOARDING_NEXT_BUTTON
- ).toLiveData()
-
- nextButtonSpotlightCheckpointLiveData.observe(
- fragment,
- object : Observer>
- )
+ val onboardingButtonSpotlightViewStateLiveData =
+ spotlightStateController.retrieveSpotlightViewState(
+ profileId,
+ org.oppia.android.app.model.Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON
+ ).toLiveData()
- checkpointLiveData.observe(
+ onboardingButtonSpotlightViewStateLiveData.observe(
fragment,
object : Observer> {
override fun onChanged(it: AsyncResult?) {
if (it is AsyncResult.Success) {
- checkpointLiveData.removeObserver(this)
- val spotlightState = (it.value as OnboardingSpotlightCheckpoint).spotlightState
- if (spotlightState == SpotlightState.SPOTLIGHT_STATE_COMPLETED || spotlightState == SpotlightState.SPOTLIGHT_STATE_DISMISSED) {
+ onboardingButtonSpotlightViewStateLiveData.removeObserver(this)
+ val viewState = (it.value as SpotlightViewState)
+ if (viewState == SpotlightViewState.SPOTLIGHT_SEEN) {
return
- } else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_PARTIAL) {
- val lastScreenViewed = (it.value as OnboardingSpotlightCheckpoint).lastScreenViewed
- when (lastScreenViewed) {
- OnboardingSpotlightCheckpoint.LastScreenViewed.NEXT_BUTTON_SPOTLIGHT -> {
-// targets.add(secondTarget)
-// startSpotlight(targets)
- }
- }
- } else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_UNKNOWN) {
+ } else if (viewState == SpotlightViewState.SPOTLIGHT_VIEW_STATE_UNSPECIFIED || viewState == SpotlightViewState.SPOTLIGHT_NOT_SEEN) {
val overlayPositionAutomator = OverlayPositionAutomator(activity, fragment)
- overlayPositionAutomator.createTarget(binding.onboardingFragmentNextImageView, "Next", OverlayPositionAutomator.Companion.SpotlightShape.Circle)
- overlayPositionAutomator.createTarget(binding.skipTextView, "Skip", OverlayPositionAutomator.Companion.SpotlightShape.Circle)
+ overlayPositionAutomator.createTarget(
+ binding.onboardingFragmentNextImageView,
+ "Next",
+ OverlayPositionAutomator.Companion.SpotlightShape.Circle
+ )
+ spotlightStateController.recordSpotlightCheckpoint(
+ profileId, org.oppia.android.app.model.Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON,
+ SpotlightViewState.SPOTLIGHT_SEEN
+ )
overlayPositionAutomator.startSpotlight()
}
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt
index c253d77a193..8715dd77e9c 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt
@@ -3,9 +3,6 @@ package org.oppia.android.app.onboarding
import androidx.databinding.ObservableField
import androidx.lifecycle.ViewModel
import org.oppia.android.R
-import org.oppia.android.app.model.OnboardingSpotlightCheckpoint
-import org.oppia.android.app.model.ProfileId
-import org.oppia.android.app.model.SpotlightState
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ObservableViewModel
import org.oppia.android.domain.spotlight.SpotlightStateController
@@ -38,18 +35,5 @@ class OnboardingViewModel @Inject constructor(
)
}
- fun recordSpotlightCheckpoint(
- lastScreenViewed: OnboardingSpotlightCheckpoint.LastScreenViewed,
- spotlightState: SpotlightState
- ) {
- val checkpoint = OnboardingSpotlightCheckpoint.newBuilder()
- .setLastScreenViewed(lastScreenViewed)
- .setSpotlightState(spotlightState)
- .build()
- val profileId = ProfileId.newBuilder()
- .setInternalId(123)
- .build()
- spotlightStateController.recordSpotlightCheckpoint(profileId, checkpoint)
- }
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt b/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
index e5e23b9a1d8..27d7b710e91 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/OverlayPositionAutomator.kt
@@ -294,7 +294,7 @@ class OverlayPositionAutomator(private val activity: Activity, private val fragm
fun startSpotlight() {
spotlight = Spotlight.Builder(activity)
.setTargets(targetList)
-// .setBackgroundColorRes(R.color.spotlightBackground)
+ .setBackgroundColorRes(R.color.spotlightBackground)
.setDuration(1000L)
.setAnimation(DecelerateInterpolator(2f))
.setOnSpotlightListener(object : OnSpotlightListener {
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
index 7369c9851bf..e51a476838b 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
@@ -44,7 +44,7 @@ class TopicFragment : InjectableFragment() {
super.onViewCreated(view, savedInstanceState)
if (topicFragmentPresenter.enableSpotlightUi.value) {
- topicFragmentPresenter.retrieveCheckpointAndInitializeSpotlight()
+// topicFragmentPresenter.retrieveCheckpointAndInitializeSpotlight()
}
}
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 2c312249083..0b20ed826e7 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -14,18 +14,13 @@ import java.util.*
import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
-import org.oppia.android.app.model.ProfileId
-import org.oppia.android.app.model.SpotlightState
-import org.oppia.android.app.model.TopicSpotlightCheckpoint
import org.oppia.android.app.spotlight.OverlayPositionAutomator
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.TopicFragmentBinding
import org.oppia.android.domain.oppialogger.OppiaLogger
-import org.oppia.android.domain.spotlight.SpotlightActivity
import org.oppia.android.domain.spotlight.SpotlightStateController
-import org.oppia.android.util.data.AsyncResult
-import org.oppia.android.util.data.DataProviders.Companion.toLiveData
+
import org.oppia.android.util.platformparameter.EnableSpotlightUi
import org.oppia.android.util.platformparameter.PlatformParameterValue
import org.oppia.android.util.system.OppiaClock
@@ -157,74 +152,74 @@ class TopicFragmentPresenter @Inject constructor(
)
}
- fun retrieveCheckpointAndInitializeSpotlight() {
-// val targets = ArrayList()
-
- val profileId = ProfileId.newBuilder()
- .setInternalId(internalProfileId)
- .build()
- val checkpointLiveData = spotlightStateController.retrieveSpotlightViewState(
- profileId,
- SpotlightActivity.TOPIC_ACTIVITY
- ).toLiveData()
-
- checkpointLiveData.observe(
- fragment,
- object : Observer> {
- override fun onChanged(it: AsyncResult?) {
- if (it is AsyncResult.Success) {
- checkpointLiveData.removeObserver(this)
- val spotlightState = (it.value as TopicSpotlightCheckpoint).spotlightState
- if (spotlightState == SpotlightState.SPOTLIGHT_STATE_COMPLETED ||
- spotlightState == SpotlightState.SPOTLIGHT_STATE_DISMISSED
- ) {
- return
- } else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_PARTIAL) {
- val lastScreenViewed = (it.value as TopicSpotlightCheckpoint).lastScreenViewed
- when (lastScreenViewed) {
- TopicSpotlightCheckpoint.LastScreenViewed.INFO_TAB_SPOTLIGHT -> {
-// targets.add(lessonsTabSpotlightTarget)
-// targets.add(practiceTabSpotlightTarget)
-// targets.add(revisionTabSpotlightTarget)
-// spotlightOverlayPositionAutomator.startSpotlight(targets)
- }
- TopicSpotlightCheckpoint.LastScreenViewed.LESSONS_TAB_SPOTLIGHT -> {
-// targets.add(practiceTabSpotlightTarget)
-// targets.add(revisionTabSpotlightTarget)
-// spotlightOverlayPositionAutomator.startSpotlight(targets)
- }
- TopicSpotlightCheckpoint.LastScreenViewed.PRACTICE_TAB_SPOTLIGHT -> {
-// targets.add(revisionTabSpotlightTarget)
-// spotlightOverlayPositionAutomator.startSpotlight(targets)
- }
- }
- } else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_UNKNOWN) {
- spotlightOverlayPositionAutomator.createTarget(
- getTab(TopicTab.INFO),
- "INFO tab...",
- OverlayPositionAutomator.Companion.SpotlightShape.RoundedRectangle
- )
- spotlightOverlayPositionAutomator.createTarget(
- getTab(TopicTab.LESSONS),
- "LESSONS tab...",
- OverlayPositionAutomator.Companion.SpotlightShape.RoundedRectangle
- )
- spotlightOverlayPositionAutomator.createTarget(
- getTab(TopicTab.PRACTICE),
- "PRACTICE tab...",
- OverlayPositionAutomator.Companion.SpotlightShape.RoundedRectangle
- )
- spotlightOverlayPositionAutomator.createTarget(
- getTab(TopicTab.REVISION),
- "REVISION tab...",
- OverlayPositionAutomator.Companion.SpotlightShape.RoundedRectangle
- )
- spotlightOverlayPositionAutomator.startSpotlight()
- }
- }
- }
- }
- )
- }
+// fun retrieveCheckpointAndInitializeSpotlight() {
+//// val targets = ArrayList()
+//
+// val profileId = ProfileId.newBuilder()
+// .setInternalId(internalProfileId)
+// .build()
+// val checkpointLiveData = spotlightStateController.retrieveSpotlightViewState(
+// profileId,
+// SpotlightActivity.TOPIC_ACTIVITY
+// ).toLiveData()
+//
+// checkpointLiveData.observe(
+// fragment,
+// object : Observer> {
+// override fun onChanged(it: AsyncResult?) {
+// if (it is AsyncResult.Success) {
+// checkpointLiveData.removeObserver(this)
+// val spotlightState = (it.value as TopicSpotlightCheckpoint).spotlightState
+// if (spotlightState == SpotlightState.SPOTLIGHT_STATE_COMPLETED ||
+// spotlightState == SpotlightState.SPOTLIGHT_STATE_DISMISSED
+// ) {
+// return
+// } else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_PARTIAL) {
+// val lastScreenViewed = (it.value as TopicSpotlightCheckpoint).lastScreenViewed
+// when (lastScreenViewed) {
+// TopicSpotlightCheckpoint.LastScreenViewed.INFO_TAB_SPOTLIGHT -> {
+//// targets.add(lessonsTabSpotlightTarget)
+//// targets.add(practiceTabSpotlightTarget)
+//// targets.add(revisionTabSpotlightTarget)
+//// spotlightOverlayPositionAutomator.startSpotlight(targets)
+// }
+// TopicSpotlightCheckpoint.LastScreenViewed.LESSONS_TAB_SPOTLIGHT -> {
+//// targets.add(practiceTabSpotlightTarget)
+//// targets.add(revisionTabSpotlightTarget)
+//// spotlightOverlayPositionAutomator.startSpotlight(targets)
+// }
+// TopicSpotlightCheckpoint.LastScreenViewed.PRACTICE_TAB_SPOTLIGHT -> {
+//// targets.add(revisionTabSpotlightTarget)
+//// spotlightOverlayPositionAutomator.startSpotlight(targets)
+// }
+// }
+// } else if (spotlightState == SpotlightState.SPOTLIGHT_STATE_UNKNOWN) {
+// spotlightOverlayPositionAutomator.createTarget(
+// getTab(TopicTab.INFO),
+// "INFO tab...",
+// OverlayPositionAutomator.Companion.SpotlightShape.RoundedRectangle
+// )
+// spotlightOverlayPositionAutomator.createTarget(
+// getTab(TopicTab.LESSONS),
+// "LESSONS tab...",
+// OverlayPositionAutomator.Companion.SpotlightShape.RoundedRectangle
+// )
+// spotlightOverlayPositionAutomator.createTarget(
+// getTab(TopicTab.PRACTICE),
+// "PRACTICE tab...",
+// OverlayPositionAutomator.Companion.SpotlightShape.RoundedRectangle
+// )
+// spotlightOverlayPositionAutomator.createTarget(
+// getTab(TopicTab.REVISION),
+// "REVISION tab...",
+// OverlayPositionAutomator.Companion.SpotlightShape.RoundedRectangle
+// )
+// spotlightOverlayPositionAutomator.startSpotlight()
+// }
+// }
+// }
+// }
+// )
+// }
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt b/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
index 79fcf14f0df..a4beb338e81 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
@@ -6,7 +6,6 @@ import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.Topic
-import org.oppia.android.app.model.TopicSpotlightCheckpoint
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ObservableViewModel
import org.oppia.android.domain.oppialogger.OppiaLogger
@@ -65,17 +64,4 @@ class TopicViewModel @Inject constructor(
}
}
- fun recordSpotlightCheckpoint(
- lastScreenViewed: TopicSpotlightCheckpoint.LastScreenViewed
- ) {
- val checkpoint = TopicSpotlightCheckpoint.newBuilder()
- .setLastScreenViewed(lastScreenViewed)
- .setSpotlightState(spotlightStateController.computeSpotlightState(lastScreenViewed))
- .build()
-
- val profileId = ProfileId.newBuilder()
- .setInternalId(internalProfileId)
- .build()
- spotlightStateController.recordSpotlightCheckpoint(profileId, checkpoint)
- }
}
From 864b657f8d9caabade74bd3b26b5cafa33aae3e0 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 1 Jul 2022 00:17:01 +0530
Subject: [PATCH 021/138] spotlight fragment introduced. Retrieving from
spotFrag so not working
---
.../onboarding/OnboardingFragmentPresenter.kt | 54 +--
.../app/spotlight/SpotlightFragment.kt | 400 ++++++++++++++++++
.../android/app/spotlight/SpotlightShape.kt | 7 +
.../main/res/layout/overlay_over_right.xml | 2 +
4 files changed, 428 insertions(+), 35 deletions(-)
create mode 100644 app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
create mode 100644 app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index b1f903b3795..597f4443b80 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -17,7 +17,9 @@ import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.SpotlightViewState
import org.oppia.android.app.recyclerview.BindableAdapter
-import org.oppia.android.app.spotlight.OverlayPositionAutomator
+import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightShape
+import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.OnboardingFragmentBinding
@@ -37,7 +39,8 @@ class OnboardingFragmentPresenter @Inject constructor(
private val fragment: Fragment,
private val viewModelProvider: ViewModelProvider,
private val viewModelProviderFinalSlide: ViewModelProvider,
- private val resourceHandler: AppLanguageResourceHandler
+ private val resourceHandler: AppLanguageResourceHandler,
+ private val spotlightFragment: SpotlightFragment
) : OnboardingNavigationListener, SpotlightNavigationListener {
private val dotsList = ArrayList()
private lateinit var binding: OnboardingFragmentBinding
@@ -244,40 +247,21 @@ class OnboardingFragmentPresenter @Inject constructor(
}
fun computeLastSpotlightCheckpoint() {
- val profileId = ProfileId.newBuilder()
- .setInternalId(123)
- .build()
- val onboardingButtonSpotlightViewStateLiveData =
- spotlightStateController.retrieveSpotlightViewState(
- profileId,
- org.oppia.android.app.model.Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON
- ).toLiveData()
- onboardingButtonSpotlightViewStateLiveData.observe(
- fragment,
- object : Observer> {
- override fun onChanged(it: AsyncResult?) {
- if (it is AsyncResult.Success) {
- onboardingButtonSpotlightViewStateLiveData.removeObserver(this)
- val viewState = (it.value as SpotlightViewState)
- if (viewState == SpotlightViewState.SPOTLIGHT_SEEN) {
- return
- } else if (viewState == SpotlightViewState.SPOTLIGHT_VIEW_STATE_UNSPECIFIED || viewState == SpotlightViewState.SPOTLIGHT_NOT_SEEN) {
- val overlayPositionAutomator = OverlayPositionAutomator(activity, fragment)
- overlayPositionAutomator.createTarget(
- binding.onboardingFragmentNextImageView,
- "Next",
- OverlayPositionAutomator.Companion.SpotlightShape.Circle
- )
- spotlightStateController.recordSpotlightCheckpoint(
- profileId, org.oppia.android.app.model.Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON,
- SpotlightViewState.SPOTLIGHT_SEEN
- )
- overlayPositionAutomator.startSpotlight()
- }
- }
- }
- }
+ val onboardingButtonSpotlight = SpotlightTarget(
+ binding.onboardingFragmentNextImageView,
+ "Next",
+ SpotlightShape.Circle,
+ org.oppia.android.app.model.Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON
)
+
+ val targetList = ArrayList()
+ targetList.add(onboardingButtonSpotlight)
+ spotlightFragment.spotlightTargetList = targetList
+
+ activity.supportFragmentManager.beginTransaction()
+ .add(R.id.onboarding_fragment_placeholder, spotlightFragment)
+ .commit()
+
}
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
new file mode 100644
index 00000000000..ade9a9135ee
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -0,0 +1,400 @@
+package org.oppia.android.app.spotlight
+
+import android.content.res.Resources
+import android.os.Bundle
+import android.util.DisplayMetrics
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.animation.DecelerateInterpolator
+import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.Observer
+import androidx.lifecycle.lifecycleScope
+import com.takusemba.spotlight.OnSpotlightListener
+import com.takusemba.spotlight.OnTargetListener
+import com.takusemba.spotlight.Spotlight
+import com.takusemba.spotlight.Target
+import com.takusemba.spotlight.shape.Circle
+import com.takusemba.spotlight.shape.RoundedRectangle
+import com.takusemba.spotlight.shape.Shape
+import java.util.*
+import javax.inject.Inject
+import kotlinx.coroutines.launch
+import org.oppia.android.R
+import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.model.SpotlightViewState
+import org.oppia.android.app.onboarding.SpotlightNavigationListener
+import org.oppia.android.databinding.OverlayOverLeftBinding
+import org.oppia.android.databinding.OverlayOverRightBinding
+import org.oppia.android.databinding.OverlayUnderLeftBinding
+import org.oppia.android.databinding.OverlayUnderRightBinding
+import org.oppia.android.domain.spotlight.SpotlightStateController
+import org.oppia.android.util.data.AsyncResult
+import org.oppia.android.util.data.DataProviders.Companion.toLiveData
+
+class SpotlightFragment @Inject constructor(
+ val activity: AppCompatActivity,
+ val spotlightStateController: SpotlightStateController
+) : Fragment(), SpotlightNavigationListener {
+ var targetList = ArrayList()
+
+ var spotlightTargetList = ArrayList()
+
+ private lateinit var spotlight: Spotlight
+ private val overlay = "overlay"
+
+ private var screenHeight: Int = 0
+ private var screenWidth: Int = 0
+ private lateinit var anchorPosition: AnchorPosition
+ private lateinit var overlayBinding: Any
+
+ private lateinit var itemToSpotlight: View
+ private var isRTL = false
+ private var hintText = ""
+
+ init {
+ val displayMetrics = DisplayMetrics()
+ activity.windowManager.defaultDisplay.getMetrics(displayMetrics)
+
+ screenHeight = displayMetrics.heightPixels
+ screenWidth = displayMetrics.widthPixels
+
+ isRTL = checkIsRTL()
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+
+
+ lifecycleScope.launch {
+ for (i in spotlightTargetList) {
+ checkSpotlightViewState(i)
+ }
+ startSpotlight()
+ }
+ super.onViewCreated(view, savedInstanceState)
+ }
+
+
+
+ private fun checkSpotlightViewState(spotlightTarget: SpotlightTarget) {
+
+ val profileId = ProfileId.newBuilder()
+ .setInternalId(123)
+ .build()
+
+ val featureViewStateLiveData =
+ spotlightStateController.retrieveSpotlightViewState(
+ profileId,
+ spotlightTarget.feature
+ ).toLiveData()
+
+ featureViewStateLiveData.observe(
+ viewLifecycleOwner,
+ object : Observer> {
+ override fun onChanged(it: AsyncResult?) {
+ if (it is AsyncResult.Success) {
+ featureViewStateLiveData.removeObserver(this)
+ val viewState = (it.value as SpotlightViewState)
+ if (viewState == SpotlightViewState.SPOTLIGHT_SEEN) {
+ return
+ } else if (viewState == SpotlightViewState.SPOTLIGHT_VIEW_STATE_UNSPECIFIED || viewState == SpotlightViewState.SPOTLIGHT_NOT_SEEN) {
+
+ createTarget(spotlightTarget)
+ }
+ }
+ }
+ }
+
+ )
+ }
+
+ private fun createTarget(
+ spotlightTarget: SpotlightTarget
+ ) {
+ initialiseAnchor(spotlightTarget.anchor)
+ initialiseHintText(hintText)
+
+ val target = Target.Builder()
+ .setAnchor(spotlightTarget.anchor)
+ .setShape(getShape(spotlightTarget.shape))
+ .setOverlay(requestOverlayResource())
+ .setOnTargetListener(object : OnTargetListener {
+ override fun onStarted() {
+
+ }
+
+ override fun onEnded() {
+ val profileId = ProfileId.newBuilder()
+ .setInternalId(123)
+ .build()
+ spotlightStateController.recordSpotlightCheckpoint(
+ profileId,
+ spotlightTarget.feature,
+ SpotlightViewState.SPOTLIGHT_SEEN
+ )
+ }
+ })
+ .build()
+
+ targetList.add(target)
+ }
+
+ private fun startSpotlight() {
+ spotlight = Spotlight.Builder(activity)
+ .setTargets(targetList)
+ .setBackgroundColorRes(R.color.spotlightBackground)
+ .setDuration(1000L)
+ .setAnimation(DecelerateInterpolator(2f))
+ .setOnSpotlightListener(object : OnSpotlightListener {
+ override fun onStarted() {
+ }
+
+ override fun onEnded() {
+ }
+ })
+ .build()
+
+ spotlight.start()
+ }
+
+ private fun getShape(shape: SpotlightShape): Shape {
+ return when (shape) {
+ SpotlightShape.RoundedRectangle -> {
+ RoundedRectangle(itemToSpotlight.height.toFloat(), itemToSpotlight.width.toFloat(), 24f)
+ }
+ SpotlightShape.Circle -> {
+ return if (getAnchorHeight() > getAnchorWidth()) {
+ Circle((getAnchorHeight() / 2).toFloat())
+ } else {
+ Circle((getAnchorWidth() / 2).toFloat())
+ }
+ }
+ }
+ }
+
+ private fun checkIsRTL(): Boolean {
+ val locale = Locale.getDefault()
+ val directionality: Byte = Character.getDirectionality(locale.displayName[0].toInt())
+ return directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT || directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
+ }
+
+ private fun getArrowHeight(): Float {
+ return this.resources.getDimension(R.dimen.arrow_height)
+ }
+
+ private fun getArrowWidth(): Float {
+ return this.resources.getDimension(R.dimen.arrow_width)
+ }
+
+ private fun initialiseAnchor(itemToSpotlight: View) {
+ this.itemToSpotlight = itemToSpotlight
+ }
+
+ private fun initialiseHintText(hintText: String) {
+ this.hintText = hintText
+ }
+
+ private fun getAnchorLeft(): Float {
+ val location = IntArray(2)
+ itemToSpotlight.getLocationOnScreen(location)
+ val x = location[0]
+ return x.toFloat()
+ }
+
+ private fun getAnchorTop(): Float {
+ val location = IntArray(2)
+ itemToSpotlight.getLocationOnScreen(location)
+ val y = location[1]
+ return y.toFloat()
+ }
+
+ private fun getAnchorHeight(): Int {
+ return itemToSpotlight.height
+ }
+
+ private fun getAnchorWidth(): Int {
+ return itemToSpotlight.width
+ }
+
+ private fun getAnchorCentreX(): Float {
+ Log.d(overlay + "anchorCentre X ", (getAnchorLeft() + getAnchorWidth() / 2).toString())
+ return getAnchorLeft() + getAnchorWidth() / 2
+ }
+
+ private fun getAnchorCentreY(): Float {
+ Log.d(overlay + "anchorCentre Y ", (getAnchorTop() + getAnchorHeight() / 2).toString())
+ return getAnchorTop() + getAnchorHeight() / 2
+ }
+
+ private fun getScreenCentreX(): Int {
+ Log.d("overlay screenCentre X", (screenWidth / 2).toString())
+ return screenWidth / 2
+ }
+
+ private fun getScreenCentreY(): Int {
+ Log.d("overlay screenCentre Y", (screenHeight / 2).toString())
+ return screenHeight / 2
+ }
+
+ private fun calculateAnchorPosition() {
+ anchorPosition = if (getAnchorCentreX() > getScreenCentreX()) {
+ if (getAnchorCentreY() > getScreenCentreY()) {
+ AnchorPosition.BottomRight
+ } else {
+ AnchorPosition.TopRight
+ }
+ } else if (getAnchorCentreY() > getScreenCentreY()) {
+ AnchorPosition.BottomLeft
+ } else {
+ AnchorPosition.TopLeft
+ }
+
+ Log.d(overlay, anchorPosition.toString())
+ }
+
+ private fun requestOverlayResource(): View {
+ calculateAnchorPosition()
+
+ return when (anchorPosition) {
+ AnchorPosition.TopLeft -> {
+ if (isRTL) {
+ configureTopRightOverlay()
+ } else {
+ configureTopLeftOverlay()
+ }
+ }
+ AnchorPosition.TopRight -> {
+ configureTopRightOverlay()
+ }
+ AnchorPosition.BottomRight -> {
+ configureBottomRightOverlay()
+ }
+ AnchorPosition.BottomLeft -> {
+ configureBottomLeftOverlay()
+ }
+ }
+ }
+
+ private sealed class AnchorPosition {
+ object TopLeft : AnchorPosition()
+ object TopRight : AnchorPosition()
+ object BottomLeft : AnchorPosition()
+ object BottomRight : AnchorPosition()
+ }
+
+ override fun clickOnDismiss() {
+ spotlight.finish()
+ }
+
+ override fun clickOnNextTip() {
+ spotlight.next()
+ }
+
+ private fun configureBottomLeftOverlay(): View {
+ overlayBinding = OverlayOverLeftBinding.inflate(this.layoutInflater)
+ (overlayBinding as OverlayOverLeftBinding).let {
+ it.lifecycleOwner = this
+ it.presenter = this
+ }
+
+ (overlayBinding as OverlayOverLeftBinding).customText.text = hintText
+
+ val arrowParams = (overlayBinding as OverlayOverLeftBinding).arrow.layoutParams
+ as ViewGroup.MarginLayoutParams
+ arrowParams.setMargins(
+ getAnchorLeft().toInt(),
+ (getAnchorTop().toInt() - getArrowHeight()).toInt(),
+ 10.dp,
+ 10.dp
+ )
+// arrowParams.marginStart = getAnchorLeft().toInt()
+// arrowParams.marginEnd = 10.dp
+ (overlayBinding as OverlayOverLeftBinding).arrow.layoutParams = arrowParams
+
+ return (overlayBinding as OverlayOverLeftBinding).root
+ }
+
+ private fun configureBottomRightOverlay(): View {
+ overlayBinding = OverlayOverRightBinding.inflate(this.layoutInflater)
+ (overlayBinding as OverlayOverRightBinding).let {
+ it.lifecycleOwner = this
+ it.presenter = this
+ }
+
+ (overlayBinding as OverlayOverRightBinding).customText.text = hintText
+
+ val arrowParams = (overlayBinding as OverlayOverRightBinding).arrow.layoutParams
+ as ViewGroup.MarginLayoutParams
+ arrowParams.setMargins(
+ (getAnchorLeft() + getAnchorWidth() - getArrowWidth()).toInt(),
+ (getAnchorTop().toInt() - getArrowHeight()).toInt(),
+ 10.dp,
+ 10.dp
+ )
+// arrowParams.marginStart = (getAnchorLeft() + getAnchorWidth() - getArrowWidth()).toInt()
+// arrowParams.marginEnd = 10.dp
+ (overlayBinding as OverlayOverRightBinding).arrow.layoutParams = arrowParams
+
+ return (overlayBinding as OverlayOverRightBinding).root
+ }
+
+ private fun configureTopRightOverlay(): View {
+ overlayBinding = OverlayUnderRightBinding.inflate(layoutInflater)
+ (overlayBinding as OverlayUnderRightBinding).let {
+ it.lifecycleOwner = this
+ it.presenter = this
+ }
+
+ (overlayBinding as OverlayUnderRightBinding).customText.text = hintText
+
+ val arrowParams = (overlayBinding as OverlayUnderRightBinding).arrow.layoutParams
+ as ViewGroup.MarginLayoutParams
+ arrowParams.setMargins(
+ (getAnchorLeft() + getAnchorWidth() - getArrowWidth()).toInt(),
+ (getAnchorTop() + getAnchorHeight()).toInt(),
+ 10.dp,
+ 10.dp
+ )
+// arrowParams.marginStart = (getAnchorLeft() + getAnchorWidth() - getArrowWidth()).toInt()
+// arrowParams.marginEnd = 10.dp
+ (overlayBinding as OverlayUnderRightBinding).arrow.layoutParams = arrowParams
+
+ return (overlayBinding as OverlayUnderRightBinding).root
+ }
+
+ private fun configureTopLeftOverlay(): View {
+ overlayBinding = OverlayUnderLeftBinding.inflate(this.layoutInflater)
+ (overlayBinding as OverlayUnderLeftBinding).let {
+ it.lifecycleOwner = this
+ it.presenter = this
+ }
+
+ (overlayBinding as OverlayUnderLeftBinding).customText.text = hintText
+
+ val arrowParams = (overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams
+ as ViewGroup.MarginLayoutParams
+ arrowParams.setMargins(
+ getAnchorLeft().toInt(),
+ (getAnchorTop() + getAnchorHeight()).toInt(),
+ 10.dp,
+ 10.dp
+ )
+// arrowParams.marginStart = getAnchorLeft().toInt()
+// arrowParams.marginEnd = 10.dp
+ (overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams = arrowParams
+
+ return (overlayBinding as OverlayUnderLeftBinding).root
+ }
+
+ private val Int.dp: Int
+ get() = (this * Resources.getSystem().displayMetrics.density + 0.5f).toInt()
+}
+
+data class SpotlightTarget(
+ val anchor: View,
+ val hint: String = "",
+ val shape: SpotlightShape = SpotlightShape.RoundedRectangle,
+ val feature: org.oppia.android.app.model.Spotlight.FeatureCase
+)
\ No newline at end of file
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt
new file mode 100644
index 00000000000..78ffff851f8
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt
@@ -0,0 +1,7 @@
+package org.oppia.android.app.spotlight
+
+sealed class SpotlightShape {
+ object RoundedRectangle : SpotlightShape()
+ object Circle : SpotlightShape()
+}
+
diff --git a/app/src/main/res/layout/overlay_over_right.xml b/app/src/main/res/layout/overlay_over_right.xml
index 792af8d529e..502c7bcc4da 100644
--- a/app/src/main/res/layout/overlay_over_right.xml
+++ b/app/src/main/res/layout/overlay_over_right.xml
@@ -14,6 +14,8 @@
From 25dbfc4f6c560e0fd386659da3d6998fd71b1982 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 1 Jul 2022 00:18:47 +0530
Subject: [PATCH 022/138] rearrange
---
.../spotlight/SpotlightStateController.kt | 52 +++++++++----------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt b/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
index 7a92808bee2..dfa72bd629e 100644
--- a/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
+++ b/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
@@ -34,32 +34,6 @@ class SpotlightStateController @Inject constructor(
private val cacheStoreMap =
mutableMapOf>()
- private fun recordSpotlightStateAsync(
- profileId: ProfileId,
- feature: Spotlight.FeatureCase,
- viewState: SpotlightViewState
- ): Deferred {
- return retrieveCacheStore(profileId).storeDataWithCustomChannelAsync(
- updateInMemoryCache = true
- ) {
- val spotlightStateDatabaseBuilder = it.toBuilder()
-
- val spotlight = when (feature) {
- Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON -> {
- spotlightStateDatabaseBuilder.setOnboardingNextButton(viewState)
- }
- Spotlight.FeatureCase.TOPIC_LESSON_TAB -> {
- spotlightStateDatabaseBuilder.setTopicLessonTab(viewState)
- }
- else -> {
- throw SpotlightFeatureUnrecognizedException("spotlight feature is not one of the recognized types")
- }
- }
- val spotlightStateDatabase = spotlightStateDatabaseBuilder.build()
- Pair(spotlightStateDatabase, spotlight)
- }
- }
-
fun recordSpotlightCheckpoint(
profileId: ProfileId,
feature: Spotlight.FeatureCase,
@@ -106,6 +80,32 @@ class SpotlightStateController @Inject constructor(
}
}
+ private fun recordSpotlightStateAsync(
+ profileId: ProfileId,
+ feature: Spotlight.FeatureCase,
+ viewState: SpotlightViewState
+ ): Deferred {
+ return retrieveCacheStore(profileId).storeDataWithCustomChannelAsync(
+ updateInMemoryCache = true
+ ) {
+ val spotlightStateDatabaseBuilder = it.toBuilder()
+
+ val spotlight = when (feature) {
+ Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON -> {
+ spotlightStateDatabaseBuilder.setOnboardingNextButton(viewState)
+ }
+ Spotlight.FeatureCase.TOPIC_LESSON_TAB -> {
+ spotlightStateDatabaseBuilder.setTopicLessonTab(viewState)
+ }
+ else -> {
+ throw SpotlightFeatureUnrecognizedException("spotlight feature is not one of the recognized types")
+ }
+ }
+ val spotlightStateDatabase = spotlightStateDatabaseBuilder.build()
+ Pair(spotlightStateDatabase, spotlight)
+ }
+ }
+
private fun retrieveCacheStore(
profileId: ProfileId
): PersistentCacheStore {
From 08d72172eeb011a84b550cd1476ec4d28e3b3089 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Tue, 5 Jul 2022 03:09:39 +0530
Subject: [PATCH 023/138] commit because i need to see another commit
---
.../onboarding/OnboardingFragmentPresenter.kt | 2 +-
.../app/spotlight/SpotlightFragment.kt | 75 ++++++++++++-------
.../main/res/layout/onboarding_activity.xml | 26 +++++--
.../spotlight/SpotlightStateController.kt | 14 +++-
4 files changed, 81 insertions(+), 36 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index 597f4443b80..11676ff0e36 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -257,7 +257,7 @@ class OnboardingFragmentPresenter @Inject constructor(
val targetList = ArrayList()
targetList.add(onboardingButtonSpotlight)
- spotlightFragment.spotlightTargetList = targetList
+ spotlightFragment.initialiseTargetList(targetList)
activity.supportFragmentManager.beginTransaction()
.add(R.id.onboarding_fragment_placeholder, spotlightFragment)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index ade9a9135ee..59292864ece 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -8,6 +8,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.DecelerateInterpolator
+import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
@@ -21,6 +22,7 @@ import com.takusemba.spotlight.shape.RoundedRectangle
import com.takusemba.spotlight.shape.Shape
import java.util.*
import javax.inject.Inject
+import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.oppia.android.R
import org.oppia.android.app.model.ProfileId
@@ -38,9 +40,9 @@ class SpotlightFragment @Inject constructor(
val activity: AppCompatActivity,
val spotlightStateController: SpotlightStateController
) : Fragment(), SpotlightNavigationListener {
- var targetList = ArrayList()
+ private var targetList = ArrayList()
- var spotlightTargetList = ArrayList()
+ private var spotlightTargetList = ArrayList()
private lateinit var spotlight: Spotlight
private val overlay = "overlay"
@@ -64,18 +66,37 @@ class SpotlightFragment @Inject constructor(
isRTL = checkIsRTL()
}
+ fun initialiseTargetList(spotlightTargets: ArrayList){
+ spotlightTargetList = spotlightTargets
+ }
+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ Log.d("overlay" , "inside on view created")
+
+// viewLifecycleOwner.lifecycleScope.launchWhenCreated {
+// for (i in spotlightTargetList) {
+// lifecycleScope.launchWhenCreated {
+ checkSpotlightViewState(spotlightTargetList[0])
+// }
+// }
+
+// }
+
- lifecycleScope.launch {
- for (i in spotlightTargetList) {
- checkSpotlightViewState(i)
- }
- startSpotlight()
- }
- super.onViewCreated(view, savedInstanceState)
}
+// override fun onCreateView(
+// inflater: LayoutInflater,
+// container: ViewGroup?,
+// savedInstanceState: Bundle?
+// ): View? {
+// val binding: OverlayOverLeftBinding = OverlayOverLeftBinding.inflate(inflater)
+// return binding.root
+// }
+
private fun checkSpotlightViewState(spotlightTarget: SpotlightTarget) {
@@ -92,16 +113,21 @@ class SpotlightFragment @Inject constructor(
featureViewStateLiveData.observe(
viewLifecycleOwner,
- object : Observer> {
- override fun onChanged(it: AsyncResult?) {
+ object : Observer> {
+ override fun onChanged(it: AsyncResult?) {
if (it is AsyncResult.Success) {
- featureViewStateLiveData.removeObserver(this)
- val viewState = (it.value as SpotlightViewState)
+
+ val viewState = (it.value)
if (viewState == SpotlightViewState.SPOTLIGHT_SEEN) {
return
} else if (viewState == SpotlightViewState.SPOTLIGHT_VIEW_STATE_UNSPECIFIED || viewState == SpotlightViewState.SPOTLIGHT_NOT_SEEN) {
+ Log.d("overlay",viewState.toString())
+ Log.d("overlay", "adding target ")
createTarget(spotlightTarget)
+ startSpotlight()
+
+ featureViewStateLiveData.removeObserver(this)
}
}
}
@@ -126,14 +152,14 @@ class SpotlightFragment @Inject constructor(
}
override fun onEnded() {
- val profileId = ProfileId.newBuilder()
- .setInternalId(123)
- .build()
- spotlightStateController.recordSpotlightCheckpoint(
- profileId,
- spotlightTarget.feature,
- SpotlightViewState.SPOTLIGHT_SEEN
- )
+// val profileId = ProfileId.newBuilder()
+// .setInternalId(123)
+// .build()
+// spotlightStateController.recordSpotlightCheckpoint(
+// profileId,
+// spotlightTarget.feature,
+// SpotlightViewState.SPOTLIGHT_SEEN
+// )
}
})
.build()
@@ -391,10 +417,3 @@ class SpotlightFragment @Inject constructor(
private val Int.dp: Int
get() = (this * Resources.getSystem().displayMetrics.density + 0.5f).toInt()
}
-
-data class SpotlightTarget(
- val anchor: View,
- val hint: String = "",
- val shape: SpotlightShape = SpotlightShape.RoundedRectangle,
- val feature: org.oppia.android.app.model.Spotlight.FeatureCase
-)
\ No newline at end of file
diff --git a/app/src/main/res/layout/onboarding_activity.xml b/app/src/main/res/layout/onboarding_activity.xml
index a62631c63a3..fe6de777e9a 100644
--- a/app/src/main/res/layout/onboarding_activity.xml
+++ b/app/src/main/res/layout/onboarding_activity.xml
@@ -1,7 +1,23 @@
-
+ android:layout_width="match_parent"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+
+
+
+
+
+
+
+
+
diff --git a/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt b/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
index dfa72bd629e..496feb318af 100644
--- a/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
+++ b/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
@@ -14,13 +14,13 @@ import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.model.SpotlightStateDatabase
import org.oppia.android.app.model.SpotlightViewState
-private const val SPOTLIGHT_STATE_DATA_PROVIDER_ID = "spotlight_state_data_provider_id"
private const val CACHE_NAME = "spotlight_checkpoint_database"
private const val RECORD_SPOTLIGHT_CHECKPOINT_DATA_PROVIDER_ID =
"record_spotlight_checkpoint_provider_id"
private const val RETRIEVE_SPOTLIGHT_CHECKPOINT_DATA_PROVIDER_ID =
"retrieve_spotlight_checkpoint_provider_id"
+/** Handles saving and retrieving spotlight view states */
@Singleton
class SpotlightStateController @Inject constructor(
private val cacheStoreFactory: PersistentCacheStore.Factory,
@@ -34,6 +34,16 @@ class SpotlightStateController @Inject constructor(
private val cacheStoreMap =
mutableMapOf>()
+ /**
+ * Records SpotlightViewState of a Spotlight feature on a per profile basis
+ *
+ * @param profileId profileId of the current user
+ * @param feature the spotlight feature who's view state is to be recorded
+ * @param viewState SpotlightViewState of this spotlight feature
+ *
+ * @return AsyncResult
+ * @throws SpotlightFeatureUnrecognizedException
+ **/
fun recordSpotlightCheckpoint(
profileId: ProfileId,
feature: Spotlight.FeatureCase,
@@ -54,7 +64,7 @@ class SpotlightStateController @Inject constructor(
fun retrieveSpotlightViewState(
profileId: ProfileId,
feature: Spotlight.FeatureCase,
- ): DataProvider {
+ ): DataProvider {
return retrieveCacheStore(profileId)
.transformAsync(
RETRIEVE_SPOTLIGHT_CHECKPOINT_DATA_PROVIDER_ID
From b23becfb9fba63ba3ff6aff03d00261f270d7aef Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sat, 15 Oct 2022 00:51:49 +0530
Subject: [PATCH 024/138] commit before checkout
---
.../app/spotlight/SpotlightFragment.kt | 74 ++++++++++++++++---
.../oppia/android/app/topic/TopicFragment.kt | 4 +-
.../app/topic/TopicFragmentPresenter.kt | 31 ++++++--
3 files changed, 91 insertions(+), 18 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 59292864ece..656713806b9 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -1,5 +1,6 @@
package org.oppia.android.app.spotlight
+import android.content.Context
import android.content.res.Resources
import android.os.Bundle
import android.util.DisplayMetrics
@@ -70,6 +71,12 @@ class SpotlightFragment @Inject constructor(
spotlightTargetList = spotlightTargets
}
+ override fun onAttach(context: Context) {
+
+ super.onAttach(context)
+ start()
+ }
+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@@ -78,24 +85,22 @@ class SpotlightFragment @Inject constructor(
// viewLifecycleOwner.lifecycleScope.launchWhenCreated {
// for (i in spotlightTargetList) {
// lifecycleScope.launchWhenCreated {
- checkSpotlightViewState(spotlightTargetList[0])
+// checkSpotlightViewState(spotlightTargetList[0])
// }
// }
// }
+// checkSpotlightViewState(spotlightTargetList[0])
}
-// override fun onCreateView(
-// inflater: LayoutInflater,
-// container: ViewGroup?,
-// savedInstanceState: Bundle?
-// ): View? {
-// val binding: OverlayOverLeftBinding = OverlayOverLeftBinding.inflate(inflater)
-// return binding.root
-// }
+ fun start() {
+ createTarget(spotlightTargetList[0])
+ startSpotlight()
+ }
+
@@ -140,7 +145,7 @@ class SpotlightFragment @Inject constructor(
spotlightTarget: SpotlightTarget
) {
initialiseAnchor(spotlightTarget.anchor)
- initialiseHintText(hintText)
+ initialiseHintText(spotlightTarget.hint)
val target = Target.Builder()
.setAnchor(spotlightTarget.anchor)
@@ -417,3 +422,52 @@ class SpotlightFragment @Inject constructor(
private val Int.dp: Int
get() = (this * Resources.getSystem().displayMetrics.density + 0.5f).toInt()
}
+
+data class SpotlightTarget(
+ val anchor: View,
+ val hint: String = "",
+ val shape: SpotlightShape = SpotlightShape.RoundedRectangle,
+ val feature: org.oppia.android.app.model.Spotlight.FeatureCase
+) {
+ val positionParameters = PositionParameters(anchor)
+
+}
+
+data class PositionParameters(
+ val anchor: View
+) {
+ val anchorLeft: Float = calculateAnchorLeft()
+ val anchorTop: Float = calculateAnchorTop()
+ val anchorHeight: Int = calculateAnchorHeight()
+ val anchorWidth: Int = calculateAnchorWidth()
+
+ private fun calculateAnchorLeft(): Float {
+ val location = IntArray(2)
+ anchor.getLocationOnScreen(location)
+ val x = location[0]
+ return x.toFloat()
+ }
+
+ private fun calculateAnchorTop(): Float {
+ val location = IntArray(2)
+ anchor.getLocationOnScreen(location)
+ val y = location[1]
+ return y.toFloat()
+ }
+
+ private fun calculateAnchorHeight(): Int {
+ return anchor.height
+ }
+
+ private fun calculateAnchorWidth(): Int {
+ return anchor.width
+ }
+
+ private fun calculateAnchorCentreX(): Float {
+ return anchorLeft + anchorWidth / 2
+ }
+
+ private fun calculateAnchorCentreY(): Float {
+ return anchorTop + anchorHeight / 2
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
index e51a476838b..e618b9553df 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
@@ -43,8 +43,6 @@ class TopicFragment : InjectableFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- if (topicFragmentPresenter.enableSpotlightUi.value) {
-// topicFragmentPresenter.retrieveCheckpointAndInitializeSpotlight()
- }
+ topicFragmentPresenter.startSpotlight()
}
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 0b20ed826e7..133263b58e3 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -6,21 +6,22 @@ import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
-import androidx.lifecycle.Observer
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
-import java.util.*
import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
+import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.OverlayPositionAutomator
+import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightShape
+import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.TopicFragmentBinding
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.spotlight.SpotlightStateController
-
import org.oppia.android.util.platformparameter.EnableSpotlightUi
import org.oppia.android.util.platformparameter.PlatformParameterValue
import org.oppia.android.util.system.OppiaClock
@@ -36,6 +37,7 @@ class TopicFragmentPresenter @Inject constructor(
private val spotlightStateController: SpotlightStateController,
@EnableSpotlightUi val enableSpotlightUi: PlatformParameterValue,
@EnablePracticeTab private val enablePracticeTab: Boolean,
+ private val spotlightFragment: SpotlightFragment,
private val resourceHandler: AppLanguageResourceHandler
) {
private lateinit var tabLayout: TabLayout
@@ -51,6 +53,26 @@ class TopicFragmentPresenter @Inject constructor(
return tabLayout.getTabAt(tab.ordinal)!!.view
}
+ fun startSpotlight() {
+ spotlightFragment.initialiseTargetList(
+ arrayListOf(
+ SpotlightTarget(
+ getTab(TopicTab.LESSONS),
+ "hello",
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.TOPIC_LESSON_TAB
+ )
+ )
+ )
+ val fragmentManager = activity.supportFragmentManager.beginTransaction()
+ .add(
+ R.id.topic_fragment_placeholder,
+ spotlightFragment
+ )
+
+
+ }
+
fun handleCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@@ -79,8 +101,7 @@ class TopicFragmentPresenter @Inject constructor(
binding.topicToolbarTitle.isSelected = true
}
-
- spotlightOverlayPositionAutomator = OverlayPositionAutomator(activity, fragment)
+// spotlightOverlayPositionAutomator = OverlayPositionAutomator(activity, fragment)
val viewModel = getTopicViewModel()
viewModel.setInternalProfileId(internalProfileId)
From cf4bc9ce0c741d0f9b2c10f7a6dca75f53840ed2 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sun, 16 Oct 2022 23:43:29 +0530
Subject: [PATCH 025/138] store position parameters as fields
---
.../app/spotlight/SpotlightFragment.kt | 138 +++++++-----------
.../app/topic/TopicFragmentPresenter.kt | 4 +-
2 files changed, 58 insertions(+), 84 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 656713806b9..d6422742cf3 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -5,15 +5,12 @@ import android.content.res.Resources
import android.os.Bundle
import android.util.DisplayMetrics
import android.util.Log
-import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.DecelerateInterpolator
-import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
-import androidx.lifecycle.lifecycleScope
import com.takusemba.spotlight.OnSpotlightListener
import com.takusemba.spotlight.OnTargetListener
import com.takusemba.spotlight.Spotlight
@@ -23,8 +20,6 @@ import com.takusemba.spotlight.shape.RoundedRectangle
import com.takusemba.spotlight.shape.Shape
import java.util.*
import javax.inject.Inject
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
import org.oppia.android.R
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.SpotlightViewState
@@ -101,6 +96,12 @@ class SpotlightFragment @Inject constructor(
startSpotlight()
}
+ fun selfInitTargets(){
+ spotlightTargetList.forEach {
+ it.selfInitialize()
+ }
+ }
+
@@ -149,8 +150,8 @@ class SpotlightFragment @Inject constructor(
val target = Target.Builder()
.setAnchor(spotlightTarget.anchor)
- .setShape(getShape(spotlightTarget.shape))
- .setOverlay(requestOverlayResource())
+ .setShape(getShape(spotlightTarget))
+ .setOverlay(requestOverlayResource(spotlightTarget))
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
@@ -190,16 +191,16 @@ class SpotlightFragment @Inject constructor(
spotlight.start()
}
- private fun getShape(shape: SpotlightShape): Shape {
- return when (shape) {
+ private fun getShape(spotlightTarget: SpotlightTarget): Shape {
+ return when (spotlightTarget.shape) {
SpotlightShape.RoundedRectangle -> {
RoundedRectangle(itemToSpotlight.height.toFloat(), itemToSpotlight.width.toFloat(), 24f)
}
SpotlightShape.Circle -> {
- return if (getAnchorHeight() > getAnchorWidth()) {
- Circle((getAnchorHeight() / 2).toFloat())
+ return if (spotlightTarget.anchorHeight > spotlightTarget.anchorWidth) {
+ Circle((spotlightTarget.anchorHeight / 2).toFloat())
} else {
- Circle((getAnchorWidth() / 2).toFloat())
+ Circle((spotlightTarget.anchorWidth / 2).toFloat())
}
}
}
@@ -227,56 +228,20 @@ class SpotlightFragment @Inject constructor(
this.hintText = hintText
}
- private fun getAnchorLeft(): Float {
- val location = IntArray(2)
- itemToSpotlight.getLocationOnScreen(location)
- val x = location[0]
- return x.toFloat()
- }
-
- private fun getAnchorTop(): Float {
- val location = IntArray(2)
- itemToSpotlight.getLocationOnScreen(location)
- val y = location[1]
- return y.toFloat()
- }
-
- private fun getAnchorHeight(): Int {
- return itemToSpotlight.height
- }
-
- private fun getAnchorWidth(): Int {
- return itemToSpotlight.width
- }
-
- private fun getAnchorCentreX(): Float {
- Log.d(overlay + "anchorCentre X ", (getAnchorLeft() + getAnchorWidth() / 2).toString())
- return getAnchorLeft() + getAnchorWidth() / 2
- }
-
- private fun getAnchorCentreY(): Float {
- Log.d(overlay + "anchorCentre Y ", (getAnchorTop() + getAnchorHeight() / 2).toString())
- return getAnchorTop() + getAnchorHeight() / 2
- }
-
- private fun getScreenCentreX(): Int {
- Log.d("overlay screenCentre X", (screenWidth / 2).toString())
- return screenWidth / 2
- }
private fun getScreenCentreY(): Int {
Log.d("overlay screenCentre Y", (screenHeight / 2).toString())
return screenHeight / 2
}
- private fun calculateAnchorPosition() {
- anchorPosition = if (getAnchorCentreX() > getScreenCentreX()) {
- if (getAnchorCentreY() > getScreenCentreY()) {
+ private fun calculateAnchorPosition(spotlightTarget: SpotlightTarget) {
+ anchorPosition = if (spotlightTarget.anchorCentreX > spotlightTarget.anchorCentreY) {
+ if (spotlightTarget.anchorCentreY > getScreenCentreY()) {
AnchorPosition.BottomRight
} else {
AnchorPosition.TopRight
}
- } else if (getAnchorCentreY() > getScreenCentreY()) {
+ } else if (spotlightTarget.anchorCentreY > getScreenCentreY()) {
AnchorPosition.BottomLeft
} else {
AnchorPosition.TopLeft
@@ -285,25 +250,25 @@ class SpotlightFragment @Inject constructor(
Log.d(overlay, anchorPosition.toString())
}
- private fun requestOverlayResource(): View {
- calculateAnchorPosition()
+ private fun requestOverlayResource(spotlightTarget: SpotlightTarget): View {
+ calculateAnchorPosition(spotlightTarget)
return when (anchorPosition) {
AnchorPosition.TopLeft -> {
if (isRTL) {
- configureTopRightOverlay()
+ configureTopRightOverlay(spotlightTarget)
} else {
- configureTopLeftOverlay()
+ configureTopLeftOverlay(spotlightTarget)
}
}
AnchorPosition.TopRight -> {
- configureTopRightOverlay()
+ configureTopRightOverlay(spotlightTarget)
}
AnchorPosition.BottomRight -> {
- configureBottomRightOverlay()
+ configureBottomRightOverlay(spotlightTarget)
}
AnchorPosition.BottomLeft -> {
- configureBottomLeftOverlay()
+ configureBottomLeftOverlay(spotlightTarget)
}
}
}
@@ -323,7 +288,7 @@ class SpotlightFragment @Inject constructor(
spotlight.next()
}
- private fun configureBottomLeftOverlay(): View {
+ private fun configureBottomLeftOverlay(spotlightTarget: SpotlightTarget): View {
overlayBinding = OverlayOverLeftBinding.inflate(this.layoutInflater)
(overlayBinding as OverlayOverLeftBinding).let {
it.lifecycleOwner = this
@@ -335,19 +300,19 @@ class SpotlightFragment @Inject constructor(
val arrowParams = (overlayBinding as OverlayOverLeftBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
arrowParams.setMargins(
- getAnchorLeft().toInt(),
- (getAnchorTop().toInt() - getArrowHeight()).toInt(),
+ spotlightTarget.anchorLeft.toInt(),
+ (spotlightTarget.anchorTop.toInt() - spotlightTarget.anchorHeight).toInt(),
10.dp,
10.dp
)
-// arrowParams.marginStart = getAnchorLeft().toInt()
+// arrowParams.marginStart = spotlightTarget.anchorLeft.toInt()
// arrowParams.marginEnd = 10.dp
(overlayBinding as OverlayOverLeftBinding).arrow.layoutParams = arrowParams
return (overlayBinding as OverlayOverLeftBinding).root
}
- private fun configureBottomRightOverlay(): View {
+ private fun configureBottomRightOverlay(spotlightTarget: SpotlightTarget): View {
overlayBinding = OverlayOverRightBinding.inflate(this.layoutInflater)
(overlayBinding as OverlayOverRightBinding).let {
it.lifecycleOwner = this
@@ -359,19 +324,19 @@ class SpotlightFragment @Inject constructor(
val arrowParams = (overlayBinding as OverlayOverRightBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
arrowParams.setMargins(
- (getAnchorLeft() + getAnchorWidth() - getArrowWidth()).toInt(),
- (getAnchorTop().toInt() - getArrowHeight()).toInt(),
+ (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
+ (spotlightTarget.anchorTop.toInt() - spotlightTarget.anchorHeight).toInt(),
10.dp,
10.dp
)
-// arrowParams.marginStart = (getAnchorLeft() + getAnchorWidth() - getArrowWidth()).toInt()
+// arrowParams.marginStart = (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt()
// arrowParams.marginEnd = 10.dp
(overlayBinding as OverlayOverRightBinding).arrow.layoutParams = arrowParams
return (overlayBinding as OverlayOverRightBinding).root
}
- private fun configureTopRightOverlay(): View {
+ private fun configureTopRightOverlay(spotlightTarget: SpotlightTarget): View {
overlayBinding = OverlayUnderRightBinding.inflate(layoutInflater)
(overlayBinding as OverlayUnderRightBinding).let {
it.lifecycleOwner = this
@@ -383,19 +348,19 @@ class SpotlightFragment @Inject constructor(
val arrowParams = (overlayBinding as OverlayUnderRightBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
arrowParams.setMargins(
- (getAnchorLeft() + getAnchorWidth() - getArrowWidth()).toInt(),
- (getAnchorTop() + getAnchorHeight()).toInt(),
+ (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
+ (spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
10.dp,
10.dp
)
-// arrowParams.marginStart = (getAnchorLeft() + getAnchorWidth() - getArrowWidth()).toInt()
+// arrowParams.marginStart = (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt()
// arrowParams.marginEnd = 10.dp
(overlayBinding as OverlayUnderRightBinding).arrow.layoutParams = arrowParams
return (overlayBinding as OverlayUnderRightBinding).root
}
- private fun configureTopLeftOverlay(): View {
+ private fun configureTopLeftOverlay(spotlightTarget: SpotlightTarget): View {
overlayBinding = OverlayUnderLeftBinding.inflate(this.layoutInflater)
(overlayBinding as OverlayUnderLeftBinding).let {
it.lifecycleOwner = this
@@ -407,12 +372,12 @@ class SpotlightFragment @Inject constructor(
val arrowParams = (overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
arrowParams.setMargins(
- getAnchorLeft().toInt(),
- (getAnchorTop() + getAnchorHeight()).toInt(),
+ spotlightTarget.anchorLeft.toInt(),
+ (spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
10.dp,
10.dp
)
-// arrowParams.marginStart = getAnchorLeft().toInt()
+// arrowParams.marginStart = spotlightTarget.anchorLeft.toInt()
// arrowParams.marginEnd = 10.dp
(overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams = arrowParams
@@ -428,18 +393,24 @@ data class SpotlightTarget(
val hint: String = "",
val shape: SpotlightShape = SpotlightShape.RoundedRectangle,
val feature: org.oppia.android.app.model.Spotlight.FeatureCase
-) {
- val positionParameters = PositionParameters(anchor)
-
-}
-
-data class PositionParameters(
- val anchor: View
) {
val anchorLeft: Float = calculateAnchorLeft()
val anchorTop: Float = calculateAnchorTop()
val anchorHeight: Int = calculateAnchorHeight()
val anchorWidth: Int = calculateAnchorWidth()
+ val anchorCentreX = calculateAnchorCentreX()
+ val anchorCentreY = calculateAnchorCentreY()
+
+
+
+ fun selfInitialize() {
+ calculateAnchorLeft()
+ calculateAnchorTop()
+ calculateAnchorHeight()
+ calculateAnchorWidth()
+ calculateAnchorCentreX()
+ calculateAnchorCentreY()
+ }
private fun calculateAnchorLeft(): Float {
val location = IntArray(2)
@@ -470,4 +441,5 @@ data class PositionParameters(
private fun calculateAnchorCentreY(): Float {
return anchorTop + anchorHeight / 2
}
-}
\ No newline at end of file
+
+}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 133263b58e3..9ce8d72515c 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -64,11 +64,13 @@ class TopicFragmentPresenter @Inject constructor(
)
)
)
+
+ spotlightFragment.selfInitTargets()
val fragmentManager = activity.supportFragmentManager.beginTransaction()
.add(
R.id.topic_fragment_placeholder,
spotlightFragment
- )
+ ).commit()
}
From 7f7b623121f6ce73eddee8576db4d7eed57305d5 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Wed, 19 Oct 2022 19:44:12 +0530
Subject: [PATCH 026/138] all working. Partial impl for rtl compat
---
.../app/onboarding/OnboardingFragment.kt | 1 -
.../onboarding/OnboardingFragmentPresenter.kt | 38 +++++---
.../app/spotlight/SpotlightFragment.kt | 87 +++++++------------
.../app/topic/TopicFragmentPresenter.kt | 1 -
4 files changed, 54 insertions(+), 73 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
index 5b54c531b53..d9eb5dadb66 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
@@ -29,7 +29,6 @@ class OnboardingFragment : InjectableFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
onboardingFragmentPresenter.computeLastSpotlightCheckpoint()
- super.onViewCreated(view, savedInstanceState)
}
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index 11676ff0e36..bef05eca4c5 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -248,20 +248,32 @@ class OnboardingFragmentPresenter @Inject constructor(
fun computeLastSpotlightCheckpoint() {
- val onboardingButtonSpotlight = SpotlightTarget(
- binding.onboardingFragmentNextImageView,
- "Next",
- SpotlightShape.Circle,
- org.oppia.android.app.model.Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON
- )
+ binding.onboardingFragmentNextImageView.post {
+ val onboardingButtonSpotlight = SpotlightTarget(
+ binding.onboardingFragmentNextImageView,
+ "Next",
+ SpotlightShape.Circle,
+ org.oppia.android.app.model.Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON
+ )
+
+
+ val onboardingSkipSpotlight = SpotlightTarget(
+ binding.skipTextView,
+ "Next",
+ SpotlightShape.Circle,
+ org.oppia.android.app.model.Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON
+ )
+
- val targetList = ArrayList()
- targetList.add(onboardingButtonSpotlight)
- spotlightFragment.initialiseTargetList(targetList)
+ val targetList = ArrayList()
+ targetList.add(onboardingButtonSpotlight)
+ targetList.add(onboardingSkipSpotlight)
- activity.supportFragmentManager.beginTransaction()
- .add(R.id.onboarding_fragment_placeholder, spotlightFragment)
- .commit()
-
+ spotlightFragment.initialiseTargetList(targetList)
+ activity.supportFragmentManager.beginTransaction()
+ .add(R.id.onboarding_fragment_placeholder, spotlightFragment)
+ .commit()
+
+ }
}
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index d6422742cf3..1c554d9447e 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -2,7 +2,6 @@ package org.oppia.android.app.spotlight
import android.content.Context
import android.content.res.Resources
-import android.os.Bundle
import android.util.DisplayMetrics
import android.util.Log
import android.view.View
@@ -34,23 +33,23 @@ import org.oppia.android.util.data.DataProviders.Companion.toLiveData
class SpotlightFragment @Inject constructor(
val activity: AppCompatActivity,
- val spotlightStateController: SpotlightStateController
+ val spotlightStateController: SpotlightStateController,
) : Fragment(), SpotlightNavigationListener {
- private var targetList = ArrayList()
+ private var targetList = ArrayList()
private var spotlightTargetList = ArrayList()
private lateinit var spotlight: Spotlight
private val overlay = "overlay"
+ var counter = 0
private var screenHeight: Int = 0
private var screenWidth: Int = 0
private lateinit var anchorPosition: AnchorPosition
private lateinit var overlayBinding: Any
- private lateinit var itemToSpotlight: View
+
private var isRTL = false
- private var hintText = ""
init {
val displayMetrics = DisplayMetrics()
@@ -67,44 +66,13 @@ class SpotlightFragment @Inject constructor(
}
override fun onAttach(context: Context) {
-
super.onAttach(context)
- start()
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
-
- Log.d("overlay" , "inside on view created")
-
-// viewLifecycleOwner.lifecycleScope.launchWhenCreated {
-// for (i in spotlightTargetList) {
-// lifecycleScope.launchWhenCreated {
-// checkSpotlightViewState(spotlightTargetList[0])
-// }
-// }
-
-// }
-// checkSpotlightViewState(spotlightTargetList[0])
-
-
- }
-
- fun start() {
- createTarget(spotlightTargetList[0])
- startSpotlight()
- }
-
- fun selfInitTargets(){
spotlightTargetList.forEach {
- it.selfInitialize()
+ checkSpotlightViewState(it)
}
}
-
-
-
private fun checkSpotlightViewState(spotlightTarget: SpotlightTarget) {
val profileId = ProfileId.newBuilder()
@@ -118,7 +86,7 @@ class SpotlightFragment @Inject constructor(
).toLiveData()
featureViewStateLiveData.observe(
- viewLifecycleOwner,
+ activity,
object : Observer> {
override fun onChanged(it: AsyncResult?) {
if (it is AsyncResult.Success) {
@@ -131,7 +99,12 @@ class SpotlightFragment @Inject constructor(
Log.d("overlay",viewState.toString())
Log.d("overlay", "adding target ")
createTarget(spotlightTarget)
- startSpotlight()
+ counter++
+ if (counter == spotlightTargetList.size){
+ startSpotlight()
+ }
+
+
featureViewStateLiveData.removeObserver(this)
}
@@ -145,8 +118,6 @@ class SpotlightFragment @Inject constructor(
private fun createTarget(
spotlightTarget: SpotlightTarget
) {
- initialiseAnchor(spotlightTarget.anchor)
- initialiseHintText(spotlightTarget.hint)
val target = Target.Builder()
.setAnchor(spotlightTarget.anchor)
@@ -194,7 +165,7 @@ class SpotlightFragment @Inject constructor(
private fun getShape(spotlightTarget: SpotlightTarget): Shape {
return when (spotlightTarget.shape) {
SpotlightShape.RoundedRectangle -> {
- RoundedRectangle(itemToSpotlight.height.toFloat(), itemToSpotlight.width.toFloat(), 24f)
+ RoundedRectangle(spotlightTarget.anchorHeight.toFloat(), spotlightTarget.anchorWidth.toFloat(), 24f)
}
SpotlightShape.Circle -> {
return if (spotlightTarget.anchorHeight > spotlightTarget.anchorWidth) {
@@ -220,13 +191,7 @@ class SpotlightFragment @Inject constructor(
return this.resources.getDimension(R.dimen.arrow_width)
}
- private fun initialiseAnchor(itemToSpotlight: View) {
- this.itemToSpotlight = itemToSpotlight
- }
- private fun initialiseHintText(hintText: String) {
- this.hintText = hintText
- }
private fun getScreenCentreY(): Int {
@@ -265,10 +230,19 @@ class SpotlightFragment @Inject constructor(
configureTopRightOverlay(spotlightTarget)
}
AnchorPosition.BottomRight -> {
- configureBottomRightOverlay(spotlightTarget)
+ if (isRTL){
+ configureBottomLeftOverlay(spotlightTarget)
+
+ }else {
+ configureBottomRightOverlay(spotlightTarget)
+ }
}
AnchorPosition.BottomLeft -> {
- configureBottomLeftOverlay(spotlightTarget)
+ if (isRTL){
+ configureBottomRightOverlay(spotlightTarget)
+ }else {
+ configureBottomLeftOverlay(spotlightTarget)
+ }
}
}
}
@@ -295,7 +269,7 @@ class SpotlightFragment @Inject constructor(
it.presenter = this
}
- (overlayBinding as OverlayOverLeftBinding).customText.text = hintText
+ (overlayBinding as OverlayOverLeftBinding).customText.text = spotlightTarget.hint
val arrowParams = (overlayBinding as OverlayOverLeftBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
@@ -319,7 +293,7 @@ class SpotlightFragment @Inject constructor(
it.presenter = this
}
- (overlayBinding as OverlayOverRightBinding).customText.text = hintText
+ (overlayBinding as OverlayOverRightBinding).customText.text = spotlightTarget.hint
val arrowParams = (overlayBinding as OverlayOverRightBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
@@ -343,7 +317,7 @@ class SpotlightFragment @Inject constructor(
it.presenter = this
}
- (overlayBinding as OverlayUnderRightBinding).customText.text = hintText
+ (overlayBinding as OverlayUnderRightBinding).customText.text = spotlightTarget.hint
val arrowParams = (overlayBinding as OverlayUnderRightBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
@@ -367,7 +341,7 @@ class SpotlightFragment @Inject constructor(
it.presenter = this
}
- (overlayBinding as OverlayUnderLeftBinding).customText.text = hintText
+ (overlayBinding as OverlayUnderLeftBinding).customText.text = spotlightTarget.hint
val arrowParams = (overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
@@ -401,9 +375,7 @@ data class SpotlightTarget(
val anchorCentreX = calculateAnchorCentreX()
val anchorCentreY = calculateAnchorCentreY()
-
-
- fun selfInitialize() {
+ init {
calculateAnchorLeft()
calculateAnchorTop()
calculateAnchorHeight()
@@ -441,5 +413,4 @@ data class SpotlightTarget(
private fun calculateAnchorCentreY(): Float {
return anchorTop + anchorHeight / 2
}
-
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 9ce8d72515c..be3f2f9d6f1 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -65,7 +65,6 @@ class TopicFragmentPresenter @Inject constructor(
)
)
- spotlightFragment.selfInitTargets()
val fragmentManager = activity.supportFragmentManager.beginTransaction()
.add(
R.id.topic_fragment_placeholder,
From 99e14f6e63d5204a2f5bbe5f44473786c24c765c Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Wed, 19 Oct 2022 22:53:44 +0530
Subject: [PATCH 027/138] rtl functionality added
---
.../onboarding/OnboardingFragmentPresenter.kt | 4 +-
.../app/spotlight/SpotlightFragment.kt | 164 +++++++++++-------
app/src/main/res/layout/overlay_over_left.xml | 2 +
.../main/res/layout/overlay_over_right.xml | 18 +-
.../main/res/layout/overlay_under_left.xml | 10 +-
.../main/res/layout/overlay_under_right.xml | 1 +
6 files changed, 123 insertions(+), 76 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index bef05eca4c5..0c9e5a8d2f4 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -259,15 +259,15 @@ class OnboardingFragmentPresenter @Inject constructor(
val onboardingSkipSpotlight = SpotlightTarget(
binding.skipTextView,
- "Next",
+ "Skip",
SpotlightShape.Circle,
org.oppia.android.app.model.Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON
)
val targetList = ArrayList()
- targetList.add(onboardingButtonSpotlight)
targetList.add(onboardingSkipSpotlight)
+ targetList.add(onboardingButtonSpotlight)
spotlightFragment.initialiseTargetList(targetList)
activity.supportFragmentManager.beginTransaction()
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 1c554d9447e..5049315816b 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -48,7 +48,6 @@ class SpotlightFragment @Inject constructor(
private lateinit var anchorPosition: AnchorPosition
private lateinit var overlayBinding: Any
-
private var isRTL = false
init {
@@ -61,7 +60,7 @@ class SpotlightFragment @Inject constructor(
isRTL = checkIsRTL()
}
- fun initialiseTargetList(spotlightTargets: ArrayList){
+ fun initialiseTargetList(spotlightTargets: ArrayList) {
spotlightTargetList = spotlightTargets
}
@@ -96,16 +95,13 @@ class SpotlightFragment @Inject constructor(
return
} else if (viewState == SpotlightViewState.SPOTLIGHT_VIEW_STATE_UNSPECIFIED || viewState == SpotlightViewState.SPOTLIGHT_NOT_SEEN) {
- Log.d("overlay",viewState.toString())
+ Log.d("overlay", viewState.toString())
Log.d("overlay", "adding target ")
createTarget(spotlightTarget)
counter++
- if (counter == spotlightTargetList.size){
+ if (counter == spotlightTargetList.size) {
startSpotlight()
}
-
-
-
featureViewStateLiveData.removeObserver(this)
}
}
@@ -118,6 +114,7 @@ class SpotlightFragment @Inject constructor(
private fun createTarget(
spotlightTarget: SpotlightTarget
) {
+ spotlightTarget.logParams()
val target = Target.Builder()
.setAnchor(spotlightTarget.anchor)
@@ -129,14 +126,14 @@ class SpotlightFragment @Inject constructor(
}
override fun onEnded() {
-// val profileId = ProfileId.newBuilder()
-// .setInternalId(123)
-// .build()
-// spotlightStateController.recordSpotlightCheckpoint(
-// profileId,
-// spotlightTarget.feature,
-// SpotlightViewState.SPOTLIGHT_SEEN
-// )
+ val profileId = ProfileId.newBuilder()
+ .setInternalId(123)
+ .build()
+ spotlightStateController.recordSpotlightCheckpoint(
+ profileId,
+ spotlightTarget.feature,
+ SpotlightViewState.SPOTLIGHT_SEEN
+ )
}
})
.build()
@@ -165,7 +162,11 @@ class SpotlightFragment @Inject constructor(
private fun getShape(spotlightTarget: SpotlightTarget): Shape {
return when (spotlightTarget.shape) {
SpotlightShape.RoundedRectangle -> {
- RoundedRectangle(spotlightTarget.anchorHeight.toFloat(), spotlightTarget.anchorWidth.toFloat(), 24f)
+ RoundedRectangle(
+ spotlightTarget.anchorHeight.toFloat(),
+ spotlightTarget.anchorWidth.toFloat(),
+ 24f
+ )
}
SpotlightShape.Circle -> {
return if (spotlightTarget.anchorHeight > spotlightTarget.anchorWidth) {
@@ -183,24 +184,22 @@ class SpotlightFragment @Inject constructor(
return directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT || directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
}
- private fun getArrowHeight(): Float {
- return this.resources.getDimension(R.dimen.arrow_height)
- }
-
private fun getArrowWidth(): Float {
return this.resources.getDimension(R.dimen.arrow_width)
}
-
-
-
private fun getScreenCentreY(): Int {
Log.d("overlay screenCentre Y", (screenHeight / 2).toString())
return screenHeight / 2
}
+ private fun getScreenCentreX(): Int {
+ Log.d("overlay screenCentre X", (screenWidth / 2).toString())
+ return screenWidth / 2
+ }
+
private fun calculateAnchorPosition(spotlightTarget: SpotlightTarget) {
- anchorPosition = if (spotlightTarget.anchorCentreX > spotlightTarget.anchorCentreY) {
+ anchorPosition = if (spotlightTarget.anchorCentreX > getScreenCentreX()) {
if (spotlightTarget.anchorCentreY > getScreenCentreY()) {
AnchorPosition.BottomRight
} else {
@@ -230,17 +229,17 @@ class SpotlightFragment @Inject constructor(
configureTopRightOverlay(spotlightTarget)
}
AnchorPosition.BottomRight -> {
- if (isRTL){
+ if (isRTL) {
configureBottomLeftOverlay(spotlightTarget)
- }else {
+ } else {
configureBottomRightOverlay(spotlightTarget)
}
}
AnchorPosition.BottomLeft -> {
- if (isRTL){
+ if (isRTL) {
configureBottomRightOverlay(spotlightTarget)
- }else {
+ } else {
configureBottomLeftOverlay(spotlightTarget)
}
}
@@ -273,14 +272,24 @@ class SpotlightFragment @Inject constructor(
val arrowParams = (overlayBinding as OverlayOverLeftBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
- arrowParams.setMargins(
- spotlightTarget.anchorLeft.toInt(),
- (spotlightTarget.anchorTop.toInt() - spotlightTarget.anchorHeight).toInt(),
- 10.dp,
- 10.dp
- )
-// arrowParams.marginStart = spotlightTarget.anchorLeft.toInt()
-// arrowParams.marginEnd = 10.dp
+ if (false) {
+ arrowParams.setMargins(
+ 10.dp,
+ (spotlightTarget.anchorTop.toInt() - spotlightTarget.anchorHeight - 5.dp).toInt(),
+ screenWidth - spotlightTarget.anchorLeft.toInt(),
+ 10.dp
+ )
+ } else {
+ arrowParams.setMargins(
+ spotlightTarget.anchorLeft.toInt(),
+ (spotlightTarget.anchorTop.toInt() - spotlightTarget.anchorHeight - 5.dp).toInt(),
+ 10.dp,
+ 10.dp
+ )
+ }
+ Log.d("overlay", "arrowLeft: ${arrowParams.leftMargin}")
+ Log.d("overlay", "arrowTop: ${arrowParams.topMargin}")
+
(overlayBinding as OverlayOverLeftBinding).arrow.layoutParams = arrowParams
return (overlayBinding as OverlayOverLeftBinding).root
@@ -297,14 +306,24 @@ class SpotlightFragment @Inject constructor(
val arrowParams = (overlayBinding as OverlayOverRightBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
- arrowParams.setMargins(
- (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
- (spotlightTarget.anchorTop.toInt() - spotlightTarget.anchorHeight).toInt(),
- 10.dp,
- 10.dp
- )
-// arrowParams.marginStart = (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt()
-// arrowParams.marginEnd = 10.dp
+ if (isRTL) {
+ arrowParams.setMargins(
+ 10.dp,
+ (spotlightTarget.anchorTop.toInt() - spotlightTarget.anchorHeight - 5.dp).toInt(),
+ screenWidth - (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
+ 10.dp
+ )
+ } else {
+ arrowParams.setMargins(
+ (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
+ (spotlightTarget.anchorTop.toInt() - spotlightTarget.anchorHeight - 5.dp).toInt(),
+ 10.dp,
+ 10.dp
+ )
+ }
+ Log.d("overlay", "arrowLeft: ${arrowParams.leftMargin}")
+ Log.d("overlay", "arrowTop: ${arrowParams.topMargin}")
+
(overlayBinding as OverlayOverRightBinding).arrow.layoutParams = arrowParams
return (overlayBinding as OverlayOverRightBinding).root
@@ -321,14 +340,24 @@ class SpotlightFragment @Inject constructor(
val arrowParams = (overlayBinding as OverlayUnderRightBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
- arrowParams.setMargins(
- (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
- (spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
- 10.dp,
- 10.dp
- )
-// arrowParams.marginStart = (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt()
-// arrowParams.marginEnd = 10.dp
+ if (isRTL) {
+ arrowParams.setMargins(
+ 10.dp,
+ (spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
+ screenWidth - (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
+ 10.dp
+ )
+ } else {
+ arrowParams.setMargins(
+ (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth() + 5.dp).toInt(),
+ (spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
+ 10.dp,
+ 10.dp
+ )
+ }
+ Log.d("overlay", "arrowLeft: ${arrowParams.leftMargin}")
+ Log.d("overlay", "arrowTop: ${arrowParams.topMargin}")
+
(overlayBinding as OverlayUnderRightBinding).arrow.layoutParams = arrowParams
return (overlayBinding as OverlayUnderRightBinding).root
@@ -345,14 +374,24 @@ class SpotlightFragment @Inject constructor(
val arrowParams = (overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
- arrowParams.setMargins(
- spotlightTarget.anchorLeft.toInt(),
- (spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
- 10.dp,
- 10.dp
- )
-// arrowParams.marginStart = spotlightTarget.anchorLeft.toInt()
-// arrowParams.marginEnd = 10.dp
+ if (isRTL) {
+ arrowParams.setMargins(
+ 10.dp,
+ (spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
+ screenWidth - spotlightTarget.anchorLeft.toInt(),
+ 10.dp
+ )
+ } else {
+ arrowParams.setMargins(
+ spotlightTarget.anchorLeft.toInt(),
+ (spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
+ 10.dp,
+ 10.dp
+ )
+ }
+ Log.d("overlay", "arrowLeft: ${arrowParams.leftMargin}")
+ Log.d("overlay", "arrowTop: ${arrowParams.topMargin}")
+
(overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams = arrowParams
return (overlayBinding as OverlayUnderLeftBinding).root
@@ -398,6 +437,11 @@ data class SpotlightTarget(
return y.toFloat()
}
+ fun logParams() {
+ Log.d("overlay", "anchorLeft: " + anchorLeft.toString())
+ Log.d("overlay", "anchorTop: " + anchorTop.toString())
+ }
+
private fun calculateAnchorHeight(): Int {
return anchor.height
}
diff --git a/app/src/main/res/layout/overlay_over_left.xml b/app/src/main/res/layout/overlay_over_left.xml
index 4a1ee8c6fa7..7a3a869e71b 100644
--- a/app/src/main/res/layout/overlay_over_left.xml
+++ b/app/src/main/res/layout/overlay_over_left.xml
@@ -36,6 +36,8 @@
android:textColor="@android:color/white"
android:textSize="24dp"
android:textStyle="bold"
+ style="@style/TextViewStart"
+
app:layout_constraintStart_toStartOf="@+id/arrow"
app:layout_constraintBottom_toTopOf="@id/arrow" />
diff --git a/app/src/main/res/layout/overlay_over_right.xml b/app/src/main/res/layout/overlay_over_right.xml
index 502c7bcc4da..a8bd7b2aa6a 100644
--- a/app/src/main/res/layout/overlay_over_right.xml
+++ b/app/src/main/res/layout/overlay_over_right.xml
@@ -1,6 +1,5 @@
-
@@ -14,23 +13,24 @@
+ android:layout_height="match_parent"
+ android:clickable="true"
+ android:focusable="true">
+ app:layout_constraintBottom_toTopOf="@id/arrow"
+ app:layout_constraintEnd_toEndOf="@+id/arrow" />
-
@@ -19,14 +18,15 @@
+ app:layout_constraintStart_toStartOf="@id/arrow"
+ app:layout_constraintTop_toBottomOf="@id/arrow" />
Date: Wed, 19 Oct 2022 23:32:18 +0530
Subject: [PATCH 028/138] support for suspending spotlights when talkback is
being used
---
.../app/spotlight/SpotlightFragment.kt | 21 ++++++++++++-------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 5049315816b..61e8278721b 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -28,21 +28,20 @@ import org.oppia.android.databinding.OverlayOverRightBinding
import org.oppia.android.databinding.OverlayUnderLeftBinding
import org.oppia.android.databinding.OverlayUnderRightBinding
import org.oppia.android.domain.spotlight.SpotlightStateController
+import org.oppia.android.util.accessibility.AccessibilityServiceImpl
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
class SpotlightFragment @Inject constructor(
- val activity: AppCompatActivity,
- val spotlightStateController: SpotlightStateController,
+ private val activity: AppCompatActivity,
+ private val spotlightStateController: SpotlightStateController,
+ private val accessibilityServiceImpl: AccessibilityServiceImpl
) : Fragment(), SpotlightNavigationListener {
private var targetList = ArrayList()
-
private var spotlightTargetList = ArrayList()
-
private lateinit var spotlight: Spotlight
private val overlay = "overlay"
- var counter = 0
-
+ private var counter = 0
private var screenHeight: Int = 0
private var screenWidth: Int = 0
private lateinit var anchorPosition: AnchorPosition
@@ -64,11 +63,16 @@ class SpotlightFragment @Inject constructor(
spotlightTargetList = spotlightTargets
}
+ // since this fragment does not have any view to inflate yet, all the tasks should be done here.
override fun onAttach(context: Context) {
super.onAttach(context)
- spotlightTargetList.forEach {
- checkSpotlightViewState(it)
+ if (accessibilityServiceImpl.isScreenReaderEnabled()) {
+ activity.supportFragmentManager.beginTransaction().remove(this)
+ }else {
+ spotlightTargetList.forEach {
+ checkSpotlightViewState(it)
+ }
}
}
@@ -84,6 +88,7 @@ class SpotlightFragment @Inject constructor(
spotlightTarget.feature
).toLiveData()
+ // use activity as observer because this fragment's view hasn't been created yet.
featureViewStateLiveData.observe(
activity,
object : Observer> {
From cca553b048e349db5d3f832c60e9df5c2f479c5b Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 20 Oct 2022 19:53:53 +0530
Subject: [PATCH 029/138] use indexed list parser
---
.../java/org/oppia/android/app/spotlight/SpotlightFragment.kt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 61e8278721b..5536d01b02b 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -70,8 +70,8 @@ class SpotlightFragment @Inject constructor(
if (accessibilityServiceImpl.isScreenReaderEnabled()) {
activity.supportFragmentManager.beginTransaction().remove(this)
}else {
- spotlightTargetList.forEach {
- checkSpotlightViewState(it)
+ spotlightTargetList.forEachIndexed { _, spotlightTarget ->
+ checkSpotlightViewState(spotlightTarget)
}
}
}
From 020004dd53ae829b7787175c742722c64b91426e Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Wed, 26 Oct 2022 23:22:35 +0530
Subject: [PATCH 030/138] setup
---
.../java/org/oppia/android/app/onboarding/OnboardingFragment.kt | 1 -
1 file changed, 1 deletion(-)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
index d9eb5dadb66..83ab16eb163 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
@@ -28,7 +28,6 @@ class OnboardingFragment : InjectableFragment() {
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- onboardingFragmentPresenter.computeLastSpotlightCheckpoint()
}
}
From 6aff0021fbb53cb48fcedb41eba48ebdc014e1ae Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Wed, 26 Oct 2022 23:31:39 +0530
Subject: [PATCH 031/138] setup - not to be pushed
---
.../org/oppia/android/app/spotlight/SpotlightFragment.kt | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 8bd867ad1a7..b4eabb086d8 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -46,6 +46,7 @@ class SpotlightFragment @Inject constructor(
private var screenWidth: Int = 0
private lateinit var anchorPosition: AnchorPosition
private lateinit var overlayBinding: Any
+ private var internalProfileId: Int = -1
private var isRTL = false
@@ -59,8 +60,9 @@ class SpotlightFragment @Inject constructor(
isRTL = checkIsRTL()
}
- fun initialiseTargetList(spotlightTargets: ArrayList) {
+ fun initialiseTargetList(spotlightTargets: ArrayList, profileId: Int) {
spotlightTargetList = spotlightTargets
+ internalProfileId = profileId
}
// since this fragment does not have any view to inflate yet, all the tasks should be done here.
@@ -132,7 +134,7 @@ class SpotlightFragment @Inject constructor(
override fun onEnded() {
val profileId = ProfileId.newBuilder()
- .setInternalId(123)
+ .setInternalId(internalProfileId)
.build()
spotlightStateController.markSpotlightViewed(
profileId,
From 85de6603c846d2402162bda7ac61bc03b3d41652 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Wed, 26 Oct 2022 23:32:44 +0530
Subject: [PATCH 032/138] add lesson tab spotlight and content desc
---
.../app/topic/TopicFragmentPresenter.kt | 28 ++++++++++++++++++-
.../org/oppia/android/app/topic/TopicTab.kt | 15 ++++++----
app/src/main/res/values/strings.xml | 4 +++
3 files changed, 41 insertions(+), 6 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 6ff307e8f0f..b798adc089d 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -17,6 +17,10 @@ import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.util.platformparameter.EnableExtraTopicTabsUi
import org.oppia.android.util.platformparameter.PlatformParameterValue
import javax.inject.Inject
+import org.oppia.android.app.model.Spotlight
+import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightShape
+import org.oppia.android.app.spotlight.SpotlightTarget
/** The presenter for [TopicFragment]. */
@FragmentScope
@@ -26,7 +30,8 @@ class TopicFragmentPresenter @Inject constructor(
private val viewModel: TopicViewModel,
private val oppiaLogger: OppiaLogger,
@EnableExtraTopicTabsUi private val enableExtraTopicTabsUi: PlatformParameterValue,
- private val resourceHandler: AppLanguageResourceHandler
+ private val resourceHandler: AppLanguageResourceHandler,
+ private val spotlightFragment: SpotlightFragment
) {
private lateinit var tabLayout: TabLayout
private var internalProfileId: Int = -1
@@ -70,6 +75,26 @@ class TopicFragmentPresenter @Inject constructor(
return binding.root
}
+ fun startSpotlight() {
+ val lessonsTabView = tabLayout.getTabAt(computeTabPosition(TopicTab.LESSONS))?.view
+ lessonsTabView?.let{ lessonsTabView ->
+ lessonsTabView.post {
+ val lessonsTabSpotlightTarget = SpotlightTarget(
+ lessonsTabView,
+ "Find all your lessons here",
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.TOPIC_LESSON_TAB
+ )
+
+ val targetList = arrayListOf(lessonsTabSpotlightTarget)
+ spotlightFragment.initialiseTargetList(targetList, internalProfileId)
+ activity.supportFragmentManager.beginTransaction()
+ .add(spotlightFragment, "")
+ .commitNow()
+ }
+ }
+ }
+
private fun setCurrentTab(tab: TopicTab) {
viewPager.setCurrentItem(computeTabPosition(tab), true)
logTopicEvents(tab)
@@ -87,6 +112,7 @@ class TopicFragmentPresenter @Inject constructor(
val topicTab = TopicTab.getTabForPosition(position, enableExtraTopicTabsUi.value)
tab.text = resourceHandler.getStringInLocale(topicTab.tabLabelResId)
tab.icon = ContextCompat.getDrawable(activity, topicTab.tabIconResId)
+ tab.contentDescription = resourceHandler.getStringInLocale(topicTab.contentDescription)
}.attach()
if (!isConfigChanged && topicId.isNotEmpty()) {
if (enableExtraTopicTabsUi.value) {
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicTab.kt b/app/src/main/java/org/oppia/android/app/topic/TopicTab.kt
index 1609791493b..3a8b66d4830 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicTab.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicTab.kt
@@ -9,31 +9,36 @@ enum class TopicTab(
val positionWithTwoTabs: Int,
val positionWithFourTabs: Int,
@StringRes val tabLabelResId: Int,
- @DrawableRes val tabIconResId: Int
+ @DrawableRes val tabIconResId: Int,
+ @StringRes val contentDescription: Int
) {
INFO(
positionWithTwoTabs = -1,
positionWithFourTabs = 0,
tabLabelResId = R.string.info,
- tabIconResId = R.drawable.ic_info_icon_24dp
+ tabIconResId = R.drawable.ic_info_icon_24dp,
+ contentDescription = R.string.info_tab_content_description
),
LESSONS(
positionWithTwoTabs = 0,
positionWithFourTabs = 1,
tabLabelResId = R.string.lessons,
- tabIconResId = R.drawable.ic_lessons_icon_24dp
+ tabIconResId = R.drawable.ic_lessons_icon_24dp,
+ contentDescription = R.string.lessons_tab_content_description
),
PRACTICE(
positionWithTwoTabs = -1,
positionWithFourTabs = 2,
tabLabelResId = R.string.practice,
- tabIconResId = R.drawable.ic_practice_icon_24dp
+ tabIconResId = R.drawable.ic_practice_icon_24dp,
+ contentDescription = R.string.practice_tab_content_description
),
REVISION(
positionWithTwoTabs = 1,
positionWithFourTabs = 3,
tabLabelResId = R.string.revision,
- tabIconResId = R.drawable.ic_revision_icon_24dp
+ tabIconResId = R.drawable.ic_revision_icon_24dp,
+ contentDescription = R.string.revision_tab_content_description
);
companion object {
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8fb3f074919..7b4c664c89e 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -575,4 +575,8 @@
Administrator Controls Fragment Test Activity
Select a Topic to Start
Continue Studying
+ Info tab
+ After completing a lesson, revise your concepts in the revision tab.
+ Practice tab
+ Start learning here in the lessons tab.
From 4edef9e71f5ba618a062690693029e5a0a877745 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Wed, 26 Oct 2022 23:32:52 +0530
Subject: [PATCH 033/138] add test
---
.../android/app/topic/TopicFragmentTest.kt | 33 +++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
index 775d03f0949..0b2761e378e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
@@ -169,6 +169,39 @@ class TopicFragmentTest {
}
}
+ @Test
+ fun testTopicLessonTabSpotlight_spotlightNotSeenBefore_checkSpotlightIsShown() {
+ initializeApplicationComponent(false)
+ activityTestRule.launchActivity(
+ createTopicActivityIntent(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID
+ )
+ )
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.custom_text)).check(matches(withText("Find all your lessons here")))
+ }
+
+ @Test
+ fun testTopicLessonTabSpotlight_spotlightSeen_checkSpotlightIsNotShown() {
+ initializeApplicationComponent(false)
+ activityTestRule.launchActivity(
+ createTopicActivityIntent(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID
+ )
+ )
+ testCoroutineDispatchers.runCurrent()
+ activityTestRule.launchActivity(
+ createTopicActivityIntent(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID
+ )
+ )
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.custom_text)).check(doesNotExist())
+ }
+
@Test
fun testTopicFragment_toolbarTitle_marqueeInRtl_isDisplayedCorrectly() {
initializeApplicationComponent(false)
From 293150c93474b08b713383e84d4b389dcada08ef Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 27 Oct 2022 00:36:32 +0530
Subject: [PATCH 034/138] try to get reference to the toolbar through
findviewbyid
---
.../player/exploration/ExplorationFragment.kt | 2 +-
.../ExplorationFragmentPresenter.kt | 32 +++++++++++++++++--
.../oppia/android/app/topic/TopicFragment.kt | 1 -
3 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragment.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragment.kt
index b72f2f0da61..0ea284862d4 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragment.kt
@@ -56,7 +56,7 @@ class ExplorationFragment : InjectableFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- explorationFragmentPresenter.handleViewCreated()
+ explorationFragmentPresenter.handleViewCreated(view)
}
fun handlePlayAudio() = explorationFragmentPresenter.handlePlayAudio()
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index 99f12480320..20b6d548166 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -4,6 +4,8 @@ import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.widget.Toolbar
+import androidx.core.view.forEach
import androidx.fragment.app.Fragment
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
@@ -19,6 +21,11 @@ import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.extensions.getProto
import org.oppia.android.util.extensions.putProto
import javax.inject.Inject
+import kotlinx.android.synthetic.main.toolbar.*
+import org.oppia.android.app.model.Spotlight
+import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightShape
+import org.oppia.android.app.spotlight.SpotlightTarget
/** The presenter for [ExplorationFragment]. */
@FragmentScope
@@ -26,7 +33,8 @@ class ExplorationFragmentPresenter @Inject constructor(
private val fragment: Fragment,
private val oppiaLogger: OppiaLogger,
private val fontScaleConfigurationUtil: FontScaleConfigurationUtil,
- private val profileManagementController: ProfileManagementController
+ private val profileManagementController: ProfileManagementController,
+ private val spotlightFragment: SpotlightFragment
) {
/** Handles the [Fragment.onAttach] portion of [ExplorationFragment]'s lifecycle. */
fun handleAttach(context: Context) {
@@ -53,7 +61,7 @@ class ExplorationFragmentPresenter @Inject constructor(
}
/** Handles the [Fragment.onViewCreated] portion of [ExplorationFragment]'s lifecycle. */
- fun handleViewCreated() {
+ fun handleViewCreated(view: View) {
val profileDataProvider = profileManagementController.getProfile(retrieveArguments().profileId)
profileDataProvider.toLiveData().observe(
fragment,
@@ -68,6 +76,26 @@ class ExplorationFragmentPresenter @Inject constructor(
}
}
)
+ val toolbar: Toolbar = view.findViewById(R.id.exploration_toolbar)
+ toolbar.forEach {
+ if (it.id == R.id.action_audio_player) {
+ it.post {
+ val targetList = arrayListOf(
+ SpotlightTarget (
+ it,
+ "Would you like Oppia to read for you? Tap on this button to try!",
+ SpotlightShape.Circle,
+ Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
+ )
+ )
+
+ spotlightFragment.initialiseTargetList(targetList, 123)
+ fragment.childFragmentManager.beginTransaction()
+ .add(spotlightFragment, "")
+ .commitNow()
+ }
+ }
+ }
}
fun handlePlayAudio() {
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
index e618b9553df..fd4cc488fb3 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
@@ -43,6 +43,5 @@ class TopicFragment : InjectableFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- topicFragmentPresenter.startSpotlight()
}
}
From 169a1cbbde1de0169e941f9119354e398ceef982 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Wed, 26 Oct 2022 23:31:39 +0530
Subject: [PATCH 035/138] setup spotlight fragment
---
.../org/oppia/android/app/spotlight/SpotlightFragment.kt | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 8bd867ad1a7..b4eabb086d8 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -46,6 +46,7 @@ class SpotlightFragment @Inject constructor(
private var screenWidth: Int = 0
private lateinit var anchorPosition: AnchorPosition
private lateinit var overlayBinding: Any
+ private var internalProfileId: Int = -1
private var isRTL = false
@@ -59,8 +60,9 @@ class SpotlightFragment @Inject constructor(
isRTL = checkIsRTL()
}
- fun initialiseTargetList(spotlightTargets: ArrayList) {
+ fun initialiseTargetList(spotlightTargets: ArrayList, profileId: Int) {
spotlightTargetList = spotlightTargets
+ internalProfileId = profileId
}
// since this fragment does not have any view to inflate yet, all the tasks should be done here.
@@ -132,7 +134,7 @@ class SpotlightFragment @Inject constructor(
override fun onEnded() {
val profileId = ProfileId.newBuilder()
- .setInternalId(123)
+ .setInternalId(internalProfileId)
.build()
spotlightStateController.markSpotlightViewed(
profileId,
From 893e2cf2c41c343b522606b368d3c21f3afe707e Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 27 Oct 2022 14:05:43 +0530
Subject: [PATCH 036/138] re-structure the code
---
.../app/spotlight/SpotlightFragment.kt | 104 ++----------------
.../android/app/spotlight/SpotlightTarget.kt | 56 ++++++++++
2 files changed, 66 insertions(+), 94 deletions(-)
create mode 100644 app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index b4eabb086d8..3160db63c95 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -3,7 +3,6 @@ package org.oppia.android.app.spotlight
import android.content.Context
import android.content.res.Resources
import android.util.DisplayMetrics
-import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.view.animation.DecelerateInterpolator
@@ -40,24 +39,19 @@ class SpotlightFragment @Inject constructor(
private var targetList = ArrayList()
private var spotlightTargetList = ArrayList()
private lateinit var spotlight: Spotlight
- private val overlay = "overlay"
- private var counter = 0
private var screenHeight: Int = 0
private var screenWidth: Int = 0
private lateinit var anchorPosition: AnchorPosition
private lateinit var overlayBinding: Any
private var internalProfileId: Int = -1
-
private var isRTL = false
- init {
+ private fun calculateScreenSize() {
val displayMetrics = DisplayMetrics()
activity.windowManager.defaultDisplay.getMetrics(displayMetrics)
screenHeight = displayMetrics.heightPixels
screenWidth = displayMetrics.widthPixels
-
- isRTL = checkIsRTL()
}
fun initialiseTargetList(spotlightTargets: ArrayList, profileId: Int) {
@@ -72,6 +66,8 @@ class SpotlightFragment @Inject constructor(
if (accessibilityServiceImpl.isScreenReaderEnabled()) {
activity.supportFragmentManager.beginTransaction().remove(this)
}else {
+ calculateScreenSize()
+ checkIsRTL()
spotlightTargetList.forEachIndexed { _, spotlightTarget ->
checkSpotlightViewState(spotlightTarget)
}
@@ -79,9 +75,9 @@ class SpotlightFragment @Inject constructor(
}
private fun checkSpotlightViewState(spotlightTarget: SpotlightTarget) {
-
+ var counter = 0
val profileId = ProfileId.newBuilder()
- .setInternalId(123)
+ .setInternalId(internalProfileId)
.build()
val featureViewStateLiveData =
@@ -96,14 +92,10 @@ class SpotlightFragment @Inject constructor(
object : Observer> {
override fun onChanged(it: AsyncResult?) {
if (it is AsyncResult.Success) {
-
val viewState = (it.value)
if (viewState == SpotlightViewState.SPOTLIGHT_SEEN) {
return
- } else if (viewState == SpotlightViewState.SPOTLIGHT_VIEW_STATE_UNSPECIFIED || viewState == SpotlightViewState.SPOTLIGHT_NOT_SEEN) {
-
- Log.d("overlay", viewState.toString())
- Log.d("overlay", "adding target ")
+ } else if (viewState == SpotlightViewState.SPOTLIGHT_NOT_SEEN) {
createTarget(spotlightTarget)
counter++
if (counter == spotlightTargetList.size) {
@@ -114,15 +106,12 @@ class SpotlightFragment @Inject constructor(
}
}
}
-
)
}
private fun createTarget(
spotlightTarget: SpotlightTarget
) {
- spotlightTarget.logParams()
-
val target = Target.Builder()
.setAnchor(spotlightTarget.anchor)
.setShape(getShape(spotlightTarget))
@@ -158,6 +147,7 @@ class SpotlightFragment @Inject constructor(
}
override fun onEnded() {
+
}
})
.build()
@@ -184,10 +174,10 @@ class SpotlightFragment @Inject constructor(
}
}
- private fun checkIsRTL(): Boolean {
+ private fun checkIsRTL() {
val locale = Locale.getDefault()
val directionality: Byte = Character.getDirectionality(locale.displayName[0].toInt())
- return directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT || directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
+ isRTL = directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT || directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
}
private fun getArrowWidth(): Float {
@@ -195,12 +185,10 @@ class SpotlightFragment @Inject constructor(
}
private fun getScreenCentreY(): Int {
- Log.d("overlay screenCentre Y", (screenHeight / 2).toString())
return screenHeight / 2
}
private fun getScreenCentreX(): Int {
- Log.d("overlay screenCentre X", (screenWidth / 2).toString())
return screenWidth / 2
}
@@ -216,8 +204,6 @@ class SpotlightFragment @Inject constructor(
} else {
AnchorPosition.TopLeft
}
-
- Log.d(overlay, anchorPosition.toString())
}
private fun requestOverlayResource(spotlightTarget: SpotlightTarget): View {
@@ -278,7 +264,7 @@ class SpotlightFragment @Inject constructor(
val arrowParams = (overlayBinding as OverlayOverLeftBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
- if (false) {
+ if (isRTL) {
arrowParams.setMargins(
10.dp,
(spotlightTarget.anchorTop.toInt() - spotlightTarget.anchorHeight - 5.dp).toInt(),
@@ -293,9 +279,6 @@ class SpotlightFragment @Inject constructor(
10.dp
)
}
- Log.d("overlay", "arrowLeft: ${arrowParams.leftMargin}")
- Log.d("overlay", "arrowTop: ${arrowParams.topMargin}")
-
(overlayBinding as OverlayOverLeftBinding).arrow.layoutParams = arrowParams
return (overlayBinding as OverlayOverLeftBinding).root
@@ -327,9 +310,6 @@ class SpotlightFragment @Inject constructor(
10.dp
)
}
- Log.d("overlay", "arrowLeft: ${arrowParams.leftMargin}")
- Log.d("overlay", "arrowTop: ${arrowParams.topMargin}")
-
(overlayBinding as OverlayOverRightBinding).arrow.layoutParams = arrowParams
return (overlayBinding as OverlayOverRightBinding).root
@@ -361,9 +341,6 @@ class SpotlightFragment @Inject constructor(
10.dp
)
}
- Log.d("overlay", "arrowLeft: ${arrowParams.leftMargin}")
- Log.d("overlay", "arrowTop: ${arrowParams.topMargin}")
-
(overlayBinding as OverlayUnderRightBinding).arrow.layoutParams = arrowParams
return (overlayBinding as OverlayUnderRightBinding).root
@@ -395,9 +372,6 @@ class SpotlightFragment @Inject constructor(
10.dp
)
}
- Log.d("overlay", "arrowLeft: ${arrowParams.leftMargin}")
- Log.d("overlay", "arrowTop: ${arrowParams.topMargin}")
-
(overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams = arrowParams
return (overlayBinding as OverlayUnderLeftBinding).root
@@ -406,61 +380,3 @@ class SpotlightFragment @Inject constructor(
private val Int.dp: Int
get() = (this * Resources.getSystem().displayMetrics.density + 0.5f).toInt()
}
-
-data class SpotlightTarget(
- val anchor: View,
- val hint: String = "",
- val shape: SpotlightShape = SpotlightShape.RoundedRectangle,
- val feature: org.oppia.android.app.model.Spotlight.FeatureCase
-) {
- val anchorLeft: Float = calculateAnchorLeft()
- val anchorTop: Float = calculateAnchorTop()
- val anchorHeight: Int = calculateAnchorHeight()
- val anchorWidth: Int = calculateAnchorWidth()
- val anchorCentreX = calculateAnchorCentreX()
- val anchorCentreY = calculateAnchorCentreY()
-
- init {
- calculateAnchorLeft()
- calculateAnchorTop()
- calculateAnchorHeight()
- calculateAnchorWidth()
- calculateAnchorCentreX()
- calculateAnchorCentreY()
- }
-
- private fun calculateAnchorLeft(): Float {
- val location = IntArray(2)
- anchor.getLocationOnScreen(location)
- val x = location[0]
- return x.toFloat()
- }
-
- private fun calculateAnchorTop(): Float {
- val location = IntArray(2)
- anchor.getLocationOnScreen(location)
- val y = location[1]
- return y.toFloat()
- }
-
- fun logParams() {
- Log.d("overlay", "anchorLeft: " + anchorLeft.toString())
- Log.d("overlay", "anchorTop: " + anchorTop.toString())
- }
-
- private fun calculateAnchorHeight(): Int {
- return anchor.height
- }
-
- private fun calculateAnchorWidth(): Int {
- return anchor.width
- }
-
- private fun calculateAnchorCentreX(): Float {
- return anchorLeft + anchorWidth / 2
- }
-
- private fun calculateAnchorCentreY(): Float {
- return anchorTop + anchorHeight / 2
- }
-}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
new file mode 100644
index 00000000000..1677762cb56
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
@@ -0,0 +1,56 @@
+package org.oppia.android.app.spotlight
+
+import android.view.View
+
+data class SpotlightTarget(
+ val anchor: View,
+ val hint: String = "",
+ val shape: SpotlightShape = SpotlightShape.RoundedRectangle,
+ val feature: org.oppia.android.app.model.Spotlight.FeatureCase
+) {
+ val anchorLeft: Float = calculateAnchorLeft()
+ val anchorTop: Float = calculateAnchorTop()
+ val anchorHeight: Int = calculateAnchorHeight()
+ val anchorWidth: Int = calculateAnchorWidth()
+ val anchorCentreX = calculateAnchorCentreX()
+ val anchorCentreY = calculateAnchorCentreY()
+
+ init {
+ calculateAnchorLeft()
+ calculateAnchorTop()
+ calculateAnchorHeight()
+ calculateAnchorWidth()
+ calculateAnchorCentreX()
+ calculateAnchorCentreY()
+ }
+
+ private fun calculateAnchorLeft(): Float {
+ val location = IntArray(2)
+ anchor.getLocationOnScreen(location)
+ val x = location[0]
+ return x.toFloat()
+ }
+
+ private fun calculateAnchorTop(): Float {
+ val location = IntArray(2)
+ anchor.getLocationOnScreen(location)
+ val y = location[1]
+ return y.toFloat()
+ }
+
+ private fun calculateAnchorHeight(): Int {
+ return anchor.height
+ }
+
+ private fun calculateAnchorWidth(): Int {
+ return anchor.width
+ }
+
+ private fun calculateAnchorCentreX(): Float {
+ return anchorLeft + anchorWidth / 2
+ }
+
+ private fun calculateAnchorCentreY(): Float {
+ return anchorTop + anchorHeight / 2
+ }
+}
From 3116b1af8be9ceffa7f68f73975b90d0bdf8457c Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 27 Oct 2022 14:24:31 +0530
Subject: [PATCH 037/138] rename overlay layout resources
---
.../app/spotlight/SpotlightFragment.kt | 58 +++++++++----------
..._over_left.xml => bottom_left_overlay.xml} | 0
...ver_right.xml => bottom_right_overlay.xml} | 0
...ay_under_left.xml => top_left_overlay.xml} | 0
..._under_right.xml => top_right_overlay.xml} | 0
5 files changed, 29 insertions(+), 29 deletions(-)
rename app/src/main/res/layout/{overlay_over_left.xml => bottom_left_overlay.xml} (100%)
rename app/src/main/res/layout/{overlay_over_right.xml => bottom_right_overlay.xml} (100%)
rename app/src/main/res/layout/{overlay_under_left.xml => top_left_overlay.xml} (100%)
rename app/src/main/res/layout/{overlay_under_right.xml => top_right_overlay.xml} (100%)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 3160db63c95..2f2c01e09ab 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -16,16 +16,16 @@ import com.takusemba.spotlight.Target
import com.takusemba.spotlight.shape.Circle
import com.takusemba.spotlight.shape.RoundedRectangle
import com.takusemba.spotlight.shape.Shape
-import java.util.*
+import java.util.Locale
import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.SpotlightViewState
import org.oppia.android.app.onboarding.SpotlightNavigationListener
-import org.oppia.android.databinding.OverlayOverLeftBinding
-import org.oppia.android.databinding.OverlayOverRightBinding
-import org.oppia.android.databinding.OverlayUnderLeftBinding
-import org.oppia.android.databinding.OverlayUnderRightBinding
+import org.oppia.android.databinding.BottomLeftOverlayBinding
+import org.oppia.android.databinding.BottomRightOverlayBinding
+import org.oppia.android.databinding.TopLeftOverlayBinding
+import org.oppia.android.databinding.TopRightOverlayBinding
import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.util.accessibility.AccessibilityServiceImpl
import org.oppia.android.util.data.AsyncResult
@@ -254,15 +254,15 @@ class SpotlightFragment @Inject constructor(
}
private fun configureBottomLeftOverlay(spotlightTarget: SpotlightTarget): View {
- overlayBinding = OverlayOverLeftBinding.inflate(this.layoutInflater)
- (overlayBinding as OverlayOverLeftBinding).let {
+ overlayBinding = BottomLeftOverlayBinding.inflate(this.layoutInflater)
+ (overlayBinding as BottomLeftOverlayBinding).let {
it.lifecycleOwner = this
it.presenter = this
}
- (overlayBinding as OverlayOverLeftBinding).customText.text = spotlightTarget.hint
+ (overlayBinding as BottomLeftOverlayBinding).customText.text = spotlightTarget.hint
- val arrowParams = (overlayBinding as OverlayOverLeftBinding).arrow.layoutParams
+ val arrowParams = (overlayBinding as BottomLeftOverlayBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
if (isRTL) {
arrowParams.setMargins(
@@ -279,21 +279,21 @@ class SpotlightFragment @Inject constructor(
10.dp
)
}
- (overlayBinding as OverlayOverLeftBinding).arrow.layoutParams = arrowParams
+ (overlayBinding as BottomLeftOverlayBinding).arrow.layoutParams = arrowParams
- return (overlayBinding as OverlayOverLeftBinding).root
+ return (overlayBinding as BottomLeftOverlayBinding).root
}
private fun configureBottomRightOverlay(spotlightTarget: SpotlightTarget): View {
- overlayBinding = OverlayOverRightBinding.inflate(this.layoutInflater)
- (overlayBinding as OverlayOverRightBinding).let {
+ overlayBinding = BottomRightOverlayBinding.inflate(this.layoutInflater)
+ (overlayBinding as BottomRightOverlayBinding).let {
it.lifecycleOwner = this
it.presenter = this
}
- (overlayBinding as OverlayOverRightBinding).customText.text = spotlightTarget.hint
+ (overlayBinding as BottomRightOverlayBinding).customText.text = spotlightTarget.hint
- val arrowParams = (overlayBinding as OverlayOverRightBinding).arrow.layoutParams
+ val arrowParams = (overlayBinding as BottomRightOverlayBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
if (isRTL) {
arrowParams.setMargins(
@@ -310,21 +310,21 @@ class SpotlightFragment @Inject constructor(
10.dp
)
}
- (overlayBinding as OverlayOverRightBinding).arrow.layoutParams = arrowParams
+ (overlayBinding as BottomRightOverlayBinding).arrow.layoutParams = arrowParams
- return (overlayBinding as OverlayOverRightBinding).root
+ return (overlayBinding as BottomRightOverlayBinding).root
}
private fun configureTopRightOverlay(spotlightTarget: SpotlightTarget): View {
- overlayBinding = OverlayUnderRightBinding.inflate(layoutInflater)
- (overlayBinding as OverlayUnderRightBinding).let {
+ overlayBinding = TopRightOverlayBinding.inflate(layoutInflater)
+ (overlayBinding as TopRightOverlayBinding).let {
it.lifecycleOwner = this
it.presenter = this
}
- (overlayBinding as OverlayUnderRightBinding).customText.text = spotlightTarget.hint
+ (overlayBinding as TopRightOverlayBinding).customText.text = spotlightTarget.hint
- val arrowParams = (overlayBinding as OverlayUnderRightBinding).arrow.layoutParams
+ val arrowParams = (overlayBinding as TopRightOverlayBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
if (isRTL) {
arrowParams.setMargins(
@@ -341,21 +341,21 @@ class SpotlightFragment @Inject constructor(
10.dp
)
}
- (overlayBinding as OverlayUnderRightBinding).arrow.layoutParams = arrowParams
+ (overlayBinding as TopRightOverlayBinding).arrow.layoutParams = arrowParams
- return (overlayBinding as OverlayUnderRightBinding).root
+ return (overlayBinding as TopRightOverlayBinding).root
}
private fun configureTopLeftOverlay(spotlightTarget: SpotlightTarget): View {
- overlayBinding = OverlayUnderLeftBinding.inflate(this.layoutInflater)
- (overlayBinding as OverlayUnderLeftBinding).let {
+ overlayBinding = TopLeftOverlayBinding.inflate(this.layoutInflater)
+ (overlayBinding as TopLeftOverlayBinding).let {
it.lifecycleOwner = this
it.presenter = this
}
- (overlayBinding as OverlayUnderLeftBinding).customText.text = spotlightTarget.hint
+ (overlayBinding as TopLeftOverlayBinding).customText.text = spotlightTarget.hint
- val arrowParams = (overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams
+ val arrowParams = (overlayBinding as TopLeftOverlayBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
if (isRTL) {
arrowParams.setMargins(
@@ -372,9 +372,9 @@ class SpotlightFragment @Inject constructor(
10.dp
)
}
- (overlayBinding as OverlayUnderLeftBinding).arrow.layoutParams = arrowParams
+ (overlayBinding as TopLeftOverlayBinding).arrow.layoutParams = arrowParams
- return (overlayBinding as OverlayUnderLeftBinding).root
+ return (overlayBinding as TopLeftOverlayBinding).root
}
private val Int.dp: Int
diff --git a/app/src/main/res/layout/overlay_over_left.xml b/app/src/main/res/layout/bottom_left_overlay.xml
similarity index 100%
rename from app/src/main/res/layout/overlay_over_left.xml
rename to app/src/main/res/layout/bottom_left_overlay.xml
diff --git a/app/src/main/res/layout/overlay_over_right.xml b/app/src/main/res/layout/bottom_right_overlay.xml
similarity index 100%
rename from app/src/main/res/layout/overlay_over_right.xml
rename to app/src/main/res/layout/bottom_right_overlay.xml
diff --git a/app/src/main/res/layout/overlay_under_left.xml b/app/src/main/res/layout/top_left_overlay.xml
similarity index 100%
rename from app/src/main/res/layout/overlay_under_left.xml
rename to app/src/main/res/layout/top_left_overlay.xml
diff --git a/app/src/main/res/layout/overlay_under_right.xml b/app/src/main/res/layout/top_right_overlay.xml
similarity index 100%
rename from app/src/main/res/layout/overlay_under_right.xml
rename to app/src/main/res/layout/top_right_overlay.xml
From 643046338f384269eb1eaa756e81dbb66aee0389 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 27 Oct 2022 14:27:24 +0530
Subject: [PATCH 038/138] lint
---
.../app/onboarding/OnboardingFragment.kt | 1 -
.../app/onboarding/OnboardingViewModel.kt | 2 --
.../android/app/spotlight/SpotlightFragment.kt | 18 +++++++++---------
.../android/app/spotlight/SpotlightShape.kt | 1 -
4 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
index 83ab16eb163..4bc940d1ebd 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
@@ -28,6 +28,5 @@ class OnboardingFragment : InjectableFragment() {
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-
}
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt
index 8715dd77e9c..bea399282fb 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt
@@ -34,6 +34,4 @@ class OnboardingViewModel @Inject constructor(
totalNumberOfSlides.toString()
)
}
-
-
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 2f2c01e09ab..839e02e1415 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -16,8 +16,6 @@ import com.takusemba.spotlight.Target
import com.takusemba.spotlight.shape.Circle
import com.takusemba.spotlight.shape.RoundedRectangle
import com.takusemba.spotlight.shape.Shape
-import java.util.Locale
-import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.SpotlightViewState
@@ -30,6 +28,8 @@ import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.util.accessibility.AccessibilityServiceImpl
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
+import java.util.Locale
+import javax.inject.Inject
class SpotlightFragment @Inject constructor(
private val activity: AppCompatActivity,
@@ -65,7 +65,7 @@ class SpotlightFragment @Inject constructor(
if (accessibilityServiceImpl.isScreenReaderEnabled()) {
activity.supportFragmentManager.beginTransaction().remove(this)
- }else {
+ } else {
calculateScreenSize()
checkIsRTL()
spotlightTargetList.forEachIndexed { _, spotlightTarget ->
@@ -118,7 +118,6 @@ class SpotlightFragment @Inject constructor(
.setOverlay(requestOverlayResource(spotlightTarget))
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
-
}
override fun onEnded() {
@@ -147,7 +146,6 @@ class SpotlightFragment @Inject constructor(
}
override fun onEnded() {
-
}
})
.build()
@@ -177,7 +175,8 @@ class SpotlightFragment @Inject constructor(
private fun checkIsRTL() {
val locale = Locale.getDefault()
val directionality: Byte = Character.getDirectionality(locale.displayName[0].toInt())
- isRTL = directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT || directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
+ isRTL = directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT ||
+ directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
}
private fun getArrowWidth(): Float {
@@ -223,7 +222,6 @@ class SpotlightFragment @Inject constructor(
AnchorPosition.BottomRight -> {
if (isRTL) {
configureBottomLeftOverlay(spotlightTarget)
-
} else {
configureBottomRightOverlay(spotlightTarget)
}
@@ -299,7 +297,8 @@ class SpotlightFragment @Inject constructor(
arrowParams.setMargins(
10.dp,
(spotlightTarget.anchorTop.toInt() - spotlightTarget.anchorHeight - 5.dp).toInt(),
- screenWidth - (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
+ screenWidth -
+ (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
10.dp
)
} else {
@@ -330,7 +329,8 @@ class SpotlightFragment @Inject constructor(
arrowParams.setMargins(
10.dp,
(spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
- screenWidth - (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
+ screenWidth -
+ (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
10.dp
)
} else {
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt
index 78ffff851f8..fda6c4dcb91 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt
@@ -4,4 +4,3 @@ sealed class SpotlightShape {
object RoundedRectangle : SpotlightShape()
object Circle : SpotlightShape()
}
-
From 5f2c63416a3a4c2614fe613611f6fcfe68675bc9 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 27 Oct 2022 19:23:44 +0530
Subject: [PATCH 039/138] remove unused resources
---
.../app/onboarding/OnboardingFragment.kt | 3 -
.../app/onboarding/OnboardingViewModel.kt | 4 +-
.../oppia/android/app/topic/TopicFragment.kt | 6 --
app/src/main/res/drawable/ic_arrow.xml | 7 --
app/src/main/res/drawable/ic_roundedarrow.xml | 5 --
.../main/res/layout/onboarding_activity.xml | 26 ++-----
.../main/res/layout/onboarding_fragment.xml | 1 -
app/src/main/res/layout/overlay.xml | 71 -------------------
8 files changed, 6 insertions(+), 117 deletions(-)
delete mode 100644 app/src/main/res/drawable/ic_arrow.xml
delete mode 100644 app/src/main/res/drawable/ic_roundedarrow.xml
delete mode 100644 app/src/main/res/layout/overlay.xml
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
index 4bc940d1ebd..081abae41ee 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
@@ -26,7 +26,4 @@ class OnboardingFragment : InjectableFragment() {
): View? {
return onboardingFragmentPresenter.handleCreateView(inflater, container)
}
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- }
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt
index bea399282fb..f7f80e412cb 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingViewModel.kt
@@ -5,15 +5,13 @@ import androidx.lifecycle.ViewModel
import org.oppia.android.R
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ObservableViewModel
-import org.oppia.android.domain.spotlight.SpotlightStateController
import javax.inject.Inject
private const val INITIAL_SLIDE_NUMBER = 0
/** [ViewModel] for [OnboardingFragment]. */
class OnboardingViewModel @Inject constructor(
- private val resourceHandler: AppLanguageResourceHandler,
- private val spotlightStateController: SpotlightStateController
+ private val resourceHandler: AppLanguageResourceHandler
) : ObservableViewModel() {
val slideNumber = ObservableField(INITIAL_SLIDE_NUMBER)
val totalNumberOfSlides = TOTAL_NUMBER_OF_SLIDES
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
index e618b9553df..04d367b089e 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
@@ -39,10 +39,4 @@ class TopicFragment : InjectableFragment() {
isConfigChanged = savedInstanceState != null
)
}
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
-
- topicFragmentPresenter.startSpotlight()
- }
}
diff --git a/app/src/main/res/drawable/ic_arrow.xml b/app/src/main/res/drawable/ic_arrow.xml
deleted file mode 100644
index df1f0931b3e..00000000000
--- a/app/src/main/res/drawable/ic_arrow.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/ic_roundedarrow.xml b/app/src/main/res/drawable/ic_roundedarrow.xml
deleted file mode 100644
index 7bbb1f2b141..00000000000
--- a/app/src/main/res/drawable/ic_roundedarrow.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
diff --git a/app/src/main/res/layout/onboarding_activity.xml b/app/src/main/res/layout/onboarding_activity.xml
index fe6de777e9a..a62631c63a3 100644
--- a/app/src/main/res/layout/onboarding_activity.xml
+++ b/app/src/main/res/layout/onboarding_activity.xml
@@ -1,23 +1,7 @@
-
-
-
-
-
-
-
-
-
-
-
+ android:layout_height="match_parent"
+ tools:context="app.onboarding.OnboardingActivity" />
diff --git a/app/src/main/res/layout/onboarding_fragment.xml b/app/src/main/res/layout/onboarding_fragment.xml
index 42883a304d7..50f2545d200 100644
--- a/app/src/main/res/layout/onboarding_fragment.xml
+++ b/app/src/main/res/layout/onboarding_fragment.xml
@@ -16,7 +16,6 @@
diff --git a/app/src/main/res/layout/overlay.xml b/app/src/main/res/layout/overlay.xml
deleted file mode 100644
index 7494af94aae..00000000000
--- a/app/src/main/res/layout/overlay.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
From e75c95856afb0ecf5b67be9a202516b5c499e9ee Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 28 Oct 2022 19:55:50 +0530
Subject: [PATCH 040/138] toolbar can now be spotlit. todo: Add extra logic for
including some spotlight targets
---
.../ExplorationFragmentPresenter.kt | 70 +++++++++++++------
.../main/res/layout/overlay_under_right.xml | 3 +-
2 files changed, 50 insertions(+), 23 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index 20b6d548166..7013fc62333 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -4,7 +4,8 @@ import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import android.widget.Toolbar
+import android.widget.ImageButton
+import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.forEach
import androidx.fragment.app.Fragment
import org.oppia.android.R
@@ -21,7 +22,7 @@ import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.extensions.getProto
import org.oppia.android.util.extensions.putProto
import javax.inject.Inject
-import kotlinx.android.synthetic.main.toolbar.*
+import kotlinx.android.synthetic.main.exploration_activity.*
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightShape
@@ -64,33 +65,58 @@ class ExplorationFragmentPresenter @Inject constructor(
fun handleViewCreated(view: View) {
val profileDataProvider = profileManagementController.getProfile(retrieveArguments().profileId)
profileDataProvider.toLiveData().observe(
- fragment,
- { result ->
- val readingTextSize = retrieveArguments().readingTextSize
- if (result is AsyncResult.Success && result.value.readingTextSize != readingTextSize) {
- selectNewReadingTextSize(result.value.readingTextSize)
-
- // Since text views are based on sp for sizing, the activity needs to be recreated so that
- // sp can be correctly recomputed.
- fragment.requireActivity().recreate()
- }
+ fragment
+ ) { result ->
+ val readingTextSize = retrieveArguments().readingTextSize
+ if (result is AsyncResult.Success && result.value.readingTextSize != readingTextSize) {
+ selectNewReadingTextSize(result.value.readingTextSize)
+
+ // Since text views are based on sp for sizing, the activity needs to be recreated so that
+ // sp can be correctly recomputed.
+ fragment.requireActivity().recreate()
+ } else {
+ showSpotlights()
+// val toolbar = (fragment.requireActivity() as AppCompatActivity).action_audio_player
+// toolbar.post {
+// if (toolbar.visibility == View.GONE) return@post
+// val targetList = arrayListOf(
+// SpotlightTarget(
+// toolbar,
+// "Would you like Oppia to read for you? Tap on this button to try!",
+// SpotlightShape.Circle,
+// Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
+// )
+// )
+//
+// spotlightFragment.initialiseTargetList(targetList, 124)
+// fragment.requireActivity().supportFragmentManager.beginTransaction()
+// .add(spotlightFragment, "")
+// .commitNow()
+// }
+
+
}
- )
- val toolbar: Toolbar = view.findViewById(R.id.exploration_toolbar)
- toolbar.forEach {
- if (it.id == R.id.action_audio_player) {
- it.post {
+ }
+
+ }
+
+ private fun showSpotlights() {
+ val explorationToolbar = (fragment.requireActivity() as AppCompatActivity).exploration_toolbar
+ explorationToolbar.post {
+ explorationToolbar.forEach {
+ if (it is ImageButton) {
+ // this toolbar contains only one image button, which is the back navigation icon
val targetList = arrayListOf(
- SpotlightTarget (
+ SpotlightTarget(
it,
- "Would you like Oppia to read for you? Tap on this button to try!",
+ "Exit anytime using this button. We will save your progress.",
SpotlightShape.Circle,
Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
- )
+ )
)
- spotlightFragment.initialiseTargetList(targetList, 123)
- fragment.childFragmentManager.beginTransaction()
+ spotlightFragment.initialiseTargetList(targetList, 124)
+ fragment.requireActivity().supportFragmentManager.beginTransaction()
.add(spotlightFragment, "")
.commitNow()
}
diff --git a/app/src/main/res/layout/overlay_under_right.xml b/app/src/main/res/layout/overlay_under_right.xml
index 58a3a4cd5c5..e84a5da6981 100644
--- a/app/src/main/res/layout/overlay_under_right.xml
+++ b/app/src/main/res/layout/overlay_under_right.xml
@@ -35,11 +35,12 @@
android:layout_height="wrap_content"
android:gravity="center"
android:text="this is a custom text"
- android:textAlignment="center"
+ android:textAlignment="viewEnd"
android:textColor="@android:color/white"
style="@style/TextViewStart"
android:textSize="24dp"
android:textStyle="bold"
+ app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="@+id/arrow"
app:layout_constraintTop_toBottomOf="@id/arrow" />
From 594c511417eac597d40c12b31ef5d20764a1fa2e Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 28 Oct 2022 19:56:00 +0530
Subject: [PATCH 041/138] do not push
---
.../android/app/spotlight/SpotlightFragment.kt | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index b4eabb086d8..5d2aa90e97a 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -133,13 +133,13 @@ class SpotlightFragment @Inject constructor(
}
override fun onEnded() {
- val profileId = ProfileId.newBuilder()
- .setInternalId(internalProfileId)
- .build()
- spotlightStateController.markSpotlightViewed(
- profileId,
- spotlightTarget.feature
- )
+// val profileId = ProfileId.newBuilder()
+// .setInternalId(internalProfileId)
+// .build()
+// spotlightStateController.markSpotlightViewed(
+// profileId,
+// spotlightTarget.feature
+// )
}
})
.build()
From 7efee4f33e6d5070a3a1f32f9f1bd4f086882a10 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sun, 30 Oct 2022 00:39:36 +0530
Subject: [PATCH 042/138] spotlight languages icon
---
.../player/audio/AudioFragmentPresenter.kt | 32 +++++++++++++++++--
1 file changed, 29 insertions(+), 3 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index 07c50966429..1eae6405b29 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -13,14 +13,19 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.Transformations
+import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.AudioLanguage
import org.oppia.android.app.model.CellularDataPreference
import org.oppia.android.app.model.Profile
import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.model.State
import org.oppia.android.app.player.audio.AudioViewModel.UiAudioPlayStatus
+import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightShape
+import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.AudioFragmentBinding
@@ -30,7 +35,6 @@ import org.oppia.android.domain.profile.ProfileManagementController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.networking.NetworkConnectionUtil
-import javax.inject.Inject
const val TAG_LANGUAGE_DIALOG = "LANGUAGE_DIALOG"
private const val TAG_CELLULAR_DATA_DIALOG = "CELLULAR_DATA_DIALOG"
@@ -47,7 +51,8 @@ class AudioFragmentPresenter @Inject constructor(
private val networkConnectionUtil: NetworkConnectionUtil,
private val viewModelProvider: ViewModelProvider,
private val oppiaLogger: OppiaLogger,
- private val resourceHandler: AppLanguageResourceHandler
+ private val resourceHandler: AppLanguageResourceHandler,
+ private val spotlightFragment: SpotlightFragment
) {
var userIsSeeking = false
var userProgress = 0
@@ -59,6 +64,7 @@ class AudioFragmentPresenter @Inject constructor(
private val viewModel by lazy {
getAudioViewModel()
}
+ private lateinit var binding: AudioFragmentBinding
/** Sets up SeekBar listener, ViewModel, and gets VoiceoverMappings or restores saved state */
fun handleCreateView(
@@ -78,7 +84,7 @@ class AudioFragmentPresenter @Inject constructor(
}
)
- val binding = AudioFragmentBinding.inflate(inflater, container, /* attachToRoot= */ false)
+ binding = AudioFragmentBinding.inflate(inflater, container, /* attachToRoot= */ false)
binding.audioProgressSeekBar.setOnSeekBarChangeListener(
object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
@@ -113,6 +119,25 @@ class AudioFragmentPresenter @Inject constructor(
return binding.root
}
+ private fun startSpotlights() {
+ val audioLanguageIconView = binding.audioLanguageIcon
+ audioLanguageIconView.post {
+ val targetList = arrayListOf(
+ SpotlightTarget(
+ audioLanguageIconView,
+ "Tap to change",
+ SpotlightShape.Circle,
+ Spotlight.FeatureCase.VOICEOVER_LANGUAGE_ICON
+ )
+ )
+
+ spotlightFragment.initialiseTargetList(targetList, 1234)
+ activity.supportFragmentManager.beginTransaction()
+ .add(spotlightFragment, "")
+ .commitNow()
+ }
+ }
+
private fun getProfileData(): LiveData {
return Transformations.map(
profileManagementController.getProfile(profileId).toLiveData(),
@@ -263,6 +288,7 @@ class AudioFragmentPresenter @Inject constructor(
loadFeedbackAudio(feedbackId!!, true)
}
fragment.view?.startAnimation(AnimationUtils.loadAnimation(context, R.anim.slide_down_audio))
+ startSpotlights()
}
private fun hideAudioFragment() {
From 84e67378e761c97cd5372a52cbcc27bbb4097a2f Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sun, 30 Oct 2022 02:54:02 +0530
Subject: [PATCH 043/138] spotlight setup complete for base prs
---
.../android/app/spotlight/SpotlightFragment.kt | 14 +++++++-------
.../org/oppia/android/app/topic/TopicFragment.kt | 4 ----
2 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index b4eabb086d8..5d2aa90e97a 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -133,13 +133,13 @@ class SpotlightFragment @Inject constructor(
}
override fun onEnded() {
- val profileId = ProfileId.newBuilder()
- .setInternalId(internalProfileId)
- .build()
- spotlightStateController.markSpotlightViewed(
- profileId,
- spotlightTarget.feature
- )
+// val profileId = ProfileId.newBuilder()
+// .setInternalId(internalProfileId)
+// .build()
+// spotlightStateController.markSpotlightViewed(
+// profileId,
+// spotlightTarget.feature
+// )
}
})
.build()
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
index e618b9553df..0227a25af35 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
@@ -40,9 +40,5 @@ class TopicFragment : InjectableFragment() {
)
}
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- topicFragmentPresenter.startSpotlight()
- }
}
From e394d86ff964b6c8f1b7571056a4a7463557184b Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sun, 30 Oct 2022 02:54:40 +0530
Subject: [PATCH 044/138] add index to story, spotlight chapter using custom
view
---
...pterNotStartedContainerConstraintLayout.kt | 69 +++++++++++++++++++
.../topic/RouteToSpotlightFragmentListener.kt | 5 ++
.../topic/lessons/ChapterSummaryViewModel.kt | 3 +-
.../topic/lessons/StorySummaryViewModel.kt | 6 +-
.../app/topic/lessons/TopicLessonViewModel.kt | 5 +-
.../android/app/view/ViewComponentImpl.kt | 2 +
.../lessons_not_started_chapter_view.xml | 7 +-
7 files changed, 89 insertions(+), 8 deletions(-)
create mode 100644 app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
create mode 100644 app/src/main/java/org/oppia/android/app/topic/RouteToSpotlightFragmentListener.kt
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
new file mode 100644
index 00000000000..b0ba2128307
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -0,0 +1,69 @@
+package org.oppia.android.app.customview
+
+import android.content.Context
+import android.util.AttributeSet
+import android.util.Log
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentManager
+import javax.inject.Inject
+import org.oppia.android.app.model.Spotlight
+import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightShape
+import org.oppia.android.app.spotlight.SpotlightTarget
+import org.oppia.android.app.view.ViewComponentFactory
+import org.oppia.android.app.view.ViewComponentImpl
+
+class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : ConstraintLayout(context, attrs, defStyleAttr) {
+
+ private var index: Int = -1
+ private var isSpotlit = false
+
+ @Inject
+ lateinit var spotlightFragment: SpotlightFragment
+
+ @Inject
+ lateinit var fragment: Fragment
+
+ fun setStoryIndex(index: Int) {
+ // Only spotlight the first chapter of the "first" story. We know for sure that for a new user,
+ // the first chapter shall be a type of not started chapter view. The index tells which story
+ // are we on.
+ this.index = index
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+
+ val viewComponentFactory =
+ FragmentManager.findFragment(this) as ViewComponentFactory
+ val viewComponent = viewComponentFactory.createViewComponent(this) as ViewComponentImpl
+ viewComponent.inject(this)
+
+ this.post {
+ if (!isSpotlit) {
+ if (index == 0) {
+ val targetList = arrayListOf(
+ SpotlightTarget(
+ this,
+ "Tap to start a chapter",
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.FIRST_CHAPTER
+ )
+ )
+ spotlightFragment.initialiseTargetList(targetList, 123)
+ // this view is attached multiple times which can lead to crashes due [SpotlightFragment]
+ // being added multiple times. [isSpotlit] is a flag to prevent the same.
+ isSpotlit = true
+ fragment.childFragmentManager.beginTransaction()
+ .add(spotlightFragment, "")
+ .commitNow()
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/oppia/android/app/topic/RouteToSpotlightFragmentListener.kt b/app/src/main/java/org/oppia/android/app/topic/RouteToSpotlightFragmentListener.kt
new file mode 100644
index 00000000000..524b5bd486c
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/topic/RouteToSpotlightFragmentListener.kt
@@ -0,0 +1,5 @@
+package org.oppia.android.app.topic
+
+interface RouteToSpotlightFragmentListener {
+ fun routeToSpotlightFragment()
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/oppia/android/app/topic/lessons/ChapterSummaryViewModel.kt b/app/src/main/java/org/oppia/android/app/topic/lessons/ChapterSummaryViewModel.kt
index 62a499626e3..3da7ccee77f 100644
--- a/app/src/main/java/org/oppia/android/app/topic/lessons/ChapterSummaryViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/lessons/ChapterSummaryViewModel.kt
@@ -14,7 +14,8 @@ class ChapterSummaryViewModel(
val storyId: String,
private val index: Int,
private val chapterSummarySelector: ChapterSummarySelector,
- private val resourceHandler: AppLanguageResourceHandler
+ private val resourceHandler: AppLanguageResourceHandler,
+ val storyIndex: Int
) : ObservableViewModel() {
fun onClick(explorationId: String) {
diff --git a/app/src/main/java/org/oppia/android/app/topic/lessons/StorySummaryViewModel.kt b/app/src/main/java/org/oppia/android/app/topic/lessons/StorySummaryViewModel.kt
index a2d90d1134a..c57d89db6a2 100644
--- a/app/src/main/java/org/oppia/android/app/topic/lessons/StorySummaryViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/lessons/StorySummaryViewModel.kt
@@ -15,7 +15,8 @@ class StorySummaryViewModel(
private val storySummarySelector: StorySummarySelector,
private val chapterSummarySelector: ChapterSummarySelector,
private val resourceHandler: AppLanguageResourceHandler,
- private val translationController: TranslationController
+ private val translationController: TranslationController,
+ private val storyIndex: Int
) : TopicLessonsItemViewModel() {
val storySummary = ephemeralStorySummary.storySummary
val storyTitle by lazy {
@@ -90,7 +91,8 @@ class StorySummaryViewModel(
storyId = storySummary.storyId,
index = index,
chapterSummarySelector = chapterSummarySelector,
- resourceHandler = resourceHandler
+ resourceHandler = resourceHandler,
+ storyIndex = storyIndex
)
}
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/lessons/TopicLessonViewModel.kt b/app/src/main/java/org/oppia/android/app/topic/lessons/TopicLessonViewModel.kt
index 87a50c6d1d9..6e6cfc71789 100644
--- a/app/src/main/java/org/oppia/android/app/topic/lessons/TopicLessonViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/lessons/TopicLessonViewModel.kt
@@ -64,14 +64,15 @@ class TopicLessonViewModel @Inject constructor(
topicStoryList = ephemeralTopic.topic.storyList
itemList.clear()
itemList.add(TopicLessonsTitleViewModel())
- for (ephemeralStorySummary in ephemeralTopic.storiesList) {
+ ephemeralTopic.storiesList.forEachIndexed { index, ephemeralStorySummary ->
itemList.add(
StorySummaryViewModel(
ephemeralStorySummary,
fragment as StorySummarySelector,
fragment as ChapterSummarySelector,
resourceHandler,
- translationController
+ translationController,
+ index
)
)
}
diff --git a/app/src/main/java/org/oppia/android/app/view/ViewComponentImpl.kt b/app/src/main/java/org/oppia/android/app/view/ViewComponentImpl.kt
index 5be05546d1e..2b39ff29b43 100644
--- a/app/src/main/java/org/oppia/android/app/view/ViewComponentImpl.kt
+++ b/app/src/main/java/org/oppia/android/app/view/ViewComponentImpl.kt
@@ -3,6 +3,7 @@ package org.oppia.android.app.view
import android.view.View
import dagger.BindsInstance
import dagger.Subcomponent
+import org.oppia.android.app.customview.ChapterNotStartedContainerConstraintLayout
import org.oppia.android.app.customview.LessonThumbnailImageView
import org.oppia.android.app.customview.SegmentedCircularProgressView
import org.oppia.android.app.home.promotedlist.ComingSoonTopicsListView
@@ -33,4 +34,5 @@ interface ViewComponentImpl : ViewComponent {
fun inject(lessonThumbnailImageView: LessonThumbnailImageView)
fun inject(promotedStoryListView: PromotedStoryListView)
fun inject(segmentedCircularProgressView: SegmentedCircularProgressView)
+ fun inject(chapterNotStartedContainerConstraintLayout: ChapterNotStartedContainerConstraintLayout)
}
diff --git a/app/src/main/res/layout/lessons_not_started_chapter_view.xml b/app/src/main/res/layout/lessons_not_started_chapter_view.xml
index e6905547db8..358a7850e15 100644
--- a/app/src/main/res/layout/lessons_not_started_chapter_view.xml
+++ b/app/src/main/res/layout/lessons_not_started_chapter_view.xml
@@ -13,13 +13,14 @@
type="org.oppia.android.app.topic.lessons.ChapterSummaryViewModel" />
-
+ android:orientation="vertical"
+ android:storyIndex="@{viewModel.storyIndex}">
-
+
From 852c17510acc410c1bc0420056e214ef3d1d51b9 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sun, 30 Oct 2022 02:55:19 +0530
Subject: [PATCH 045/138] remove unused resources
---
.../customview/ChapterNotStartedContainerConstraintLayout.kt | 1 -
.../android/app/topic/RouteToSpotlightFragmentListener.kt | 5 -----
2 files changed, 6 deletions(-)
delete mode 100644 app/src/main/java/org/oppia/android/app/topic/RouteToSpotlightFragmentListener.kt
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index b0ba2128307..df3183f59ae 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -2,7 +2,6 @@ package org.oppia.android.app.customview
import android.content.Context
import android.util.AttributeSet
-import android.util.Log
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
diff --git a/app/src/main/java/org/oppia/android/app/topic/RouteToSpotlightFragmentListener.kt b/app/src/main/java/org/oppia/android/app/topic/RouteToSpotlightFragmentListener.kt
deleted file mode 100644
index 524b5bd486c..00000000000
--- a/app/src/main/java/org/oppia/android/app/topic/RouteToSpotlightFragmentListener.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package org.oppia.android.app.topic
-
-interface RouteToSpotlightFragmentListener {
- fun routeToSpotlightFragment()
-}
\ No newline at end of file
From c77e8e97b8c925597504e2a99d90e85d50face8d Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sun, 30 Oct 2022 20:25:51 +0530
Subject: [PATCH 046/138] setup
---
.../app/spotlight/SpotlightFragment.kt | 27 +++++++++++--------
app/src/main/res/layout/overlay_over_left.xml | 17 ++++++------
2 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 5d2aa90e97a..da738b1a7aa 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -81,7 +81,7 @@ class SpotlightFragment @Inject constructor(
private fun checkSpotlightViewState(spotlightTarget: SpotlightTarget) {
val profileId = ProfileId.newBuilder()
- .setInternalId(123)
+ .setInternalId(internalProfileId)
.build()
val featureViewStateLiveData =
@@ -133,13 +133,13 @@ class SpotlightFragment @Inject constructor(
}
override fun onEnded() {
-// val profileId = ProfileId.newBuilder()
-// .setInternalId(internalProfileId)
-// .build()
-// spotlightStateController.markSpotlightViewed(
-// profileId,
-// spotlightTarget.feature
-// )
+ val profileId = ProfileId.newBuilder()
+ .setInternalId(internalProfileId)
+ .build()
+ spotlightStateController.markSpotlightViewed(
+ profileId,
+ spotlightTarget.feature
+ )
}
})
.build()
@@ -158,6 +158,7 @@ class SpotlightFragment @Inject constructor(
}
override fun onEnded() {
+ this@SpotlightFragment.childFragmentManager.popBackStack()
}
})
.build()
@@ -194,6 +195,10 @@ class SpotlightFragment @Inject constructor(
return this.resources.getDimension(R.dimen.arrow_width)
}
+ private fun getArrowHeight(): Float {
+ return this.resources.getDimension(R.dimen.arrow_height)
+ }
+
private fun getScreenCentreY(): Int {
Log.d("overlay screenCentre Y", (screenHeight / 2).toString())
return screenHeight / 2
@@ -278,17 +283,17 @@ class SpotlightFragment @Inject constructor(
val arrowParams = (overlayBinding as OverlayOverLeftBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
- if (false) {
+ if (isRTL) {
arrowParams.setMargins(
10.dp,
- (spotlightTarget.anchorTop.toInt() - spotlightTarget.anchorHeight - 5.dp).toInt(),
+ (spotlightTarget.anchorTop.toInt() - getArrowHeight() - 5.dp).toInt(),
screenWidth - spotlightTarget.anchorLeft.toInt(),
10.dp
)
} else {
arrowParams.setMargins(
spotlightTarget.anchorLeft.toInt(),
- (spotlightTarget.anchorTop.toInt() - spotlightTarget.anchorHeight - 5.dp).toInt(),
+ (spotlightTarget.anchorTop.toInt() - getArrowHeight() - 5.dp).toInt(),
10.dp,
10.dp
)
diff --git a/app/src/main/res/layout/overlay_over_left.xml b/app/src/main/res/layout/overlay_over_left.xml
index 7a3a869e71b..894e079dbf5 100644
--- a/app/src/main/res/layout/overlay_over_left.xml
+++ b/app/src/main/res/layout/overlay_over_left.xml
@@ -1,6 +1,5 @@
-
@@ -19,8 +18,8 @@
+ app:layout_constraintBottom_toTopOf="@id/arrow"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="@+id/arrow" />
Date: Sun, 30 Oct 2022 20:26:22 +0530
Subject: [PATCH 047/138] add spotlight and tests
---
.../app/customview/PromotedStoryCardView.kt | 60 +++++++++++++++++++
.../oppia/android/app/home/HomeViewModel.kt | 5 +-
.../promotedlist/PromotedStoryViewModel.kt | 3 +-
.../android/app/view/ViewComponentImpl.kt | 2 +
.../main/res/layout/promoted_story_card.xml | 7 ++-
.../android/app/home/HomeActivityTest.kt | 48 ++++++++++++++-
.../PromotedStoryListViewModelTest.kt | 5 +-
.../PromotedStoryViewModelTest.kt | 27 ++++++---
8 files changed, 137 insertions(+), 20 deletions(-)
create mode 100644 app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
new file mode 100644
index 00000000000..27899c727e2
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -0,0 +1,60 @@
+package org.oppia.android.app.customview
+
+import android.content.Context
+import android.util.AttributeSet
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentManager
+import com.google.android.material.card.MaterialCardView
+import javax.inject.Inject
+import org.oppia.android.app.model.Spotlight
+import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightShape
+import org.oppia.android.app.spotlight.SpotlightTarget
+import org.oppia.android.app.view.ViewComponentFactory
+import org.oppia.android.app.view.ViewComponentImpl
+
+class PromotedStoryCardView @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+): MaterialCardView(context, attrs, defStyleAttr) {
+
+ private var promotedStoryIndex = -1
+
+ @Inject
+ lateinit var spotlightFragment: SpotlightFragment
+
+ @Inject
+ lateinit var fragment: Fragment
+
+ fun setIndex(index: Int) {
+ this.promotedStoryIndex = index
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+
+ val viewComponentFactory =
+ FragmentManager.findFragment(this) as ViewComponentFactory
+ val viewComponent = viewComponentFactory.createViewComponent(this) as ViewComponentImpl
+ viewComponent.inject(this)
+
+ this.post {
+ if (promotedStoryIndex == 0) {
+ val targetList = arrayListOf(
+ SpotlightTarget(
+ this,
+ "From now, here you can view stories you might be interested in",
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.PROMOTED_STORIES
+ )
+ )
+
+ spotlightFragment.initialiseTargetList(targetList, 123)
+ fragment.childFragmentManager.beginTransaction()
+ .add(spotlightFragment, "")
+ .commitNow()
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/oppia/android/app/home/HomeViewModel.kt b/app/src/main/java/org/oppia/android/app/home/HomeViewModel.kt
index 356bbd65f33..c8734e43845 100644
--- a/app/src/main/java/org/oppia/android/app/home/HomeViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/home/HomeViewModel.kt
@@ -194,14 +194,15 @@ class HomeViewModel(
// completed story topic.
val sortedStoryList = storyList.sortedByDescending { !it.isTopicLearned }
return sortedStoryList.take(promotedStoryListLimit)
- .map { promotedStory ->
+ .mapIndexed { index, promotedStory ->
PromotedStoryViewModel(
activity,
internalProfileId,
sortedStoryList.size,
storyEntityType,
promotedStory,
- translationController
+ translationController,
+ index
)
}
}
diff --git a/app/src/main/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModel.kt b/app/src/main/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModel.kt
index 38a8899204c..2adceb6abea 100755
--- a/app/src/main/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModel.kt
@@ -21,7 +21,8 @@ class PromotedStoryViewModel(
private val totalStoryCount: Int,
val entityType: String,
val promotedStory: PromotedStory,
- translationController: TranslationController
+ translationController: TranslationController,
+ val index: Int
) : ObservableViewModel() {
val storyTitle by lazy {
translationController.extractString(
diff --git a/app/src/main/java/org/oppia/android/app/view/ViewComponentImpl.kt b/app/src/main/java/org/oppia/android/app/view/ViewComponentImpl.kt
index 5be05546d1e..e9924c899f9 100644
--- a/app/src/main/java/org/oppia/android/app/view/ViewComponentImpl.kt
+++ b/app/src/main/java/org/oppia/android/app/view/ViewComponentImpl.kt
@@ -4,6 +4,7 @@ import android.view.View
import dagger.BindsInstance
import dagger.Subcomponent
import org.oppia.android.app.customview.LessonThumbnailImageView
+import org.oppia.android.app.customview.PromotedStoryCardView
import org.oppia.android.app.customview.SegmentedCircularProgressView
import org.oppia.android.app.home.promotedlist.ComingSoonTopicsListView
import org.oppia.android.app.home.promotedlist.PromotedStoryListView
@@ -33,4 +34,5 @@ interface ViewComponentImpl : ViewComponent {
fun inject(lessonThumbnailImageView: LessonThumbnailImageView)
fun inject(promotedStoryListView: PromotedStoryListView)
fun inject(segmentedCircularProgressView: SegmentedCircularProgressView)
+ fun inject(promotedStoryCardView: PromotedStoryCardView)
}
diff --git a/app/src/main/res/layout/promoted_story_card.xml b/app/src/main/res/layout/promoted_story_card.xml
index 1dc47e6eccd..465cc0c3605 100755
--- a/app/src/main/res/layout/promoted_story_card.xml
+++ b/app/src/main/res/layout/promoted_story_card.xml
@@ -11,7 +11,7 @@
type="org.oppia.android.app.home.promotedlist.PromotedStoryViewModel" />
-
+ app:cardElevation="4dp"
+ android:index="@{viewModel.index}">
-
+
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
index 6d4ecf49330..e59651af7c3 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
@@ -31,6 +31,9 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import dagger.Component
+import java.util.*
+import javax.inject.Inject
+import javax.inject.Singleton
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.Description
@@ -141,9 +144,6 @@ import org.oppia.android.util.parser.image.GlideImageLoaderModule
import org.oppia.android.util.parser.image.ImageParsingModule
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
-import java.util.Locale
-import javax.inject.Inject
-import javax.inject.Singleton
// Time: Tue Apr 23 2019 23:22:00
private const val EVENING_TIMESTAMP = 1556061720000
@@ -320,6 +320,48 @@ class HomeActivityTest {
}
}
+ @Test
+ fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_spotlightNeverSeenBefore_checkSpotlightShown() {
+ logIntoUserTwice()
+ launch(createHomeActivityIntent(internalProfileId1)).use {
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.custom_text)).check(matches(isDisplayed()))
+ onView(withId(R.id.custom_text)).check(
+ matches(
+ withText(
+ "From now, here you can view stories you might be interested in"
+ )
+ )
+ )
+ }
+ }
+
+ @Test
+ fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_spotlightAlreadySeenBefore_checkSpotlightIsNotShown() {
+ logIntoUserTwice()
+ launch(createHomeActivityIntent(internalProfileId1)).use {
+ testCoroutineDispatchers.runCurrent()
+
+ it.onActivity {
+ it.finish()
+ }
+ }
+ dataProviderTestMonitor.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
+ launch(createHomeActivityIntent(internalProfileId1)).use {
+ testCoroutineDispatchers.runCurrent()
+
+ onView(withId(R.id.custom_text)).check(doesNotExist())
+ }
+ }
+
+ @Test
+ fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_checkNotShownOnFirstLogin() {
+ launch(createHomeActivityIntent(internalProfileId1)).use {
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.custom_text)).check(doesNotExist())
+ }
+ }
+
@Test
fun testHomeActivity_recentlyPlayedStoriesTextIsDisplayed() {
fakeOppiaClock.setFakeTimeMode(FakeOppiaClock.FakeTimeMode.MODE_UPTIME_MILLIS)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryListViewModelTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryListViewModelTest.kt
index 6480ab29fb9..1312652fbc2 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryListViewModelTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryListViewModelTest.kt
@@ -321,14 +321,15 @@ class PromotedStoryListViewModelTest {
activity: AppCompatActivity,
promotedStoryList: List
): List {
- return promotedStoryList.map { promotedStory ->
+ return promotedStoryList.mapIndexed { index, promotedStory ->
PromotedStoryViewModel(
activity = activity,
internalProfileId = 1,
totalStoryCount = promotedStoryList.size,
entityType = "entity",
promotedStory = promotedStory,
- translationController
+ translationController,
+ index
)
}
}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModelTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModelTest.kt
index 3066d3f7671..a4e3ca71ac7 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModelTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModelTest.kt
@@ -211,7 +211,8 @@ class PromotedStoryViewModelTest {
totalStoryCount = 3,
entityType = "entity",
promotedStory = promotedStory1,
- translationController
+ translationController,
+ index = 0
)
val promotedStoryViewModelProfile2 = PromotedStoryViewModel(
activity = homeFragmentTestActivity,
@@ -219,7 +220,8 @@ class PromotedStoryViewModelTest {
totalStoryCount = 3,
entityType = "entity",
promotedStory = promotedStory1,
- translationController
+ translationController,
+ index = 0
)
assertThat(promotedStoryViewModelProfile1).isNotEqualTo(promotedStoryViewModelProfile2)
@@ -239,7 +241,8 @@ class PromotedStoryViewModelTest {
totalStoryCount = 2,
entityType = "entity",
promotedStory = promotedStory1,
- translationController
+ translationController,
+ index = 0
)
val promotedStoryViewModelStoryCount3 = PromotedStoryViewModel(
activity = homeFragmentTestActivity,
@@ -247,7 +250,8 @@ class PromotedStoryViewModelTest {
totalStoryCount = 3,
entityType = "entity",
promotedStory = promotedStory1,
- translationController
+ translationController,
+ index = 0
)
assertThat(promotedStoryViewModelStoryCount2)
@@ -268,7 +272,8 @@ class PromotedStoryViewModelTest {
totalStoryCount = 3,
entityType = "entity_1",
promotedStory = promotedStory1,
- translationController
+ translationController,
+ index = 0
)
val promotedStoryViewModelEntity2 = PromotedStoryViewModel(
activity = homeFragmentTestActivity,
@@ -276,7 +281,8 @@ class PromotedStoryViewModelTest {
totalStoryCount = 3,
entityType = "entity_2",
promotedStory = promotedStory1,
- translationController
+ translationController,
+ index = 0
)
assertThat(promotedStoryViewModelEntity1).isNotEqualTo(promotedStoryViewModelEntity2)
@@ -298,7 +304,8 @@ class PromotedStoryViewModelTest {
totalStoryCount = 3,
entityType = "entity",
promotedStory = promotedStory1,
- translationController
+ translationController,
+ index = 0
)
val promotedStoryViewModelStory2 = PromotedStoryViewModel(
activity = homeFragmentTestActivity,
@@ -306,7 +313,8 @@ class PromotedStoryViewModelTest {
totalStoryCount = 3,
entityType = "entity",
promotedStory = promotedStory2,
- translationController
+ translationController,
+ index = 0
)
assertThat(promotedStoryViewModelStory1).isNotEqualTo(promotedStoryViewModelStory2)
@@ -360,7 +368,8 @@ class PromotedStoryViewModelTest {
totalStoryCount = 3,
entityType = "entity",
promotedStory = promotedStory1,
- translationController
+ translationController,
+ index = 0
)
}
From 18f04d163cc892d6d23619a0aec82e69f2e13f15 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Wed, 2 Nov 2022 23:40:46 +0530
Subject: [PATCH 048/138] ben's suggestion
---
.../java/org/oppia/android/app/home/HomeActivityTest.kt | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
index e59651af7c3..ba6c7ff5df4 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
@@ -342,10 +342,8 @@ class HomeActivityTest {
launch(createHomeActivityIntent(internalProfileId1)).use {
testCoroutineDispatchers.runCurrent()
- it.onActivity {
- it.finish()
- }
}
+
dataProviderTestMonitor.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
launch(createHomeActivityIntent(internalProfileId1)).use {
testCoroutineDispatchers.runCurrent()
From 44ec527542861380399c01160de7e0ebd772c416 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 4 Nov 2022 23:47:15 +0530
Subject: [PATCH 049/138] revision and lesson tab spotlights working. Tests to
be added.
---
.../app/spotlight/SpotlightFragment.kt | 1 +
.../app/topic/TopicFragmentPresenter.kt | 61 +++++++++++++------
.../oppia/android/app/topic/TopicViewModel.kt | 35 +++++++++++
app/src/main/res/layout/overlay.xml | 48 ---------------
app/src/main/res/layout/overlay_over_left.xml | 1 +
.../main/res/layout/overlay_over_right.xml | 1 +
.../main/res/layout/overlay_under_left.xml | 1 +
.../main/res/layout/overlay_under_right.xml | 2 +-
8 files changed, 81 insertions(+), 69 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index b4eabb086d8..9fe166f4422 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -23,6 +23,7 @@ import org.oppia.android.R
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.SpotlightViewState
import org.oppia.android.app.onboarding.SpotlightNavigationListener
+import org.oppia.android.databinding.OverlayBinding
import org.oppia.android.databinding.OverlayOverLeftBinding
import org.oppia.android.databinding.OverlayOverRightBinding
import org.oppia.android.databinding.OverlayUnderLeftBinding
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index b798adc089d..588186b65b1 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -1,26 +1,28 @@
package org.oppia.android.app.topic
+import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
+import androidx.core.view.doOnPreDraw
import androidx.fragment.app.Fragment
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
+import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
+import org.oppia.android.app.model.Spotlight
+import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightShape
+import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.databinding.TopicFragmentBinding
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.util.platformparameter.EnableExtraTopicTabsUi
import org.oppia.android.util.platformparameter.PlatformParameterValue
-import javax.inject.Inject
-import org.oppia.android.app.model.Spotlight
-import org.oppia.android.app.spotlight.SpotlightFragment
-import org.oppia.android.app.spotlight.SpotlightShape
-import org.oppia.android.app.spotlight.SpotlightTarget
/** The presenter for [TopicFragment]. */
@FragmentScope
@@ -76,21 +78,40 @@ class TopicFragmentPresenter @Inject constructor(
}
fun startSpotlight() {
- val lessonsTabView = tabLayout.getTabAt(computeTabPosition(TopicTab.LESSONS))?.view
- lessonsTabView?.let{ lessonsTabView ->
- lessonsTabView.post {
- val lessonsTabSpotlightTarget = SpotlightTarget(
- lessonsTabView,
- "Find all your lessons here",
- SpotlightShape.RoundedRectangle,
- Spotlight.FeatureCase.TOPIC_LESSON_TAB
- )
-
- val targetList = arrayListOf(lessonsTabSpotlightTarget)
- spotlightFragment.initialiseTargetList(targetList, internalProfileId)
- activity.supportFragmentManager.beginTransaction()
- .add(spotlightFragment, "")
- .commitNow()
+ viewModel.numberOfChaptersCompletedLiveData.observe(fragment) { numberOfChaptersCompleted->
+ if (numberOfChaptersCompleted != -1) {
+ val lessonsTabView = tabLayout.getTabAt(computeTabPosition(TopicTab.LESSONS))?.view
+ lessonsTabView?.let { lessonsTabView ->
+ lessonsTabView.doOnPreDraw {
+ val lessonsTabSpotlightTarget = SpotlightTarget(
+ lessonsTabView,
+ "Find all your lessons here",
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.TOPIC_LESSON_TAB
+ )
+
+ if (numberOfChaptersCompleted > 2) {
+ val revisionTabView = tabLayout.getTabAt(computeTabPosition(TopicTab.REVISION))?.view
+ val revisionTabSpotlightTarget = SpotlightTarget(
+ revisionTabView!!,
+ "Revise your lessons here",
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.TOPIC_REVISION_TAB
+ )
+ val targetList = arrayListOf(lessonsTabSpotlightTarget, revisionTabSpotlightTarget)
+ spotlightFragment.initialiseTargetList(targetList, internalProfileId)
+ activity.supportFragmentManager.beginTransaction()
+ .add(spotlightFragment, "")
+ .commitNow()
+ } else {
+ val targetList = arrayListOf(lessonsTabSpotlightTarget)
+ spotlightFragment.initialiseTargetList(targetList, internalProfileId)
+ activity.supportFragmentManager.beginTransaction()
+ .add(spotlightFragment, "")
+ .commitNow()
+ }
+ }
+ }
}
}
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt b/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
index 4fcfd5a2ed8..3200396baa5 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
@@ -14,10 +14,13 @@ import org.oppia.android.domain.translation.TranslationController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import javax.inject.Inject
+import org.oppia.android.app.model.PromotedActivityList
+import org.oppia.android.domain.topic.TopicListController
/** The ObservableViewModel for [TopicFragment]. */
@FragmentScope
class TopicViewModel @Inject constructor(
+ private val topicListController: TopicListController,
private val topicController: TopicController,
private val oppiaLogger: OppiaLogger,
private val resourceHandler: AppLanguageResourceHandler,
@@ -33,6 +36,38 @@ class TopicViewModel @Inject constructor(
).toLiveData()
}
+ private val topicListResultLiveData: LiveData> by lazy {
+ topicListController.getPromotedActivityList(
+ ProfileId.newBuilder().setInternalId(internalProfileId).build()
+ ).toLiveData()
+ }
+
+ val numberOfChaptersCompletedLiveData: LiveData by lazy {
+ Transformations.map(topicListResultLiveData, ::computeNumberOfChaptersCompleted)
+ }
+
+ private fun computeNumberOfChaptersCompleted(
+ topicListResult: AsyncResult
+ ): Int {
+ return when (topicListResult) {
+ is AsyncResult.Failure -> -1
+ is AsyncResult.Pending -> -1
+ is AsyncResult.Success -> {
+ var numberOfChaptersCompleted = 0
+ topicListResult.value.promotedStoryList.recentlyPlayedStoryList.forEach {
+ numberOfChaptersCompleted += it.completedChapterCount
+ }
+ topicListResult.value.promotedStoryList.suggestedStoryList.forEach {
+ numberOfChaptersCompleted += it.completedChapterCount
+ }
+ topicListResult.value.promotedStoryList.olderPlayedStoryList.forEach {
+ numberOfChaptersCompleted += it.completedChapterCount
+ }
+ numberOfChaptersCompleted
+ }
+ }
+ }
+
private val topicLiveData: LiveData by lazy {
Transformations.map(topicResultLiveData, ::processTopicResult)
}
diff --git a/app/src/main/res/layout/overlay.xml b/app/src/main/res/layout/overlay.xml
index 7494af94aae..e9a7f6dd24f 100644
--- a/app/src/main/res/layout/overlay.xml
+++ b/app/src/main/res/layout/overlay.xml
@@ -17,55 +17,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/overlay_over_left.xml b/app/src/main/res/layout/overlay_over_left.xml
index 7a3a869e71b..d4aef7170aa 100644
--- a/app/src/main/res/layout/overlay_over_left.xml
+++ b/app/src/main/res/layout/overlay_over_left.xml
@@ -14,6 +14,7 @@
diff --git a/app/src/main/res/layout/overlay_over_right.xml b/app/src/main/res/layout/overlay_over_right.xml
index a8bd7b2aa6a..1c5b06928a6 100644
--- a/app/src/main/res/layout/overlay_over_right.xml
+++ b/app/src/main/res/layout/overlay_over_right.xml
@@ -14,6 +14,7 @@
diff --git a/app/src/main/res/layout/overlay_under_left.xml b/app/src/main/res/layout/overlay_under_left.xml
index 5153019d421..a09a30e07a2 100644
--- a/app/src/main/res/layout/overlay_under_left.xml
+++ b/app/src/main/res/layout/overlay_under_left.xml
@@ -14,6 +14,7 @@
Date: Sat, 5 Nov 2022 01:06:31 +0530
Subject: [PATCH 050/138] spotlights working. tests to be added.
---
.../player/audio/AudioFragmentPresenter.kt | 3 +-
.../player/exploration/ExplorationFragment.kt | 2 +-
.../ExplorationFragmentPresenter.kt | 115 ++++++++++++++----
.../main/res/layout/overlay_under_right.xml | 1 -
4 files changed, 91 insertions(+), 30 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index 1eae6405b29..0d24789514e 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -9,6 +9,7 @@ import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.SeekBar
import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.doOnPreDraw
import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
@@ -121,7 +122,7 @@ class AudioFragmentPresenter @Inject constructor(
private fun startSpotlights() {
val audioLanguageIconView = binding.audioLanguageIcon
- audioLanguageIconView.post {
+ audioLanguageIconView.doOnPreDraw {
val targetList = arrayListOf(
SpotlightTarget(
audioLanguageIconView,
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragment.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragment.kt
index 0ea284862d4..b72f2f0da61 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragment.kt
@@ -56,7 +56,7 @@ class ExplorationFragment : InjectableFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- explorationFragmentPresenter.handleViewCreated(view)
+ explorationFragmentPresenter.handleViewCreated()
}
fun handlePlayAudio() = explorationFragmentPresenter.handlePlayAudio()
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index 7013fc62333..fc2e4f6ec29 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -8,25 +8,31 @@ import android.widget.ImageButton
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.forEach
import androidx.fragment.app.Fragment
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.Transformations
+import javax.inject.Inject
+import kotlinx.android.synthetic.main.exploration_activity.*
+import kotlinx.android.synthetic.main.exploration_activity.view.*
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.ExplorationFragmentArguments
+import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.model.PromotedActivityList
import org.oppia.android.app.model.ReadingTextSize
+import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.player.state.StateFragment
+import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightShape
+import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.utility.FontScaleConfigurationUtil
import org.oppia.android.databinding.ExplorationFragmentBinding
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.profile.ProfileManagementController
+import org.oppia.android.domain.topic.TopicListController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.extensions.getProto
import org.oppia.android.util.extensions.putProto
-import javax.inject.Inject
-import kotlinx.android.synthetic.main.exploration_activity.*
-import org.oppia.android.app.model.Spotlight
-import org.oppia.android.app.spotlight.SpotlightFragment
-import org.oppia.android.app.spotlight.SpotlightShape
-import org.oppia.android.app.spotlight.SpotlightTarget
/** The presenter for [ExplorationFragment]. */
@FragmentScope
@@ -35,8 +41,12 @@ class ExplorationFragmentPresenter @Inject constructor(
private val oppiaLogger: OppiaLogger,
private val fontScaleConfigurationUtil: FontScaleConfigurationUtil,
private val profileManagementController: ProfileManagementController,
- private val spotlightFragment: SpotlightFragment
+ private val spotlightFragment: SpotlightFragment,
+ private val topicListController: TopicListController
) {
+
+ private var internalProfileId: Int = -1
+
/** Handles the [Fragment.onAttach] portion of [ExplorationFragment]'s lifecycle. */
fun handleAttach(context: Context) {
fontScaleConfigurationUtil.adjustFontScale(context, retrieveArguments().readingTextSize)
@@ -47,6 +57,7 @@ class ExplorationFragmentPresenter @Inject constructor(
val args = retrieveArguments()
val binding =
ExplorationFragmentBinding.inflate(inflater, container, /* attachToRoot= */ false).root
+ internalProfileId = args.profileId.internalId
val stateFragment =
StateFragment.newInstance(
args.profileId.internalId, args.topicId, args.storyId, args.explorationId
@@ -62,7 +73,7 @@ class ExplorationFragmentPresenter @Inject constructor(
}
/** Handles the [Fragment.onViewCreated] portion of [ExplorationFragment]'s lifecycle. */
- fun handleViewCreated(view: View) {
+ fun handleViewCreated() {
val profileDataProvider = profileManagementController.getProfile(retrieveArguments().profileId)
profileDataProvider.toLiveData().observe(
fragment
@@ -94,32 +105,82 @@ class ExplorationFragmentPresenter @Inject constructor(
// .commitNow()
// }
-
}
}
}
private fun showSpotlights() {
- val explorationToolbar = (fragment.requireActivity() as AppCompatActivity).exploration_toolbar
- explorationToolbar.post {
- explorationToolbar.forEach {
- if (it is ImageButton) {
- // this toolbar contains only one image button, which is the back navigation icon
- val targetList = arrayListOf(
- SpotlightTarget(
- it,
- "Exit anytime using this button. We will save your progress.",
- SpotlightShape.Circle,
- Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
- )
- )
-
- spotlightFragment.initialiseTargetList(targetList, 124)
- fragment.requireActivity().supportFragmentManager.beginTransaction()
- .add(spotlightFragment, "")
- .commitNow()
+ numberOfChaptersCompletedLiveData.observe(fragment) { numberOfChaptersCompleted ->
+ if (numberOfChaptersCompleted != -1) {
+ val explorationToolbar =
+ (fragment.requireActivity() as AppCompatActivity).exploration_toolbar
+ explorationToolbar.post {
+ explorationToolbar.forEach {
+ if (it is ImageButton) {
+ // this toolbar contains only one image button, which is the back navigation icon
+ val targetList = arrayListOf(
+ SpotlightTarget(
+ it,
+ "Exit anytime using this button. We will save your progress.",
+ SpotlightShape.Circle,
+ Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
+ )
+ )
+
+ if (
+ numberOfChaptersCompleted >= 1 &&
+ explorationToolbar.action_audio_player.visibility == View.VISIBLE
+ ) {
+ targetList.add(
+ SpotlightTarget(
+ explorationToolbar.action_audio_player,
+ "Would you like Oppia to read for you? Tap on this button to try!",
+ SpotlightShape.Circle,
+ Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
+ )
+ )
+ }
+
+ spotlightFragment.initialiseTargetList(targetList, internalProfileId)
+ fragment.requireActivity().supportFragmentManager.beginTransaction()
+ .add(spotlightFragment, "")
+ .commitNow()
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private val topicListResultLiveData: LiveData> by lazy {
+ topicListController.getPromotedActivityList(
+ ProfileId.newBuilder().setInternalId(internalProfileId).build()
+ ).toLiveData()
+ }
+
+ val numberOfChaptersCompletedLiveData: LiveData by lazy {
+ Transformations.map(topicListResultLiveData, ::computeNumberOfChaptersCompleted)
+ }
+
+ private fun computeNumberOfChaptersCompleted(
+ topicListResult: AsyncResult
+ ): Int {
+ return when (topicListResult) {
+ is AsyncResult.Failure -> -1
+ is AsyncResult.Pending -> -1
+ is AsyncResult.Success -> {
+ var numberOfChaptersCompleted = 0
+ topicListResult.value.promotedStoryList.recentlyPlayedStoryList.forEach {
+ numberOfChaptersCompleted += it.completedChapterCount
+ }
+ topicListResult.value.promotedStoryList.suggestedStoryList.forEach {
+ numberOfChaptersCompleted += it.completedChapterCount
+ }
+ topicListResult.value.promotedStoryList.olderPlayedStoryList.forEach {
+ numberOfChaptersCompleted += it.completedChapterCount
}
+ numberOfChaptersCompleted
}
}
}
diff --git a/app/src/main/res/layout/overlay_under_right.xml b/app/src/main/res/layout/overlay_under_right.xml
index e84a5da6981..609b0ceae18 100644
--- a/app/src/main/res/layout/overlay_under_right.xml
+++ b/app/src/main/res/layout/overlay_under_right.xml
@@ -17,7 +17,6 @@
android:layout_width="match_parent"
android:focusable="true"
android:clickable="true"
- android:background="@color/spotlightBackground"
android:layout_height="match_parent">
Date: Sat, 5 Nov 2022 22:41:37 +0530
Subject: [PATCH 051/138] no changes added
---
app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
index c8a7b4e64c2..f0ced1dd415 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
@@ -39,7 +39,6 @@ class TopicFragment : InjectableFragment() {
isConfigChanged = savedInstanceState != null
)
}
+}
- }
-}
From de30dd49fc216e9a082728258a7e94f6d6506336 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sat, 5 Nov 2022 23:12:50 +0530
Subject: [PATCH 052/138] all spotlights work.
---
.../main/java/org/oppia/android/app/topic/TopicFragment.kt | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
index f0ced1dd415..9f435a740db 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
@@ -39,6 +39,11 @@ class TopicFragment : InjectableFragment() {
isConfigChanged = savedInstanceState != null
)
}
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ topicFragmentPresenter.startSpotlight()
+ }
}
From cf83479f242badafad5e9d4840d5d7eab07195e5 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 7 Nov 2022 01:09:05 +0530
Subject: [PATCH 053/138] add target store impl
---
app/build.gradle | 2 +-
...pterNotStartedContainerConstraintLayout.kt | 20 ++++++++++---
.../app/spotlight/SpotlightFragment.kt | 20 ++++++++++---
.../app/spotlight/SpotlightTargetStore.kt | 20 +++++++++++++
.../app/topic/TopicFragmentPresenter.kt | 30 ++++++++++---------
5 files changed, 69 insertions(+), 23 deletions(-)
create mode 100644 app/src/main/java/org/oppia/android/app/spotlight/SpotlightTargetStore.kt
diff --git a/app/build.gradle b/app/build.gradle
index 989b435a753..3b5cbaae106 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -179,7 +179,7 @@ dependencies {
'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1',
'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1',
'org.mockito:mockito-core:2.7.22',
- 'com.github.takusemba:spotlight:2.0.5'
+ 'com.github.oppia:android-spotlight:1ba764bb9e'
)
compileOnly(
'jakarta.xml.bind:jakarta.xml.bind-api:2.3.2',
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index df3183f59ae..62f300b247c 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -10,6 +10,7 @@ import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
+import org.oppia.android.app.spotlight.SpotlightTargetStore
import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
@@ -28,6 +29,9 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
@Inject
lateinit var fragment: Fragment
+ @Inject
+ lateinit var spotlightTargetStore: SpotlightTargetStore
+
fun setStoryIndex(index: Int) {
// Only spotlight the first chapter of the "first" story. We know for sure that for a new user,
// the first chapter shall be a type of not started chapter view. The index tells which story
@@ -46,15 +50,23 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
this.post {
if (!isSpotlit) {
if (index == 0) {
- val targetList = arrayListOf(
- SpotlightTarget(
+// val targetList = arrayListOf(
+// SpotlightTarget(
+// this,
+// "Tap to start a chapter",
+// SpotlightShape.RoundedRectangle,
+// Spotlight.FeatureCase.FIRST_CHAPTER
+// )
+// )
+
+ val target = SpotlightTarget(
this,
"Tap to start a chapter",
SpotlightShape.RoundedRectangle,
Spotlight.FeatureCase.FIRST_CHAPTER
)
- )
- spotlightFragment.initialiseTargetList(targetList, 123)
+ spotlightTargetStore.addSpotlightTarget(target)
+ spotlightFragment.initialiseTargetList(123)
// this view is attached multiple times which can lead to crashes due [SpotlightFragment]
// being added multiple times. [isSpotlit] is a flag to prevent the same.
isSpotlit = true
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 087b0da02d4..5d345321e86 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -19,6 +19,7 @@ import com.takusemba.spotlight.shape.RoundedRectangle
import com.takusemba.spotlight.shape.Shape
import java.util.*
import javax.inject.Inject
+import javax.inject.Singleton
import org.oppia.android.R
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.SpotlightViewState
@@ -36,7 +37,8 @@ import org.oppia.android.util.data.DataProviders.Companion.toLiveData
class SpotlightFragment @Inject constructor(
private val activity: AppCompatActivity,
private val spotlightStateController: SpotlightStateController,
- private val accessibilityServiceImpl: AccessibilityServiceImpl
+ private val accessibilityServiceImpl: AccessibilityServiceImpl,
+ private val spotlightTargetStore: SpotlightTargetStore
) : Fragment(), SpotlightNavigationListener {
private var targetList = ArrayList()
private var spotlightTargetList = ArrayList()
@@ -66,6 +68,15 @@ class SpotlightFragment @Inject constructor(
internalProfileId = profileId
}
+ fun setInternalId(profileId: Int) {
+ internalProfileId = profileId
+ }
+
+ fun initialiseTargetList(profileId: Int) {
+ spotlightTargetList = spotlightTargetStore.getSpotlightTargetList()
+ internalProfileId = profileId
+ }
+
// since this fragment does not have any view to inflate yet, all the tasks should be done here.
override fun onAttach(context: Context) {
super.onAttach(context)
@@ -73,7 +84,8 @@ class SpotlightFragment @Inject constructor(
if (accessibilityServiceImpl.isScreenReaderEnabled()) {
activity.supportFragmentManager.beginTransaction().remove(this)
}else {
- spotlightTargetList.forEachIndexed { _, spotlightTarget ->
+ spotlightTargetList.forEachIndexed { index, spotlightTarget ->
+ Log.d("overlay", "spotlight fragment target $index: $spotlightTarget ")
checkSpotlightViewState(spotlightTarget)
}
}
@@ -125,7 +137,7 @@ class SpotlightFragment @Inject constructor(
spotlightTarget.logParams()
val target = Target.Builder()
- .setAnchor(spotlightTarget.anchor)
+// .setAnchor(spotlightTarget.anchor)
.setShape(getShape(spotlightTarget))
.setOverlay(requestOverlayResource(spotlightTarget))
.setOnTargetListener(object : OnTargetListener {
@@ -143,7 +155,7 @@ class SpotlightFragment @Inject constructor(
// )
}
})
- .build()
+ .build(spotlightTarget.anchor)
targetList.add(target)
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTargetStore.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTargetStore.kt
new file mode 100644
index 00000000000..9b05091c493
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTargetStore.kt
@@ -0,0 +1,20 @@
+package org.oppia.android.app.spotlight
+
+import android.util.Log
+import java.util.ArrayList
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class SpotlightTargetStore @Inject constructor() {
+
+ private val spotlightTargetList = ArrayList()
+
+ fun addSpotlightTarget(spotlightTarget: SpotlightTarget) {
+ spotlightTargetList.add(spotlightTarget)
+ Log.d("overlay", "current target list: $spotlightTargetList")
+ }
+
+ fun getSpotlightTargetList() = spotlightTargetList
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 588186b65b1..bb09ef36e5e 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -1,12 +1,10 @@
package org.oppia.android.app.topic
-import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
-import androidx.core.view.doOnPreDraw
import androidx.fragment.app.Fragment
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayout
@@ -18,6 +16,7 @@ import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
+import org.oppia.android.app.spotlight.SpotlightTargetStore
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.databinding.TopicFragmentBinding
import org.oppia.android.domain.oppialogger.OppiaLogger
@@ -33,7 +32,8 @@ class TopicFragmentPresenter @Inject constructor(
private val oppiaLogger: OppiaLogger,
@EnableExtraTopicTabsUi private val enableExtraTopicTabsUi: PlatformParameterValue,
private val resourceHandler: AppLanguageResourceHandler,
- private val spotlightFragment: SpotlightFragment
+ private val spotlightFragment: SpotlightFragment,
+ private val spotlightTargetStore: SpotlightTargetStore
) {
private lateinit var tabLayout: TabLayout
private var internalProfileId: Int = -1
@@ -82,7 +82,7 @@ class TopicFragmentPresenter @Inject constructor(
if (numberOfChaptersCompleted != -1) {
val lessonsTabView = tabLayout.getTabAt(computeTabPosition(TopicTab.LESSONS))?.view
lessonsTabView?.let { lessonsTabView ->
- lessonsTabView.doOnPreDraw {
+// lessonsTabView.doOnPreDraw {
val lessonsTabSpotlightTarget = SpotlightTarget(
lessonsTabView,
"Find all your lessons here",
@@ -98,19 +98,21 @@ class TopicFragmentPresenter @Inject constructor(
SpotlightShape.RoundedRectangle,
Spotlight.FeatureCase.TOPIC_REVISION_TAB
)
- val targetList = arrayListOf(lessonsTabSpotlightTarget, revisionTabSpotlightTarget)
- spotlightFragment.initialiseTargetList(targetList, internalProfileId)
- activity.supportFragmentManager.beginTransaction()
- .add(spotlightFragment, "")
- .commitNow()
+// val targetList = arrayListOf(lessonsTabSpotlightTarget, revisionTabSpotlightTarget)
+ spotlightFragment.setInternalId(internalProfileId)
+ spotlightTargetStore.addSpotlightTarget(lessonsTabSpotlightTarget)
+ spotlightTargetStore.addSpotlightTarget(revisionTabSpotlightTarget)
+// activity.supportFragmentManager.beginTransaction()
+// .add(spotlightFragment, "")
+// .commitNow()
} else {
val targetList = arrayListOf(lessonsTabSpotlightTarget)
- spotlightFragment.initialiseTargetList(targetList, internalProfileId)
- activity.supportFragmentManager.beginTransaction()
- .add(spotlightFragment, "")
- .commitNow()
+ spotlightTargetStore.addSpotlightTarget(lessonsTabSpotlightTarget)
+// activity.supportFragmentManager.beginTransaction()
+// .add(spotlightFragment, "")
+// .commitNow()
}
- }
+// }
}
}
}
From 427da12fc688d7baf5f1348de669cc10e9064622 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 7 Nov 2022 05:29:43 +0530
Subject: [PATCH 054/138] custom queue implementation done
---
...pterNotStartedContainerConstraintLayout.kt | 15 ++++----
.../app/spotlight/SpotlightFragment.kt | 34 +++++++++++++------
.../oppia/android/app/topic/TopicActivity.kt | 10 ++++++
.../app/topic/TopicActivityPresenter.kt | 11 +++++-
.../app/topic/TopicFragmentPresenter.kt | 30 ++++++++--------
app/src/main/res/layout/topic_activity.xml | 16 +++++++--
6 files changed, 77 insertions(+), 39 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index 62f300b247c..46219f38c4f 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -11,6 +11,7 @@ import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.spotlight.SpotlightTargetStore
+import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
@@ -23,9 +24,6 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
private var index: Int = -1
private var isSpotlit = false
- @Inject
- lateinit var spotlightFragment: SpotlightFragment
-
@Inject
lateinit var fragment: Fragment
@@ -39,6 +37,10 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
this.index = index
}
+ private fun getSpotlightFragment(): SpotlightFragment {
+ return fragment.requireActivity().supportFragmentManager.findFragmentByTag(SPOTLIGHT_FRAGMENT_TAG) as SpotlightFragment
+ }
+
override fun onAttachedToWindow() {
super.onAttachedToWindow()
@@ -65,14 +67,11 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
SpotlightShape.RoundedRectangle,
Spotlight.FeatureCase.FIRST_CHAPTER
)
- spotlightTargetStore.addSpotlightTarget(target)
- spotlightFragment.initialiseTargetList(123)
+// spotlightTargetStore.addSpotlightTarget(target)
+ getSpotlightFragment().checkSpotlightViewState(target)
// this view is attached multiple times which can lead to crashes due [SpotlightFragment]
// being added multiple times. [isSpotlit] is a flag to prevent the same.
isSpotlit = true
- fragment.childFragmentManager.beginTransaction()
- .add(spotlightFragment, "")
- .commitNow()
}
}
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 5d345321e86..797f8dd45c6 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -19,12 +19,10 @@ import com.takusemba.spotlight.shape.RoundedRectangle
import com.takusemba.spotlight.shape.Shape
import java.util.*
import javax.inject.Inject
-import javax.inject.Singleton
import org.oppia.android.R
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.SpotlightViewState
import org.oppia.android.app.onboarding.SpotlightNavigationListener
-import org.oppia.android.databinding.OverlayBinding
import org.oppia.android.databinding.OverlayOverLeftBinding
import org.oppia.android.databinding.OverlayOverRightBinding
import org.oppia.android.databinding.OverlayUnderLeftBinding
@@ -40,18 +38,18 @@ class SpotlightFragment @Inject constructor(
private val accessibilityServiceImpl: AccessibilityServiceImpl,
private val spotlightTargetStore: SpotlightTargetStore
) : Fragment(), SpotlightNavigationListener {
- private var targetList = ArrayList()
+ private var targetList = LinkedList()
private var spotlightTargetList = ArrayList()
private lateinit var spotlight: Spotlight
private val overlay = "overlay"
- private var counter = 0
private var screenHeight: Int = 0
private var screenWidth: Int = 0
private lateinit var anchorPosition: AnchorPosition
private lateinit var overlayBinding: Any
private var internalProfileId: Int = -1
-
+ private var isSpotlightActive = false
private var isRTL = false
+ private var indexToRemove = -1
init {
val displayMetrics = DisplayMetrics()
@@ -91,7 +89,7 @@ class SpotlightFragment @Inject constructor(
}
}
- private fun checkSpotlightViewState(spotlightTarget: SpotlightTarget) {
+ fun checkSpotlightViewState(spotlightTarget: SpotlightTarget) {
val profileId = ProfileId.newBuilder()
.setInternalId(internalProfileId)
@@ -118,10 +116,7 @@ class SpotlightFragment @Inject constructor(
Log.d("overlay", viewState.toString())
Log.d("overlay", "adding target ")
createTarget(spotlightTarget)
- counter++
- if (counter == spotlightTargetList.size) {
- startSpotlight()
- }
+
featureViewStateLiveData.removeObserver(this)
}
}
@@ -143,9 +138,15 @@ class SpotlightFragment @Inject constructor(
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
+ Log.d("overlay", "target start")
}
override fun onEnded() {
+ Log.d("overlay", "target end")
+
+ targetList.pop()
+
+// targetList.remove(currentTarget)
// val profileId = ProfileId.newBuilder()
// .setInternalId(internalProfileId)
// .build()
@@ -157,10 +158,15 @@ class SpotlightFragment @Inject constructor(
})
.build(spotlightTarget.anchor)
+
targetList.add(target)
+ if (!isSpotlightActive) {
+ startSpotlight()
+ }
}
private fun startSpotlight() {
+ if (targetList.isNullOrEmpty()) return
spotlight = Spotlight.Builder(activity)
.setTargets(targetList)
.setBackgroundColorRes(R.color.spotlightBackground)
@@ -168,10 +174,16 @@ class SpotlightFragment @Inject constructor(
.setAnimation(DecelerateInterpolator(2f))
.setOnSpotlightListener(object : OnSpotlightListener {
override fun onStarted() {
+ Log.d("overlay", "spotlight start")
+
+ isSpotlightActive = true
}
override fun onEnded() {
- this@SpotlightFragment.childFragmentManager.popBackStack()
+ Log.d("overlay", "spotlight end")
+
+ isSpotlightActive = false
+ startSpotlight()
}
})
.build()
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicActivity.kt b/app/src/main/java/org/oppia/android/app/topic/TopicActivity.kt
index a65e6668e4a..3c8ce5b0c31 100755
--- a/app/src/main/java/org/oppia/android/app/topic/TopicActivity.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicActivity.kt
@@ -3,6 +3,8 @@ package org.oppia.android.app.topic
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.util.AttributeSet
+import android.view.View
import androidx.appcompat.app.AppCompatActivity
import org.oppia.android.app.activity.ActivityComponentImpl
import org.oppia.android.app.activity.ActivityIntentFactories
@@ -20,6 +22,7 @@ import org.oppia.android.app.topic.questionplayer.QuestionPlayerActivity
import org.oppia.android.app.topic.revisioncard.RevisionCardActivity
import org.oppia.android.util.logging.CurrentAppScreenNameIntentDecorator.decorateWithScreenName
import javax.inject.Inject
+import org.oppia.android.app.spotlight.SpotlightFragment
private const val TOPIC_ACTIVITY_TOPIC_ID_ARGUMENT_KEY = "TopicActivity.topic_id"
private const val TOPIC_ACTIVITY_STORY_ID_ARGUMENT_KEY = "TopicActivity.story_id"
@@ -40,6 +43,9 @@ class TopicActivity :
@Inject
lateinit var topicActivityPresenter: TopicActivityPresenter
+ @Inject
+ lateinit var spotlightFragment: SpotlightFragment
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
(activityComponent as ActivityComponentImpl).inject(this)
@@ -72,6 +78,10 @@ class TopicActivity :
)
}
+ fun getSpotlightFragment() {
+
+ }
+
override fun routeToRevisionCard(
internalProfileId: Int,
topicId: String,
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
index ea4a760a690..2079cfe73ad 100755
--- a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
@@ -6,8 +6,10 @@ import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.model.ProfileId
import javax.inject.Inject
+import org.oppia.android.app.spotlight.SpotlightFragment
const val TOPIC_FRAGMENT_TAG = "TopicFragment"
+const val SPOTLIGHT_FRAGMENT_TAG = "SpotlightFragment"
const val PROFILE_ID_ARGUMENT_KEY = "profile_id"
const val TOPIC_ID_ARGUMENT_KEY = "topic_id"
const val STORY_ID_ARGUMENT_KEY = "story_id"
@@ -15,7 +17,8 @@ const val STORY_ID_ARGUMENT_KEY = "story_id"
/** The presenter for [TopicActivity]. */
@ActivityScope
class TopicActivityPresenter @Inject constructor(
- private val activity: AppCompatActivity
+ private val activity: AppCompatActivity,
+ private val spotlightFragment: SpotlightFragment
) {
private lateinit var topicId: String
@@ -39,6 +42,12 @@ class TopicActivityPresenter @Inject constructor(
topicFragment, TOPIC_FRAGMENT_TAG
).commitNow()
}
+
+ activity.supportFragmentManager.beginTransaction().add(
+ R.id.topic_fragment_placeholder,
+ spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
+ ).commitNow()
+
}
private fun getTopicFragment(): TopicFragment? {
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index bb09ef36e5e..b4c59268b26 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -32,7 +32,6 @@ class TopicFragmentPresenter @Inject constructor(
private val oppiaLogger: OppiaLogger,
@EnableExtraTopicTabsUi private val enableExtraTopicTabsUi: PlatformParameterValue,
private val resourceHandler: AppLanguageResourceHandler,
- private val spotlightFragment: SpotlightFragment,
private val spotlightTargetStore: SpotlightTargetStore
) {
private lateinit var tabLayout: TabLayout
@@ -90,7 +89,7 @@ class TopicFragmentPresenter @Inject constructor(
Spotlight.FeatureCase.TOPIC_LESSON_TAB
)
- if (numberOfChaptersCompleted > 2) {
+// if (numberOfChaptersCompleted > 2) {
val revisionTabView = tabLayout.getTabAt(computeTabPosition(TopicTab.REVISION))?.view
val revisionTabSpotlightTarget = SpotlightTarget(
revisionTabView!!,
@@ -98,26 +97,25 @@ class TopicFragmentPresenter @Inject constructor(
SpotlightShape.RoundedRectangle,
Spotlight.FeatureCase.TOPIC_REVISION_TAB
)
-// val targetList = arrayListOf(lessonsTabSpotlightTarget, revisionTabSpotlightTarget)
- spotlightFragment.setInternalId(internalProfileId)
- spotlightTargetStore.addSpotlightTarget(lessonsTabSpotlightTarget)
- spotlightTargetStore.addSpotlightTarget(revisionTabSpotlightTarget)
-// activity.supportFragmentManager.beginTransaction()
-// .add(spotlightFragment, "")
-// .commitNow()
- } else {
- val targetList = arrayListOf(lessonsTabSpotlightTarget)
- spotlightTargetStore.addSpotlightTarget(lessonsTabSpotlightTarget)
-// activity.supportFragmentManager.beginTransaction()
-// .add(spotlightFragment, "")
-// .commitNow()
+ getSpotlightFragment().setInternalId(internalProfileId)
+ getSpotlightFragment().checkSpotlightViewState(lessonsTabSpotlightTarget)
+ getSpotlightFragment().checkSpotlightViewState(revisionTabSpotlightTarget)
+
+// } else {
+
+// getSpotlightFragment().checkSpotlightViewState(lessonsTabSpotlightTarget)
+
}
// }
- }
+// }
}
}
}
+ private fun getSpotlightFragment(): SpotlightFragment {
+ return activity.supportFragmentManager.findFragmentByTag(SPOTLIGHT_FRAGMENT_TAG) as SpotlightFragment
+ }
+
private fun setCurrentTab(tab: TopicTab) {
viewPager.setCurrentItem(computeTabPosition(tab), true)
logTopicEvents(tab)
diff --git a/app/src/main/res/layout/topic_activity.xml b/app/src/main/res/layout/topic_activity.xml
index 6924dfafa7a..1a1475ad4ff 100644
--- a/app/src/main/res/layout/topic_activity.xml
+++ b/app/src/main/res/layout/topic_activity.xml
@@ -1,6 +1,16 @@
-
+ tools:context=".app.topic.TopicActivity" >
+
+
+
+
+
From 23b2efb65e37e1bd4b5b3f898b3d83209cbc2e13 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 7 Nov 2022 18:24:23 +0530
Subject: [PATCH 055/138] small fixes
---
.../customview/ChapterNotStartedContainerConstraintLayout.kt | 5 +++--
.../org/oppia/android/app/spotlight/SpotlightFragment.kt | 1 -
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index 46219f38c4f..df86afb5375 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -3,6 +3,7 @@ package org.oppia.android.app.customview
import android.content.Context
import android.util.AttributeSet
import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.view.doOnPreDraw
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import javax.inject.Inject
@@ -49,7 +50,7 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
val viewComponent = viewComponentFactory.createViewComponent(this) as ViewComponentImpl
viewComponent.inject(this)
- this.post {
+ this.doOnPreDraw {
if (!isSpotlit) {
if (index == 0) {
// val targetList = arrayListOf(
@@ -62,7 +63,7 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
// )
val target = SpotlightTarget(
- this,
+ it,
"Tap to start a chapter",
SpotlightShape.RoundedRectangle,
Spotlight.FeatureCase.FIRST_CHAPTER
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 797f8dd45c6..6a8af6361a1 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -49,7 +49,6 @@ class SpotlightFragment @Inject constructor(
private var internalProfileId: Int = -1
private var isSpotlightActive = false
private var isRTL = false
- private var indexToRemove = -1
init {
val displayMetrics = DisplayMetrics()
From a63e55253e4aaf7ae56092845fd4f47d706c076e Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Tue, 8 Nov 2022 03:47:04 +0530
Subject: [PATCH 056/138] add all spotlights, properly initialize profileid in
spotlight fragment, inject fields into spotlights fragment
---
...pterNotStartedContainerConstraintLayout.kt | 20 +--
.../app/customview/PromotedStoryCardView.kt | 46 +++---
.../app/fragment/FragmentComponentImpl.kt | 2 +
.../oppia/android/app/home/HomeActivity.kt | 2 +-
.../android/app/home/HomeActivityPresenter.kt | 15 +-
.../player/audio/AudioFragmentPresenter.kt | 19 +--
.../ExplorationActivityPresenter.kt | 18 ++-
.../ExplorationFragmentPresenter.kt | 80 ++++-------
.../app/spotlight/SpotlightFragment.kt | 90 +++++++-----
.../app/spotlight/SpotlightTargetStore.kt | 20 ---
.../testing/NavigationDrawerTestActivity.kt | 2 +-
.../oppia/android/app/topic/TopicActivity.kt | 7 -
.../app/topic/TopicActivityPresenter.kt | 20 +--
.../app/topic/TopicFragmentPresenter.kt | 50 +++----
.../main/res/layout/exploration_activity.xml | 135 ++++++++++--------
app/src/main/res/layout/home_activity.xml | 5 +
16 files changed, 263 insertions(+), 268 deletions(-)
delete mode 100644 app/src/main/java/org/oppia/android/app/spotlight/SpotlightTargetStore.kt
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index df86afb5375..2f2a99b0580 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -11,7 +11,6 @@ import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
-import org.oppia.android.app.spotlight.SpotlightTargetStore
import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
@@ -28,9 +27,6 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
@Inject
lateinit var fragment: Fragment
- @Inject
- lateinit var spotlightTargetStore: SpotlightTargetStore
-
fun setStoryIndex(index: Int) {
// Only spotlight the first chapter of the "first" story. We know for sure that for a new user,
// the first chapter shall be a type of not started chapter view. The index tells which story
@@ -39,7 +35,9 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
}
private fun getSpotlightFragment(): SpotlightFragment {
- return fragment.requireActivity().supportFragmentManager.findFragmentByTag(SPOTLIGHT_FRAGMENT_TAG) as SpotlightFragment
+ return fragment.requireActivity().supportFragmentManager.findFragmentByTag(
+ SPOTLIGHT_FRAGMENT_TAG
+ ) as SpotlightFragment
}
override fun onAttachedToWindow() {
@@ -53,24 +51,14 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
this.doOnPreDraw {
if (!isSpotlit) {
if (index == 0) {
-// val targetList = arrayListOf(
-// SpotlightTarget(
-// this,
-// "Tap to start a chapter",
-// SpotlightShape.RoundedRectangle,
-// Spotlight.FeatureCase.FIRST_CHAPTER
-// )
-// )
-
val target = SpotlightTarget(
it,
"Tap to start a chapter",
SpotlightShape.RoundedRectangle,
Spotlight.FeatureCase.FIRST_CHAPTER
)
-// spotlightTargetStore.addSpotlightTarget(target)
getSpotlightFragment().checkSpotlightViewState(target)
- // this view is attached multiple times which can lead to crashes due [SpotlightFragment]
+ // this view is attached multiple times which can lead to crashes due spotlight request
// being added multiple times. [isSpotlit] is a flag to prevent the same.
isSpotlit = true
}
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
index 27899c727e2..74ddb1da1fb 100644
--- a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -2,6 +2,8 @@ package org.oppia.android.app.customview
import android.content.Context
import android.util.AttributeSet
+import androidx.core.view.doOnLayout
+import androidx.core.view.doOnPreDraw
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import com.google.android.material.card.MaterialCardView
@@ -10,6 +12,7 @@ import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
+import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
@@ -20,9 +23,7 @@ class PromotedStoryCardView @JvmOverloads constructor(
): MaterialCardView(context, attrs, defStyleAttr) {
private var promotedStoryIndex = -1
-
- @Inject
- lateinit var spotlightFragment: SpotlightFragment
+ private var isSpotlit = false
@Inject
lateinit var fragment: Fragment
@@ -31,29 +32,32 @@ class PromotedStoryCardView @JvmOverloads constructor(
this.promotedStoryIndex = index
}
+ private fun getSpotlightFragment(): SpotlightFragment {
+ return fragment.requireActivity().supportFragmentManager.findFragmentByTag(
+ SPOTLIGHT_FRAGMENT_TAG
+ ) as SpotlightFragment
+ }
+
override fun onAttachedToWindow() {
- super.onAttachedToWindow()
+ super.onAttachedToWindow()
- val viewComponentFactory =
- FragmentManager.findFragment(this) as ViewComponentFactory
- val viewComponent = viewComponentFactory.createViewComponent(this) as ViewComponentImpl
- viewComponent.inject(this)
+ val viewComponentFactory =
+ FragmentManager.findFragment(this) as ViewComponentFactory
+ val viewComponent = viewComponentFactory.createViewComponent(this) as ViewComponentImpl
+ viewComponent.inject(this)
this.post {
- if (promotedStoryIndex == 0) {
- val targetList = arrayListOf(
- SpotlightTarget(
- this,
- "From now, here you can view stories you might be interested in",
- SpotlightShape.RoundedRectangle,
- Spotlight.FeatureCase.PROMOTED_STORIES
- )
+ if (!isSpotlit) {
+ if (promotedStoryIndex == 0) {
+ val promotesStorySpotlightTarget = SpotlightTarget(
+ this,
+ "From now, here you can view stories you might be interested in",
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.PROMOTED_STORIES
)
-
- spotlightFragment.initialiseTargetList(targetList, 123)
- fragment.childFragmentManager.beginTransaction()
- .add(spotlightFragment, "")
- .commitNow()
+ isSpotlit = true
+ getSpotlightFragment().checkSpotlightViewState(promotesStorySpotlightTarget)
+ }
}
}
}
diff --git a/app/src/main/java/org/oppia/android/app/fragment/FragmentComponentImpl.kt b/app/src/main/java/org/oppia/android/app/fragment/FragmentComponentImpl.kt
index 5446a1d55ed..03178ae98e0 100644
--- a/app/src/main/java/org/oppia/android/app/fragment/FragmentComponentImpl.kt
+++ b/app/src/main/java/org/oppia/android/app/fragment/FragmentComponentImpl.kt
@@ -63,6 +63,7 @@ import org.oppia.android.app.settings.profile.ProfileRenameFragment
import org.oppia.android.app.settings.profile.ProfileResetPinFragment
import org.oppia.android.app.shim.IntentFactoryShimModule
import org.oppia.android.app.shim.ViewBindingShimModule
+import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.story.StoryFragment
import org.oppia.android.app.testing.DragDropTestFragment
import org.oppia.android.app.testing.ExplorationTestActivityPresenter
@@ -175,4 +176,5 @@ interface FragmentComponentImpl : FragmentComponent, ViewComponentBuilderInjecto
fun inject(walkthroughFinalFragment: WalkthroughFinalFragment)
fun inject(walkthroughTopicListFragment: WalkthroughTopicListFragment)
fun inject(walkthroughWelcomeFragment: WalkthroughWelcomeFragment)
+ fun inject(spotlightFragment: SpotlightFragment)
}
diff --git a/app/src/main/java/org/oppia/android/app/home/HomeActivity.kt b/app/src/main/java/org/oppia/android/app/home/HomeActivity.kt
index 2828d9408bb..16dc57cb5d0 100644
--- a/app/src/main/java/org/oppia/android/app/home/HomeActivity.kt
+++ b/app/src/main/java/org/oppia/android/app/home/HomeActivity.kt
@@ -52,7 +52,7 @@ class HomeActivity :
super.onCreate(savedInstanceState)
(activityComponent as ActivityComponentImpl).inject(this)
internalProfileId = intent?.getIntExtra(NAVIGATION_PROFILE_ID_ARGUMENT_KEY, -1)!!
- homeActivityPresenter.handleOnCreate()
+ homeActivityPresenter.handleOnCreate(internalProfileId)
title = resourceHandler.getStringInLocale(R.string.home_activity_title)
}
diff --git a/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
index 5f32ea6c547..3c5f855ac84 100644
--- a/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
@@ -1,5 +1,6 @@
package org.oppia.android.app.home
+import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
@@ -8,6 +9,9 @@ import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.drawer.NavigationDrawerFragment
import javax.inject.Inject
+import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
+import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
const val TAG_HOME_FRAGMENT = "HOME_FRAGMENT"
@@ -16,7 +20,7 @@ const val TAG_HOME_FRAGMENT = "HOME_FRAGMENT"
class HomeActivityPresenter @Inject constructor(private val activity: AppCompatActivity) {
private var navigationDrawerFragment: NavigationDrawerFragment? = null
- fun handleOnCreate() {
+ fun handleOnCreate(internalProfileId: Int) {
activity.setContentView(R.layout.home_activity)
setUpNavigationDrawer()
if (getHomeFragment() == null) {
@@ -26,6 +30,15 @@ class HomeActivityPresenter @Inject constructor(private val activity: AppCompatA
TAG_HOME_FRAGMENT
).commitNow()
}
+
+ val spotlightFragment = SpotlightFragment()
+ val args = Bundle()
+ args.putInt(PROFILE_ID_ARGUMENT_KEY, internalProfileId)
+ spotlightFragment.arguments = args
+ activity.supportFragmentManager.beginTransaction().add(
+ R.id.home_spotlight_fragment_placeholder,
+ spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
+ ).commitNow()
}
fun handleOnRestart() {
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index 0d24789514e..35c3819c9c2 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -27,6 +27,7 @@ import org.oppia.android.app.player.audio.AudioViewModel.UiAudioPlayStatus
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
+import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.AudioFragmentBinding
@@ -52,8 +53,7 @@ class AudioFragmentPresenter @Inject constructor(
private val networkConnectionUtil: NetworkConnectionUtil,
private val viewModelProvider: ViewModelProvider,
private val oppiaLogger: OppiaLogger,
- private val resourceHandler: AppLanguageResourceHandler,
- private val spotlightFragment: SpotlightFragment
+ private val resourceHandler: AppLanguageResourceHandler
) {
var userIsSeeking = false
var userProgress = 0
@@ -123,22 +123,23 @@ class AudioFragmentPresenter @Inject constructor(
private fun startSpotlights() {
val audioLanguageIconView = binding.audioLanguageIcon
audioLanguageIconView.doOnPreDraw {
- val targetList = arrayListOf(
+ getSpotlightFragment().checkSpotlightViewState(
SpotlightTarget(
- audioLanguageIconView,
+ it,
"Tap to change",
SpotlightShape.Circle,
Spotlight.FeatureCase.VOICEOVER_LANGUAGE_ICON
)
)
-
- spotlightFragment.initialiseTargetList(targetList, 1234)
- activity.supportFragmentManager.beginTransaction()
- .add(spotlightFragment, "")
- .commitNow()
}
}
+ private fun getSpotlightFragment(): SpotlightFragment {
+ return activity.supportFragmentManager.findFragmentByTag(
+ SPOTLIGHT_FRAGMENT_TAG
+ ) as SpotlightFragment
+ }
+
private fun getProfileData(): LiveData {
return Transformations.map(
profileManagementController.getProfile(profileId).toLiveData(),
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
index 15620778703..3e70783fbdb 100644
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
@@ -1,6 +1,7 @@
package org.oppia.android.app.player.exploration
import android.content.Context
+import android.os.Bundle
import android.view.inputmethod.EditorInfo
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
@@ -9,6 +10,7 @@ import androidx.databinding.DataBindingUtil
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.Transformations
+import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.help.HelpActivity
@@ -20,6 +22,9 @@ import org.oppia.android.app.model.ReadingTextSize
import org.oppia.android.app.options.OptionsActivity
import org.oppia.android.app.player.stopplaying.ProgressDatabaseFullDialogFragment
import org.oppia.android.app.player.stopplaying.UnsavedExplorationDialogFragment
+import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
+import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.app.topic.TopicActivity
import org.oppia.android.app.utility.FontScaleConfigurationUtil
import org.oppia.android.app.viewmodel.ViewModelProvider
@@ -29,7 +34,6 @@ import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.translation.TranslationController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
-import javax.inject.Inject
private const val TAG_UNSAVED_EXPLORATION_DIALOG = "UNSAVED_EXPLORATION_DIALOG"
private const val TAG_STOP_EXPLORATION_DIALOG = "STOP_EXPLORATION_DIALOG"
@@ -123,6 +127,15 @@ class ExplorationActivityPresenter @Inject constructor(
ExplorationManagerFragment.createNewInstance(profileId),
TAG_EXPLORATION_MANAGER_FRAGMENT
).commitNow()
+
+ val spotlightFragment = SpotlightFragment()
+ val args = Bundle()
+ args.putInt(PROFILE_ID_ARGUMENT_KEY, profileId.internalId)
+ spotlightFragment.arguments = args
+ activity.supportFragmentManager.beginTransaction().add(
+ R.id.exploration_spotlight_fragment_placeholder,
+ spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
+ ).commitNow()
}
}
@@ -419,7 +432,8 @@ class ExplorationActivityPresenter @Inject constructor(
"ExplorationActivity", "Failed to retrieve oldest saved checkpoint details.", it.error
)
}
- is AsyncResult.Pending -> {} // Wait for an actual result.
+ is AsyncResult.Pending -> {
+ } // Wait for an actual result.
}
}
)
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index fc2e4f6ec29..f6f126f1e2a 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -24,6 +24,7 @@ import org.oppia.android.app.player.state.StateFragment
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
+import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.app.utility.FontScaleConfigurationUtil
import org.oppia.android.databinding.ExplorationFragmentBinding
import org.oppia.android.domain.oppialogger.OppiaLogger
@@ -41,7 +42,6 @@ class ExplorationFragmentPresenter @Inject constructor(
private val oppiaLogger: OppiaLogger,
private val fontScaleConfigurationUtil: FontScaleConfigurationUtil,
private val profileManagementController: ProfileManagementController,
- private val spotlightFragment: SpotlightFragment,
private val topicListController: TopicListController
) {
@@ -87,24 +87,6 @@ class ExplorationFragmentPresenter @Inject constructor(
fragment.requireActivity().recreate()
} else {
showSpotlights()
-// val toolbar = (fragment.requireActivity() as AppCompatActivity).action_audio_player
-// toolbar.post {
-// if (toolbar.visibility == View.GONE) return@post
-// val targetList = arrayListOf(
-// SpotlightTarget(
-// toolbar,
-// "Would you like Oppia to read for you? Tap on this button to try!",
-// SpotlightShape.Circle,
-// Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
-// )
-// )
-//
-// spotlightFragment.initialiseTargetList(targetList, 124)
-// fragment.requireActivity().supportFragmentManager.beginTransaction()
-// .add(spotlightFragment, "")
-// .commitNow()
-// }
-
}
}
@@ -115,37 +97,29 @@ class ExplorationFragmentPresenter @Inject constructor(
if (numberOfChaptersCompleted != -1) {
val explorationToolbar =
(fragment.requireActivity() as AppCompatActivity).exploration_toolbar
- explorationToolbar.post {
- explorationToolbar.forEach {
- if (it is ImageButton) {
- // this toolbar contains only one image button, which is the back navigation icon
- val targetList = arrayListOf(
- SpotlightTarget(
- it,
- "Exit anytime using this button. We will save your progress.",
- SpotlightShape.Circle,
- Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
- )
+ explorationToolbar.forEach {
+ if (it is ImageButton) {
+ // this toolbar contains only one image button, which is the back navigation icon
+
+ val backButtonSpotlightTarget = SpotlightTarget(
+ it,
+ "Exit anytime using this button. We will save your progress.",
+ SpotlightShape.Circle,
+ Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
+ )
+ getSpotlightFragment().checkSpotlightViewState(backButtonSpotlightTarget)
+
+ if (
+ numberOfChaptersCompleted >= 1 &&
+ explorationToolbar.action_audio_player.visibility == View.VISIBLE
+ ) {
+ val audioPlayerSpotlightTarget = SpotlightTarget(
+ explorationToolbar.action_audio_player,
+ "Would you like Oppia to read for you? Tap on this button to try!",
+ SpotlightShape.Circle,
+ Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
)
-
- if (
- numberOfChaptersCompleted >= 1 &&
- explorationToolbar.action_audio_player.visibility == View.VISIBLE
- ) {
- targetList.add(
- SpotlightTarget(
- explorationToolbar.action_audio_player,
- "Would you like Oppia to read for you? Tap on this button to try!",
- SpotlightShape.Circle,
- Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
- )
- )
- }
-
- spotlightFragment.initialiseTargetList(targetList, internalProfileId)
- fragment.requireActivity().supportFragmentManager.beginTransaction()
- .add(spotlightFragment, "")
- .commitNow()
+ getSpotlightFragment().checkSpotlightViewState(audioPlayerSpotlightTarget)
}
}
}
@@ -153,13 +127,19 @@ class ExplorationFragmentPresenter @Inject constructor(
}
}
+ private fun getSpotlightFragment(): SpotlightFragment {
+ return fragment.requireActivity().supportFragmentManager.findFragmentByTag(
+ SPOTLIGHT_FRAGMENT_TAG
+ ) as SpotlightFragment
+ }
+
private val topicListResultLiveData: LiveData> by lazy {
topicListController.getPromotedActivityList(
ProfileId.newBuilder().setInternalId(internalProfileId).build()
).toLiveData()
}
- val numberOfChaptersCompletedLiveData: LiveData by lazy {
+ private val numberOfChaptersCompletedLiveData: LiveData by lazy {
Transformations.map(topicListResultLiveData, ::computeNumberOfChaptersCompleted)
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 839e02e1415..377293b3f5e 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -3,11 +3,11 @@ package org.oppia.android.app.spotlight
import android.content.Context
import android.content.res.Resources
import android.util.DisplayMetrics
+import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.view.animation.DecelerateInterpolator
import androidx.appcompat.app.AppCompatActivity
-import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import com.takusemba.spotlight.OnSpotlightListener
import com.takusemba.spotlight.OnTargetListener
@@ -16,10 +16,15 @@ import com.takusemba.spotlight.Target
import com.takusemba.spotlight.shape.Circle
import com.takusemba.spotlight.shape.RoundedRectangle
import com.takusemba.spotlight.shape.Shape
+import java.util.*
+import javax.inject.Inject
import org.oppia.android.R
+import org.oppia.android.app.fragment.FragmentComponentImpl
+import org.oppia.android.app.fragment.InjectableFragment
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.SpotlightViewState
import org.oppia.android.app.onboarding.SpotlightNavigationListener
+import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
import org.oppia.android.databinding.BottomLeftOverlayBinding
import org.oppia.android.databinding.BottomRightOverlayBinding
import org.oppia.android.databinding.TopLeftOverlayBinding
@@ -28,22 +33,25 @@ import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.util.accessibility.AccessibilityServiceImpl
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
-import java.util.Locale
-import javax.inject.Inject
-class SpotlightFragment @Inject constructor(
- private val activity: AppCompatActivity,
- private val spotlightStateController: SpotlightStateController,
- private val accessibilityServiceImpl: AccessibilityServiceImpl
-) : Fragment(), SpotlightNavigationListener {
- private var targetList = ArrayList()
- private var spotlightTargetList = ArrayList()
+class SpotlightFragment: InjectableFragment(), SpotlightNavigationListener {
+ @Inject
+ lateinit var activity: AppCompatActivity
+
+ @Inject
+ lateinit var spotlightStateController: SpotlightStateController
+
+ @Inject
+ lateinit var accessibilityServiceImpl: AccessibilityServiceImpl
+
+ private var targetList = LinkedList()
private lateinit var spotlight: Spotlight
private var screenHeight: Int = 0
private var screenWidth: Int = 0
private lateinit var anchorPosition: AnchorPosition
private lateinit var overlayBinding: Any
private var internalProfileId: Int = -1
+ private var isSpotlightActive = false
private var isRTL = false
private fun calculateScreenSize() {
@@ -54,28 +62,18 @@ class SpotlightFragment @Inject constructor(
screenWidth = displayMetrics.widthPixels
}
- fun initialiseTargetList(spotlightTargets: ArrayList, profileId: Int) {
- spotlightTargetList = spotlightTargets
- internalProfileId = profileId
- }
-
// since this fragment does not have any view to inflate yet, all the tasks should be done here.
override fun onAttach(context: Context) {
super.onAttach(context)
+ (fragmentComponent as FragmentComponentImpl).inject(this)
- if (accessibilityServiceImpl.isScreenReaderEnabled()) {
- activity.supportFragmentManager.beginTransaction().remove(this)
- } else {
- calculateScreenSize()
- checkIsRTL()
- spotlightTargetList.forEachIndexed { _, spotlightTarget ->
- checkSpotlightViewState(spotlightTarget)
- }
- }
+ internalProfileId = arguments?.getInt(PROFILE_ID_ARGUMENT_KEY) ?: -1
+ calculateScreenSize()
+ checkIsRTL()
}
- private fun checkSpotlightViewState(spotlightTarget: SpotlightTarget) {
- var counter = 0
+ fun checkSpotlightViewState(spotlightTarget: SpotlightTarget) {
+
val profileId = ProfileId.newBuilder()
.setInternalId(internalProfileId)
.build()
@@ -97,10 +95,6 @@ class SpotlightFragment @Inject constructor(
return
} else if (viewState == SpotlightViewState.SPOTLIGHT_NOT_SEEN) {
createTarget(spotlightTarget)
- counter++
- if (counter == spotlightTargetList.size) {
- startSpotlight()
- }
featureViewStateLiveData.removeObserver(this)
}
}
@@ -112,30 +106,35 @@ class SpotlightFragment @Inject constructor(
private fun createTarget(
spotlightTarget: SpotlightTarget
) {
+
val target = Target.Builder()
- .setAnchor(spotlightTarget.anchor)
.setShape(getShape(spotlightTarget))
.setOverlay(requestOverlayResource(spotlightTarget))
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
+
+ Log.d("overlay", "target start")
}
override fun onEnded() {
+ Log.d("overlay", "target end")
+ targetList.pop()
val profileId = ProfileId.newBuilder()
.setInternalId(internalProfileId)
.build()
- spotlightStateController.markSpotlightViewed(
- profileId,
- spotlightTarget.feature
- )
+ spotlightStateController.markSpotlightViewed(profileId, spotlightTarget.feature)
}
})
- .build()
+ .build(spotlightTarget.anchor)
targetList.add(target)
+ if (!isSpotlightActive) {
+ startSpotlight()
+ }
}
private fun startSpotlight() {
+ if (targetList.isNullOrEmpty()) return
spotlight = Spotlight.Builder(activity)
.setTargets(targetList)
.setBackgroundColorRes(R.color.spotlightBackground)
@@ -143,9 +142,16 @@ class SpotlightFragment @Inject constructor(
.setAnimation(DecelerateInterpolator(2f))
.setOnSpotlightListener(object : OnSpotlightListener {
override fun onStarted() {
+ Log.d("overlay", "spotlight start")
+
+ isSpotlightActive = true
}
override fun onEnded() {
+ Log.d("overlay", "spotlight end")
+
+ isSpotlightActive = false
+ startSpotlight()
}
})
.build()
@@ -183,11 +189,17 @@ class SpotlightFragment @Inject constructor(
return this.resources.getDimension(R.dimen.arrow_width)
}
+ private fun getArrowHeight(): Float {
+ return this.resources.getDimension(R.dimen.arrow_height)
+ }
+
private fun getScreenCentreY(): Int {
+ Log.d("overlay screenCentre Y", (screenHeight / 2).toString())
return screenHeight / 2
}
private fun getScreenCentreX(): Int {
+ Log.d("overlay screenCentre X", (screenWidth / 2).toString())
return screenWidth / 2
}
@@ -203,6 +215,8 @@ class SpotlightFragment @Inject constructor(
} else {
AnchorPosition.TopLeft
}
+
+ Log.d("overlay", anchorPosition.toString())
}
private fun requestOverlayResource(spotlightTarget: SpotlightTarget): View {
@@ -265,14 +279,14 @@ class SpotlightFragment @Inject constructor(
if (isRTL) {
arrowParams.setMargins(
10.dp,
- (spotlightTarget.anchorTop.toInt() - spotlightTarget.anchorHeight - 5.dp).toInt(),
+ (spotlightTarget.anchorTop.toInt() - getArrowHeight() - 5.dp).toInt(),
screenWidth - spotlightTarget.anchorLeft.toInt(),
10.dp
)
} else {
arrowParams.setMargins(
spotlightTarget.anchorLeft.toInt(),
- (spotlightTarget.anchorTop.toInt() - spotlightTarget.anchorHeight - 5.dp).toInt(),
+ (spotlightTarget.anchorTop.toInt() - getArrowHeight() - 5.dp).toInt(),
10.dp,
10.dp
)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTargetStore.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTargetStore.kt
deleted file mode 100644
index 9b05091c493..00000000000
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTargetStore.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.oppia.android.app.spotlight
-
-import android.util.Log
-import java.util.ArrayList
-import javax.inject.Inject
-import javax.inject.Singleton
-
-@Singleton
-class SpotlightTargetStore @Inject constructor() {
-
- private val spotlightTargetList = ArrayList()
-
- fun addSpotlightTarget(spotlightTarget: SpotlightTarget) {
- spotlightTargetList.add(spotlightTarget)
- Log.d("overlay", "current target list: $spotlightTargetList")
- }
-
- fun getSpotlightTargetList() = spotlightTargetList
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/org/oppia/android/app/testing/NavigationDrawerTestActivity.kt b/app/src/main/java/org/oppia/android/app/testing/NavigationDrawerTestActivity.kt
index 554c19474f9..da4817200b7 100644
--- a/app/src/main/java/org/oppia/android/app/testing/NavigationDrawerTestActivity.kt
+++ b/app/src/main/java/org/oppia/android/app/testing/NavigationDrawerTestActivity.kt
@@ -48,7 +48,7 @@ class NavigationDrawerTestActivity :
super.onCreate(savedInstanceState)
(activityComponent as ActivityComponentImpl).inject(this)
internalProfileId = intent?.getIntExtra(NAVIGATION_PROFILE_ID_ARGUMENT_KEY, -1)!!
- homeActivityPresenter.handleOnCreate()
+ homeActivityPresenter.handleOnCreate(internalProfileId)
title = resourceHandler.getStringInLocale(R.string.home_activity_title)
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicActivity.kt b/app/src/main/java/org/oppia/android/app/topic/TopicActivity.kt
index 3c8ce5b0c31..edaec9e365c 100755
--- a/app/src/main/java/org/oppia/android/app/topic/TopicActivity.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicActivity.kt
@@ -43,9 +43,6 @@ class TopicActivity :
@Inject
lateinit var topicActivityPresenter: TopicActivityPresenter
- @Inject
- lateinit var spotlightFragment: SpotlightFragment
-
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
(activityComponent as ActivityComponentImpl).inject(this)
@@ -78,10 +75,6 @@ class TopicActivity :
)
}
- fun getSpotlightFragment() {
-
- }
-
override fun routeToRevisionCard(
internalProfileId: Int,
topicId: String,
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
index 2079cfe73ad..ccc6d254bca 100755
--- a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
@@ -2,10 +2,10 @@ package org.oppia.android.app.topic
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
+import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.model.ProfileId
-import javax.inject.Inject
import org.oppia.android.app.spotlight.SpotlightFragment
const val TOPIC_FRAGMENT_TAG = "TopicFragment"
@@ -16,10 +16,7 @@ const val STORY_ID_ARGUMENT_KEY = "story_id"
/** The presenter for [TopicActivity]. */
@ActivityScope
-class TopicActivityPresenter @Inject constructor(
- private val activity: AppCompatActivity,
- private val spotlightFragment: SpotlightFragment
-) {
+class TopicActivityPresenter @Inject constructor(private val activity: AppCompatActivity) {
private lateinit var topicId: String
private lateinit var profileId: ProfileId
@@ -43,11 +40,14 @@ class TopicActivityPresenter @Inject constructor(
).commitNow()
}
- activity.supportFragmentManager.beginTransaction().add(
- R.id.topic_fragment_placeholder,
- spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
- ).commitNow()
-
+ val spotlightFragment = SpotlightFragment()
+ val args = Bundle()
+ args.putInt(PROFILE_ID_ARGUMENT_KEY, internalProfileId)
+ spotlightFragment.arguments = args
+ activity.supportFragmentManager.beginTransaction().add(
+ R.id.topic_fragment_placeholder,
+ spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
+ ).commitNow()
}
private fun getTopicFragment(): TopicFragment? {
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index b4c59268b26..fa22fc92dc8 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -16,7 +16,6 @@ import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
-import org.oppia.android.app.spotlight.SpotlightTargetStore
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.databinding.TopicFragmentBinding
import org.oppia.android.domain.oppialogger.OppiaLogger
@@ -32,7 +31,6 @@ class TopicFragmentPresenter @Inject constructor(
private val oppiaLogger: OppiaLogger,
@EnableExtraTopicTabsUi private val enableExtraTopicTabsUi: PlatformParameterValue,
private val resourceHandler: AppLanguageResourceHandler,
- private val spotlightTargetStore: SpotlightTargetStore
) {
private lateinit var tabLayout: TabLayout
private var internalProfileId: Int = -1
@@ -77,43 +75,37 @@ class TopicFragmentPresenter @Inject constructor(
}
fun startSpotlight() {
- viewModel.numberOfChaptersCompletedLiveData.observe(fragment) { numberOfChaptersCompleted->
+ viewModel.numberOfChaptersCompletedLiveData.observe(fragment) { numberOfChaptersCompleted ->
if (numberOfChaptersCompleted != -1) {
val lessonsTabView = tabLayout.getTabAt(computeTabPosition(TopicTab.LESSONS))?.view
lessonsTabView?.let { lessonsTabView ->
-// lessonsTabView.doOnPreDraw {
- val lessonsTabSpotlightTarget = SpotlightTarget(
- lessonsTabView,
- "Find all your lessons here",
+ val lessonsTabSpotlightTarget = SpotlightTarget(
+ lessonsTabView,
+ "Find all your lessons here",
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.TOPIC_LESSON_TAB
+ )
+ getSpotlightFragment().checkSpotlightViewState(lessonsTabSpotlightTarget)
+
+ if (numberOfChaptersCompleted > 2) {
+ val revisionTabView = tabLayout.getTabAt(computeTabPosition(TopicTab.REVISION))?.view
+ val revisionTabSpotlightTarget = SpotlightTarget(
+ revisionTabView!!,
+ "Revise your lessons here",
SpotlightShape.RoundedRectangle,
- Spotlight.FeatureCase.TOPIC_LESSON_TAB
+ Spotlight.FeatureCase.TOPIC_REVISION_TAB
)
-
-// if (numberOfChaptersCompleted > 2) {
- val revisionTabView = tabLayout.getTabAt(computeTabPosition(TopicTab.REVISION))?.view
- val revisionTabSpotlightTarget = SpotlightTarget(
- revisionTabView!!,
- "Revise your lessons here",
- SpotlightShape.RoundedRectangle,
- Spotlight.FeatureCase.TOPIC_REVISION_TAB
- )
- getSpotlightFragment().setInternalId(internalProfileId)
- getSpotlightFragment().checkSpotlightViewState(lessonsTabSpotlightTarget)
- getSpotlightFragment().checkSpotlightViewState(revisionTabSpotlightTarget)
-
-// } else {
-
-// getSpotlightFragment().checkSpotlightViewState(lessonsTabSpotlightTarget)
-
- }
-// }
-// }
+ getSpotlightFragment().checkSpotlightViewState(revisionTabSpotlightTarget)
+ }
+ }
}
}
}
private fun getSpotlightFragment(): SpotlightFragment {
- return activity.supportFragmentManager.findFragmentByTag(SPOTLIGHT_FRAGMENT_TAG) as SpotlightFragment
+ return activity.supportFragmentManager.findFragmentByTag(
+ SPOTLIGHT_FRAGMENT_TAG
+ ) as SpotlightFragment
}
private fun setCurrentTab(tab: TopicTab) {
diff --git a/app/src/main/res/layout/exploration_activity.xml b/app/src/main/res/layout/exploration_activity.xml
index b5291deb7cb..2fe2d8413e1 100755
--- a/app/src/main/res/layout/exploration_activity.xml
+++ b/app/src/main/res/layout/exploration_activity.xml
@@ -12,86 +12,95 @@
type="org.oppia.android.app.player.exploration.ExplorationViewModel" />
-
+ android:layout_height="match_parent">
-
+
+
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ tools:context=".player.exploration.ExplorationActivity">
-
+ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
-
+ android:background="@color/component_color_exploration_activity_toolbar_color"
+ android:minHeight="?attr/actionBarSize"
+ android:theme="@style/Widget.AppCompat.ActionBar"
+ app:navigationIcon="@drawable/ic_close_white_24dp">
-
-
-
+
+
-
-
-
-
-
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="20dp"
+ android:layout_weight="1"
+ app:animationDelay="500"
+ app:animationSpeed="10">
-
-
-
+
+
-
+
+
+
+
+
+
+ android:layout_height="match_parent">
-
-
-
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/home_activity.xml b/app/src/main/res/layout/home_activity.xml
index a1daecd2670..a9face6fb46 100644
--- a/app/src/main/res/layout/home_activity.xml
+++ b/app/src/main/res/layout/home_activity.xml
@@ -6,6 +6,11 @@
android:layout_height="match_parent"
tools:context=".app.home.HomeActivity">
+
+
Date: Tue, 8 Nov 2022 04:08:34 +0530
Subject: [PATCH 057/138] update spotlight fragment and refactor function name
---
...hapterNotStartedContainerConstraintLayout.kt | 2 +-
.../app/customview/PromotedStoryCardView.kt | 4 +---
.../app/player/audio/AudioFragmentPresenter.kt | 2 +-
.../exploration/ExplorationFragmentPresenter.kt | 4 ++--
.../android/app/spotlight/SpotlightFragment.kt | 17 +++++++++++++----
.../android/app/topic/TopicFragmentPresenter.kt | 4 ++--
6 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index 2f2a99b0580..93f45bb1413 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -57,7 +57,7 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
SpotlightShape.RoundedRectangle,
Spotlight.FeatureCase.FIRST_CHAPTER
)
- getSpotlightFragment().checkSpotlightViewState(target)
+ getSpotlightFragment().requestSpotlight(target)
// this view is attached multiple times which can lead to crashes due spotlight request
// being added multiple times. [isSpotlit] is a flag to prevent the same.
isSpotlit = true
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
index 74ddb1da1fb..f47c284e354 100644
--- a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -2,8 +2,6 @@ package org.oppia.android.app.customview
import android.content.Context
import android.util.AttributeSet
-import androidx.core.view.doOnLayout
-import androidx.core.view.doOnPreDraw
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import com.google.android.material.card.MaterialCardView
@@ -56,7 +54,7 @@ class PromotedStoryCardView @JvmOverloads constructor(
Spotlight.FeatureCase.PROMOTED_STORIES
)
isSpotlit = true
- getSpotlightFragment().checkSpotlightViewState(promotesStorySpotlightTarget)
+ getSpotlightFragment().requestSpotlight(promotesStorySpotlightTarget)
}
}
}
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index 35c3819c9c2..9a0fe528c6b 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -123,7 +123,7 @@ class AudioFragmentPresenter @Inject constructor(
private fun startSpotlights() {
val audioLanguageIconView = binding.audioLanguageIcon
audioLanguageIconView.doOnPreDraw {
- getSpotlightFragment().checkSpotlightViewState(
+ getSpotlightFragment().requestSpotlight(
SpotlightTarget(
it,
"Tap to change",
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index f6f126f1e2a..c35ec530359 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -107,7 +107,7 @@ class ExplorationFragmentPresenter @Inject constructor(
SpotlightShape.Circle,
Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
)
- getSpotlightFragment().checkSpotlightViewState(backButtonSpotlightTarget)
+ getSpotlightFragment().requestSpotlight(backButtonSpotlightTarget)
if (
numberOfChaptersCompleted >= 1 &&
@@ -119,7 +119,7 @@ class ExplorationFragmentPresenter @Inject constructor(
SpotlightShape.Circle,
Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
)
- getSpotlightFragment().checkSpotlightViewState(audioPlayerSpotlightTarget)
+ getSpotlightFragment().requestSpotlight(audioPlayerSpotlightTarget)
}
}
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 377293b3f5e..09cde0656fe 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -16,8 +16,6 @@ import com.takusemba.spotlight.Target
import com.takusemba.spotlight.shape.Circle
import com.takusemba.spotlight.shape.RoundedRectangle
import com.takusemba.spotlight.shape.Shape
-import java.util.*
-import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentComponentImpl
import org.oppia.android.app.fragment.InjectableFragment
@@ -33,8 +31,11 @@ import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.util.accessibility.AccessibilityServiceImpl
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
+import java.util.LinkedList
+import java.util.Locale
+import javax.inject.Inject
-class SpotlightFragment: InjectableFragment(), SpotlightNavigationListener {
+class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
@Inject
lateinit var activity: AppCompatActivity
@@ -72,7 +73,15 @@ class SpotlightFragment: InjectableFragment(), SpotlightNavigationListener {
checkIsRTL()
}
- fun checkSpotlightViewState(spotlightTarget: SpotlightTarget) {
+ /**
+ * Requests a spotlight to be shown on the [SpotlightTarget]. The spotlight is enqueued if it
+ * hasn't been shown before in a FIFO buffer.
+ *
+ * @param spotlightTarget The [SpotlightTarget] for which the spotlight is requested
+ */
+ fun requestSpotlight(spotlightTarget: SpotlightTarget) {
+
+ if (accessibilityServiceImpl.isScreenReaderEnabled()) return
val profileId = ProfileId.newBuilder()
.setInternalId(internalProfileId)
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index fa22fc92dc8..5882b54e995 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -85,7 +85,7 @@ class TopicFragmentPresenter @Inject constructor(
SpotlightShape.RoundedRectangle,
Spotlight.FeatureCase.TOPIC_LESSON_TAB
)
- getSpotlightFragment().checkSpotlightViewState(lessonsTabSpotlightTarget)
+ getSpotlightFragment().requestSpotlight(lessonsTabSpotlightTarget)
if (numberOfChaptersCompleted > 2) {
val revisionTabView = tabLayout.getTabAt(computeTabPosition(TopicTab.REVISION))?.view
@@ -95,7 +95,7 @@ class TopicFragmentPresenter @Inject constructor(
SpotlightShape.RoundedRectangle,
Spotlight.FeatureCase.TOPIC_REVISION_TAB
)
- getSpotlightFragment().checkSpotlightViewState(revisionTabSpotlightTarget)
+ getSpotlightFragment().requestSpotlight(revisionTabSpotlightTarget)
}
}
}
From a77f4cb016931c602ffdb802c04d6e32b892c7bf Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Tue, 8 Nov 2022 20:52:12 +0530
Subject: [PATCH 058/138] lint
---
...pterNotStartedContainerConstraintLayout.kt | 30 +++++++++----------
.../app/customview/PromotedStoryCardView.kt | 6 ++--
.../android/app/home/HomeActivityPresenter.kt | 2 +-
.../player/audio/AudioFragmentPresenter.kt | 2 +-
.../ExplorationActivityPresenter.kt | 2 +-
.../ExplorationFragmentPresenter.kt | 3 +-
.../oppia/android/app/topic/TopicActivity.kt | 3 --
.../app/topic/TopicActivityPresenter.kt | 2 +-
.../oppia/android/app/topic/TopicFragment.kt | 2 --
.../app/topic/TopicFragmentPresenter.kt | 2 +-
.../oppia/android/app/topic/TopicViewModel.kt | 4 +--
.../android/app/home/HomeActivityTest.kt | 7 ++---
12 files changed, 29 insertions(+), 36 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index 93f45bb1413..51bda7c3be7 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -6,7 +6,6 @@ import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.doOnPreDraw
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
-import javax.inject.Inject
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightShape
@@ -14,6 +13,7 @@ import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
+import javax.inject.Inject
class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
context: Context,
@@ -49,20 +49,20 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
viewComponent.inject(this)
this.doOnPreDraw {
- if (!isSpotlit) {
- if (index == 0) {
- val target = SpotlightTarget(
- it,
- "Tap to start a chapter",
- SpotlightShape.RoundedRectangle,
- Spotlight.FeatureCase.FIRST_CHAPTER
- )
- getSpotlightFragment().requestSpotlight(target)
- // this view is attached multiple times which can lead to crashes due spotlight request
- // being added multiple times. [isSpotlit] is a flag to prevent the same.
- isSpotlit = true
- }
+ if (!isSpotlit) {
+ if (index == 0) {
+ val target = SpotlightTarget(
+ it,
+ "Tap to start a chapter",
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.FIRST_CHAPTER
+ )
+ getSpotlightFragment().requestSpotlight(target)
+ // this view is attached multiple times which can lead to crashes due spotlight request
+ // being added multiple times. [isSpotlit] is a flag to prevent the same.
+ isSpotlit = true
}
}
+ }
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
index f47c284e354..2b40d186608 100644
--- a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -5,7 +5,6 @@ import android.util.AttributeSet
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import com.google.android.material.card.MaterialCardView
-import javax.inject.Inject
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightShape
@@ -13,12 +12,13 @@ import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
+import javax.inject.Inject
class PromotedStoryCardView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
-): MaterialCardView(context, attrs, defStyleAttr) {
+) : MaterialCardView(context, attrs, defStyleAttr) {
private var promotedStoryIndex = -1
private var isSpotlit = false
@@ -59,4 +59,4 @@ class PromotedStoryCardView @JvmOverloads constructor(
}
}
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
index 3c5f855ac84..ba3bddb9eb4 100644
--- a/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
@@ -8,10 +8,10 @@ import androidx.drawerlayout.widget.DrawerLayout
import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.drawer.NavigationDrawerFragment
-import javax.inject.Inject
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
+import javax.inject.Inject
const val TAG_HOME_FRAGMENT = "HOME_FRAGMENT"
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index 9a0fe528c6b..381bb60f63d 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -14,7 +14,6 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.Transformations
-import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.AudioLanguage
@@ -37,6 +36,7 @@ import org.oppia.android.domain.profile.ProfileManagementController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.networking.NetworkConnectionUtil
+import javax.inject.Inject
const val TAG_LANGUAGE_DIALOG = "LANGUAGE_DIALOG"
private const val TAG_CELLULAR_DATA_DIALOG = "CELLULAR_DATA_DIALOG"
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
index 3e70783fbdb..edbd12e1673 100644
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
@@ -10,7 +10,6 @@ import androidx.databinding.DataBindingUtil
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.Transformations
-import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.help.HelpActivity
@@ -34,6 +33,7 @@ import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.translation.TranslationController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
+import javax.inject.Inject
private const val TAG_UNSAVED_EXPLORATION_DIALOG = "UNSAVED_EXPLORATION_DIALOG"
private const val TAG_STOP_EXPLORATION_DIALOG = "STOP_EXPLORATION_DIALOG"
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index c35ec530359..2cf92c69662 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -10,7 +10,6 @@ import androidx.core.view.forEach
import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations
-import javax.inject.Inject
import kotlinx.android.synthetic.main.exploration_activity.*
import kotlinx.android.synthetic.main.exploration_activity.view.*
import org.oppia.android.R
@@ -34,6 +33,7 @@ import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.extensions.getProto
import org.oppia.android.util.extensions.putProto
+import javax.inject.Inject
/** The presenter for [ExplorationFragment]. */
@FragmentScope
@@ -89,7 +89,6 @@ class ExplorationFragmentPresenter @Inject constructor(
showSpotlights()
}
}
-
}
private fun showSpotlights() {
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicActivity.kt b/app/src/main/java/org/oppia/android/app/topic/TopicActivity.kt
index edaec9e365c..a65e6668e4a 100755
--- a/app/src/main/java/org/oppia/android/app/topic/TopicActivity.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicActivity.kt
@@ -3,8 +3,6 @@ package org.oppia.android.app.topic
import android.content.Context
import android.content.Intent
import android.os.Bundle
-import android.util.AttributeSet
-import android.view.View
import androidx.appcompat.app.AppCompatActivity
import org.oppia.android.app.activity.ActivityComponentImpl
import org.oppia.android.app.activity.ActivityIntentFactories
@@ -22,7 +20,6 @@ import org.oppia.android.app.topic.questionplayer.QuestionPlayerActivity
import org.oppia.android.app.topic.revisioncard.RevisionCardActivity
import org.oppia.android.util.logging.CurrentAppScreenNameIntentDecorator.decorateWithScreenName
import javax.inject.Inject
-import org.oppia.android.app.spotlight.SpotlightFragment
private const val TOPIC_ACTIVITY_TOPIC_ID_ARGUMENT_KEY = "TopicActivity.topic_id"
private const val TOPIC_ACTIVITY_STORY_ID_ARGUMENT_KEY = "TopicActivity.story_id"
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
index ccc6d254bca..db776f77930 100755
--- a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
@@ -2,11 +2,11 @@ package org.oppia.android.app.topic
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
-import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.spotlight.SpotlightFragment
+import javax.inject.Inject
const val TOPIC_FRAGMENT_TAG = "TopicFragment"
const val SPOTLIGHT_FRAGMENT_TAG = "SpotlightFragment"
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
index 9f435a740db..c76175afffc 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragment.kt
@@ -45,5 +45,3 @@ class TopicFragment : InjectableFragment() {
topicFragmentPresenter.startSpotlight()
}
}
-
-
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 5882b54e995..ba05439a3d4 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -9,7 +9,6 @@ import androidx.fragment.app.Fragment
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
-import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.Spotlight
@@ -21,6 +20,7 @@ import org.oppia.android.databinding.TopicFragmentBinding
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.util.platformparameter.EnableExtraTopicTabsUi
import org.oppia.android.util.platformparameter.PlatformParameterValue
+import javax.inject.Inject
/** The presenter for [TopicFragment]. */
@FragmentScope
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt b/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
index 3200396baa5..a141e418379 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
@@ -6,16 +6,16 @@ import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.EphemeralTopic
import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.model.PromotedActivityList
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ObservableViewModel
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.topic.TopicController
+import org.oppia.android.domain.topic.TopicListController
import org.oppia.android.domain.translation.TranslationController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import javax.inject.Inject
-import org.oppia.android.app.model.PromotedActivityList
-import org.oppia.android.domain.topic.TopicListController
/** The ObservableViewModel for [TopicFragment]. */
@FragmentScope
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
index ba6c7ff5df4..f368580e5d3 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
@@ -31,9 +31,6 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import dagger.Component
-import java.util.*
-import javax.inject.Inject
-import javax.inject.Singleton
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.Description
@@ -144,6 +141,9 @@ import org.oppia.android.util.parser.image.GlideImageLoaderModule
import org.oppia.android.util.parser.image.ImageParsingModule
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
+import java.util.Locale
+import javax.inject.Inject
+import javax.inject.Singleton
// Time: Tue Apr 23 2019 23:22:00
private const val EVENING_TIMESTAMP = 1556061720000
@@ -341,7 +341,6 @@ class HomeActivityTest {
logIntoUserTwice()
launch(createHomeActivityIntent(internalProfileId1)).use {
testCoroutineDispatchers.runCurrent()
-
}
dataProviderTestMonitor.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
From 26177edbd51eb9d4240106484ecfb2ac13769fd8 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Tue, 8 Nov 2022 21:51:33 +0530
Subject: [PATCH 059/138] manage audio that was playing beneath the spotlight
fragment
---
.../player/audio/AudioFragmentPresenter.kt | 19 ++++++++++++++++++-
.../app/spotlight/SpotlightFragment.kt | 13 +++++++++----
.../app/topic/TopicActivityPresenter.kt | 2 +-
3 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index 381bb60f63d..c1c21c45db6 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -14,6 +14,7 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.Transformations
+import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.AudioLanguage
@@ -36,7 +37,6 @@ import org.oppia.android.domain.profile.ProfileManagementController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.networking.NetworkConnectionUtil
-import javax.inject.Inject
const val TAG_LANGUAGE_DIALOG = "LANGUAGE_DIALOG"
private const val TAG_CELLULAR_DATA_DIALOG = "CELLULAR_DATA_DIALOG"
@@ -120,6 +120,16 @@ class AudioFragmentPresenter @Inject constructor(
return binding.root
}
+ private fun subscribeToSpotlightStatusLiveData() {
+ getSpotlightFragment().getSpotlightStatusLiveData().observe(fragment) { isSpotlightActive ->
+ if (isSpotlightActive) {
+ handleOnStop()
+ } else {
+ handleOnPlay()
+ }
+ }
+ }
+
private fun startSpotlights() {
val audioLanguageIconView = binding.audioLanguageIcon
audioLanguageIconView.doOnPreDraw {
@@ -208,6 +218,12 @@ class AudioFragmentPresenter @Inject constructor(
}
}
+ private fun handleOnPlay() {
+ if (!activity.isChangingConfigurations && prepared) {
+ viewModel.togglePlayPause(UiAudioPlayStatus.PAUSED)
+ }
+ }
+
/** Releases audio player resources */
fun handleOnDestroy() {
if (!activity.isChangingConfigurations) {
@@ -291,6 +307,7 @@ class AudioFragmentPresenter @Inject constructor(
}
fragment.view?.startAnimation(AnimationUtils.loadAnimation(context, R.anim.slide_down_audio))
startSpotlights()
+ subscribeToSpotlightStatusLiveData()
}
private fun hideAudioFragment() {
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 09cde0656fe..ccd0a1b08c3 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -8,6 +8,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.animation.DecelerateInterpolator
import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import com.takusemba.spotlight.OnSpotlightListener
import com.takusemba.spotlight.OnTargetListener
@@ -52,7 +53,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
private lateinit var anchorPosition: AnchorPosition
private lateinit var overlayBinding: Any
private var internalProfileId: Int = -1
- private var isSpotlightActive = false
+ private val isSpotlightActive = MutableLiveData(false)
private var isRTL = false
private fun calculateScreenSize() {
@@ -63,6 +64,10 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
screenWidth = displayMetrics.widthPixels
}
+ fun getSpotlightStatusLiveData(): MutableLiveData {
+ return isSpotlightActive
+ }
+
// since this fragment does not have any view to inflate yet, all the tasks should be done here.
override fun onAttach(context: Context) {
super.onAttach(context)
@@ -137,7 +142,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
.build(spotlightTarget.anchor)
targetList.add(target)
- if (!isSpotlightActive) {
+ if (!isSpotlightActive.value!!) {
startSpotlight()
}
}
@@ -153,13 +158,13 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
override fun onStarted() {
Log.d("overlay", "spotlight start")
- isSpotlightActive = true
+ isSpotlightActive.value = true
}
override fun onEnded() {
Log.d("overlay", "spotlight end")
- isSpotlightActive = false
+ isSpotlightActive.value = false
startSpotlight()
}
})
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
index db776f77930..d1eb9844378 100755
--- a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
@@ -45,7 +45,7 @@ class TopicActivityPresenter @Inject constructor(private val activity: AppCompat
args.putInt(PROFILE_ID_ARGUMENT_KEY, internalProfileId)
spotlightFragment.arguments = args
activity.supportFragmentManager.beginTransaction().add(
- R.id.topic_fragment_placeholder,
+ R.id.topic_spotlight_fragment_placeholder,
spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
).commitNow()
}
From d960e8f912b9641b77690d584bef27a2c96cfb90 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Tue, 8 Nov 2022 23:37:00 +0530
Subject: [PATCH 060/138] commit before checkout
---
...pterNotStartedContainerConstraintLayout.kt | 48 +++++++++++--------
.../app/customview/PromotedStoryCardView.kt | 28 ++++-------
2 files changed, 38 insertions(+), 38 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index 51bda7c3be7..1329bc5f1f6 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -21,8 +21,8 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
- private var index: Int = -1
- private var isSpotlit = false
+// private var index: Int = -1
+// private var isSpotlit = false
@Inject
lateinit var fragment: Fragment
@@ -31,7 +31,16 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
// Only spotlight the first chapter of the "first" story. We know for sure that for a new user,
// the first chapter shall be a type of not started chapter view. The index tells which story
// are we on.
- this.index = index
+ if (index == 0) {
+ val target = SpotlightTarget(
+ this,
+ "Tap to start a chapter",
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.FIRST_CHAPTER
+ )
+
+ getSpotlightFragment().requestSpotlight(target)
+ }
}
private fun getSpotlightFragment(): SpotlightFragment {
@@ -48,21 +57,22 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
val viewComponent = viewComponentFactory.createViewComponent(this) as ViewComponentImpl
viewComponent.inject(this)
- this.doOnPreDraw {
- if (!isSpotlit) {
- if (index == 0) {
- val target = SpotlightTarget(
- it,
- "Tap to start a chapter",
- SpotlightShape.RoundedRectangle,
- Spotlight.FeatureCase.FIRST_CHAPTER
- )
- getSpotlightFragment().requestSpotlight(target)
- // this view is attached multiple times which can lead to crashes due spotlight request
- // being added multiple times. [isSpotlit] is a flag to prevent the same.
- isSpotlit = true
- }
- }
- }
+
+// this.doOnPreDraw {
+// if (!isSpotlit) {
+// if (index == 0) {
+// val target = SpotlightTarget(
+// it,
+// "Tap to start a chapter",
+// SpotlightShape.RoundedRectangle,
+// Spotlight.FeatureCase.FIRST_CHAPTER
+// )
+// getSpotlightFragment().requestSpotlight(target)
+// // this view is attached multiple times which can lead to crashes due spotlight request
+// // being added multiple times. [isSpotlit] is a flag to prevent the same.
+// isSpotlit = true
+// }
+// }
+// }
}
}
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
index 2b40d186608..cf210975320 100644
--- a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -20,14 +20,19 @@ class PromotedStoryCardView @JvmOverloads constructor(
defStyleAttr: Int = 0
) : MaterialCardView(context, attrs, defStyleAttr) {
- private var promotedStoryIndex = -1
- private var isSpotlit = false
-
@Inject
lateinit var fragment: Fragment
fun setIndex(index: Int) {
- this.promotedStoryIndex = index
+ if (index == 0) {
+ val promotesStorySpotlightTarget = SpotlightTarget(
+ this,
+ "From now, here you can view stories you might be interested in",
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.PROMOTED_STORIES
+ )
+ getSpotlightFragment().requestSpotlight(promotesStorySpotlightTarget)
+ }
}
private fun getSpotlightFragment(): SpotlightFragment {
@@ -43,20 +48,5 @@ class PromotedStoryCardView @JvmOverloads constructor(
FragmentManager.findFragment(this) as ViewComponentFactory
val viewComponent = viewComponentFactory.createViewComponent(this) as ViewComponentImpl
viewComponent.inject(this)
-
- this.post {
- if (!isSpotlit) {
- if (promotedStoryIndex == 0) {
- val promotesStorySpotlightTarget = SpotlightTarget(
- this,
- "From now, here you can view stories you might be interested in",
- SpotlightShape.RoundedRectangle,
- Spotlight.FeatureCase.PROMOTED_STORIES
- )
- isSpotlit = true
- getSpotlightFragment().requestSpotlight(promotesStorySpotlightTarget)
- }
- }
- }
}
}
From 23af2efe5e30988dd4e9f22496a0fd841e22ebd1 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Wed, 9 Nov 2022 23:01:07 +0530
Subject: [PATCH 061/138] slight adjustments for overlay design
---
.../main/res/layout/bottom_left_overlay.xml | 21 ++++++++-----
.../main/res/layout/bottom_right_overlay.xml | 17 +++++++----
app/src/main/res/layout/top_left_overlay.xml | 21 ++++++++-----
app/src/main/res/layout/top_right_overlay.xml | 30 ++++++++++---------
4 files changed, 55 insertions(+), 34 deletions(-)
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 07fccf7fc79..014c8a8d1f7 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -13,9 +13,11 @@
+ android:layout_height="match_parent"
+ android:focusable="true"
+ android:clickable="true"
+ android:background="@drawable/transparent_background">
@@ -62,6 +68,7 @@
android:layout_marginStart="10dp"
android:layout_marginTop="50dp"
android:text="dismiss"
+ android:visibility="invisible"
android:textColor="#FFFFFF"
android:textSize="20sp"
android:textStyle="bold"
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index 1c5b06928a6..cac3a704cb9 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -14,8 +14,8 @@
@@ -45,15 +45,19 @@
@@ -67,6 +71,7 @@
android:textColor="#FFFFFF"
android:textSize="20sp"
android:textStyle="bold"
+ android:visibility="invisible"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index a09a30e07a2..42775856fd0 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -14,6 +14,8 @@
@@ -41,17 +43,21 @@
+ app:layout_constraintBottom_toBottomOf="parent"/>
-
@@ -15,48 +14,50 @@
+ android:focusable="true">
+ app:layout_constraintBottom_toBottomOf="parent"/>
From 587ad65235e22c1252f6bb86a6948e1964ffbd2a Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 10 Nov 2022 00:05:25 +0530
Subject: [PATCH 062/138] finalise overlay alignments
---
.../app/spotlight/SpotlightFragment.kt | 6 ++--
.../main/res/layout/bottom_left_overlay.xml | 1 -
.../main/res/layout/bottom_right_overlay.xml | 4 +--
app/src/main/res/layout/top_left_overlay.xml | 31 ++++++++++---------
app/src/main/res/layout/top_right_overlay.xml | 6 ++--
5 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index ccd0a1b08c3..ce6c341e3f0 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -324,7 +324,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
if (isRTL) {
arrowParams.setMargins(
10.dp,
- (spotlightTarget.anchorTop.toInt() - spotlightTarget.anchorHeight - 5.dp).toInt(),
+ (spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
screenWidth -
(spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
10.dp
@@ -332,7 +332,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
} else {
arrowParams.setMargins(
(spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
- (spotlightTarget.anchorTop.toInt() - spotlightTarget.anchorHeight - 5.dp).toInt(),
+ (spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
10.dp,
10.dp
)
@@ -363,7 +363,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
)
} else {
arrowParams.setMargins(
- (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth() + 5.dp).toInt(),
+ (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
(spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
10.dp,
10.dp
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 014c8a8d1f7..93e87a50b0b 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -34,7 +34,6 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
- android:gravity="center"
android:text="this is a custom text"
android:textColor="@android:color/white"
android:textSize="24dp"
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index cac3a704cb9..0de88fc1bac 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -34,12 +34,12 @@
style="@style/TextViewStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="center"
android:text="this is a custom text"
- android:textAlignment="center"
+ android:textAlignment="viewEnd"
android:textColor="@android:color/white"
android:textSize="24dp"
android:textStyle="bold"
+ app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@id/arrow"
app:layout_constraintEnd_toEndOf="@+id/arrow" />
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index 42775856fd0..2b53d2a5ccf 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -14,10 +14,10 @@
+ android:clickable="true"
+ android:focusable="true">
+ android:textSize="14dp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
diff --git a/app/src/main/res/layout/top_right_overlay.xml b/app/src/main/res/layout/top_right_overlay.xml
index 31a616dc9e9..6ab7171d37e 100644
--- a/app/src/main/res/layout/top_right_overlay.xml
+++ b/app/src/main/res/layout/top_right_overlay.xml
@@ -31,14 +31,14 @@
From c36fb808ad5af06f59a5935ad045fc6d78584800 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 10 Nov 2022 00:05:59 +0530
Subject: [PATCH 063/138] adjustments so that app temporarily works
---
...pterNotStartedContainerConstraintLayout.kt | 47 ++++++++-----------
.../player/audio/AudioFragmentPresenter.kt | 8 ++--
2 files changed, 23 insertions(+), 32 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index 1329bc5f1f6..4476264e187 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -21,8 +21,8 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
-// private var index: Int = -1
-// private var isSpotlit = false
+ private var index: Int = -1
+ private var isSpotlit = false
@Inject
lateinit var fragment: Fragment
@@ -31,16 +31,7 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
// Only spotlight the first chapter of the "first" story. We know for sure that for a new user,
// the first chapter shall be a type of not started chapter view. The index tells which story
// are we on.
- if (index == 0) {
- val target = SpotlightTarget(
- this,
- "Tap to start a chapter",
- SpotlightShape.RoundedRectangle,
- Spotlight.FeatureCase.FIRST_CHAPTER
- )
-
- getSpotlightFragment().requestSpotlight(target)
- }
+ this.index = index
}
private fun getSpotlightFragment(): SpotlightFragment {
@@ -58,21 +49,21 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
viewComponent.inject(this)
-// this.doOnPreDraw {
-// if (!isSpotlit) {
-// if (index == 0) {
-// val target = SpotlightTarget(
-// it,
-// "Tap to start a chapter",
-// SpotlightShape.RoundedRectangle,
-// Spotlight.FeatureCase.FIRST_CHAPTER
-// )
-// getSpotlightFragment().requestSpotlight(target)
-// // this view is attached multiple times which can lead to crashes due spotlight request
-// // being added multiple times. [isSpotlit] is a flag to prevent the same.
-// isSpotlit = true
-// }
-// }
-// }
+ this.doOnPreDraw {
+ if (!isSpotlit) {
+ if (index == 0) {
+ val target = SpotlightTarget(
+ it,
+ "Tap to start a chapter",
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.FIRST_CHAPTER
+ )
+ getSpotlightFragment().requestSpotlight(target)
+ // this view is attached multiple times which can lead to crashes due spotlight request
+ // being added multiple times. [isSpotlit] is a flag to prevent the same.
+ isSpotlit = true
+ }
+ }
+ }
}
}
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index c1c21c45db6..6c5f0092edc 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -136,11 +136,12 @@ class AudioFragmentPresenter @Inject constructor(
getSpotlightFragment().requestSpotlight(
SpotlightTarget(
it,
- "Tap to change",
+ "Tap to change voice-over language",
SpotlightShape.Circle,
Spotlight.FeatureCase.VOICEOVER_LANGUAGE_ICON
)
)
+ subscribeToSpotlightStatusLiveData()
}
}
@@ -301,13 +302,12 @@ class AudioFragmentPresenter @Inject constructor(
audioButtonListener.scrollToTop()
if (feedbackId == null) {
// This isn't reloading content since it's the first case of the content auto-playing.
- loadMainContentAudio(allowAutoPlay = true, reloadingContent = false)
+ loadMainContentAudio(allowAutoPlay = false, reloadingContent = false)
} else {
- loadFeedbackAudio(feedbackId!!, true)
+ loadFeedbackAudio(feedbackId!!, false)
}
fragment.view?.startAnimation(AnimationUtils.loadAnimation(context, R.anim.slide_down_audio))
startSpotlights()
- subscribeToSpotlightStatusLiveData()
}
private fun hideAudioFragment() {
From 792638ecb43f2dfc278f24bdba42b8d930470a68 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 11 Nov 2022 18:03:57 +0530
Subject: [PATCH 064/138] restrict doOnPreDraw calls to spotlight fragment
---
...pterNotStartedContainerConstraintLayout.kt | 45 ++++++-------------
.../app/customview/PromotedStoryCardView.kt | 33 ++++++++++----
.../player/audio/AudioFragmentPresenter.kt | 20 ++++-----
.../app/spotlight/SpotlightFragment.kt | 27 +++++++++++
4 files changed, 72 insertions(+), 53 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index 1329bc5f1f6..8b581c8eafd 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -3,17 +3,15 @@ package org.oppia.android.app.customview
import android.content.Context
import android.util.AttributeSet
import androidx.constraintlayout.widget.ConstraintLayout
-import androidx.core.view.doOnPreDraw
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
+import javax.inject.Inject
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightFragment
-import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
-import javax.inject.Inject
class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
context: Context,
@@ -21,8 +19,8 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
-// private var index: Int = -1
-// private var isSpotlit = false
+ private var index: Int = -1
+ private var isSpotlit = false
@Inject
lateinit var fragment: Fragment
@@ -31,16 +29,7 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
// Only spotlight the first chapter of the "first" story. We know for sure that for a new user,
// the first chapter shall be a type of not started chapter view. The index tells which story
// are we on.
- if (index == 0) {
- val target = SpotlightTarget(
- this,
- "Tap to start a chapter",
- SpotlightShape.RoundedRectangle,
- Spotlight.FeatureCase.FIRST_CHAPTER
- )
-
- getSpotlightFragment().requestSpotlight(target)
- }
+ this.index = index
}
private fun getSpotlightFragment(): SpotlightFragment {
@@ -57,22 +46,14 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
val viewComponent = viewComponentFactory.createViewComponent(this) as ViewComponentImpl
viewComponent.inject(this)
-
-// this.doOnPreDraw {
-// if (!isSpotlit) {
-// if (index == 0) {
-// val target = SpotlightTarget(
-// it,
-// "Tap to start a chapter",
-// SpotlightShape.RoundedRectangle,
-// Spotlight.FeatureCase.FIRST_CHAPTER
-// )
-// getSpotlightFragment().requestSpotlight(target)
-// // this view is attached multiple times which can lead to crashes due spotlight request
-// // being added multiple times. [isSpotlit] is a flag to prevent the same.
-// isSpotlit = true
-// }
-// }
-// }
+ if (!isSpotlit) {
+ isSpotlit = true
+ val spotlightTarget = SpotlightTarget(
+ this,
+ "Tap to start a chapter",
+ feature = Spotlight.FeatureCase.FIRST_CHAPTER
+ )
+ getSpotlightFragment().requestSpotlightOnFirstRecyclerItem(this, index, spotlightTarget)
+ }
}
}
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
index cf210975320..a70bbb132f4 100644
--- a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -5,14 +5,13 @@ import android.util.AttributeSet
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import com.google.android.material.card.MaterialCardView
-import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightFragment
-import org.oppia.android.app.spotlight.SpotlightShape
-import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
import javax.inject.Inject
+import org.oppia.android.app.model.Spotlight
+import org.oppia.android.app.spotlight.SpotlightTarget
class PromotedStoryCardView @JvmOverloads constructor(
context: Context,
@@ -23,16 +22,31 @@ class PromotedStoryCardView @JvmOverloads constructor(
@Inject
lateinit var fragment: Fragment
+
+ private var index: Int = -1
+ private var isSpotlit = false
+
fun setIndex(index: Int) {
- if (index == 0) {
- val promotesStorySpotlightTarget = SpotlightTarget(
+// if (index == 0) {
+// val promotesStorySpotlightTarget = SpotlightTarget(
+// this,
+// "From now, here you can view stories you might be interested in",
+// SpotlightShape.RoundedRectangle,
+// Spotlight.FeatureCase.PROMOTED_STORIES
+// )
+// getSpotlightFragment().requestSpotlight(promotesStorySpotlightTarget)
+// }
+
+ if (!isSpotlit) {
+ isSpotlit = true
+ val spotlightTarget = SpotlightTarget(
this,
- "From now, here you can view stories you might be interested in",
- SpotlightShape.RoundedRectangle,
- Spotlight.FeatureCase.PROMOTED_STORIES
+ "From now, you can see stories recommended for you here",
+ feature = Spotlight.FeatureCase.PROMOTED_STORIES
)
- getSpotlightFragment().requestSpotlight(promotesStorySpotlightTarget)
+ getSpotlightFragment().requestSpotlightOnFirstRecyclerItem(this, index, spotlightTarget)
}
+
}
private fun getSpotlightFragment(): SpotlightFragment {
@@ -48,5 +62,6 @@ class PromotedStoryCardView @JvmOverloads constructor(
FragmentManager.findFragment(this) as ViewComponentFactory
val viewComponent = viewComponentFactory.createViewComponent(this) as ViewComponentImpl
viewComponent.inject(this)
+
}
}
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index c1c21c45db6..83413c8ec39 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -9,7 +9,6 @@ import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.SeekBar
import androidx.appcompat.app.AppCompatActivity
-import androidx.core.view.doOnPreDraw
import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
@@ -131,17 +130,14 @@ class AudioFragmentPresenter @Inject constructor(
}
private fun startSpotlights() {
- val audioLanguageIconView = binding.audioLanguageIcon
- audioLanguageIconView.doOnPreDraw {
- getSpotlightFragment().requestSpotlight(
- SpotlightTarget(
- it,
- "Tap to change",
- SpotlightShape.Circle,
- Spotlight.FeatureCase.VOICEOVER_LANGUAGE_ICON
- )
- )
- }
+ val audioLanguageIconSpotlightTarget = SpotlightTarget(
+ binding.audioLanguageIcon,
+ "Tap to change",
+ SpotlightShape.Circle,
+ Spotlight.FeatureCase.VOICEOVER_LANGUAGE_ICON
+ )
+
+ getSpotlightFragment().requestSpotlightViewWithDelayedLayout(audioLanguageIconSpotlightTarget)
}
private fun getSpotlightFragment(): SpotlightFragment {
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index ccd0a1b08c3..240dd52d537 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -8,6 +8,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.animation.DecelerateInterpolator
import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.doOnPreDraw
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import com.takusemba.spotlight.OnSpotlightListener
@@ -78,6 +79,32 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
checkIsRTL()
}
+ fun requestSpotlightViewWithDelayedLayout(spotlightTarget: SpotlightTarget) {
+ spotlightTarget.anchor.doOnPreDraw {
+ val targetAfterViewFullyDrawn = SpotlightTarget(
+ it,
+ spotlightTarget.hint,
+ spotlightTarget.shape,
+ spotlightTarget.feature
+ )
+ requestSpotlight(targetAfterViewFullyDrawn)
+ }
+ }
+
+ fun requestSpotlightOnFirstRecyclerItem(customView: View, index: Int, spotlightTarget: SpotlightTarget) {
+ customView.doOnPreDraw {
+ if (index == 0) {
+ val targetAfterViewFullyDrawn = SpotlightTarget(
+ it,
+ spotlightTarget.hint,
+ spotlightTarget.shape,
+ spotlightTarget.feature
+ )
+ requestSpotlight(targetAfterViewFullyDrawn)
+ }
+ }
+ }
+
/**
* Requests a spotlight to be shown on the [SpotlightTarget]. The spotlight is enqueued if it
* hasn't been shown before in a FIFO buffer.
From e6832d77b38ff41f1cf796fce21cf65ebfb96e2e Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sat, 12 Nov 2022 02:26:22 +0530
Subject: [PATCH 065/138] top left position in rtl not working
---
.../app/spotlight/SpotlightFragment.kt | 77 ++++++++++++++-----
.../android/app/spotlight/SpotlightTarget.kt | 4 +-
.../main/res/layout/bottom_right_overlay.xml | 3 +-
app/src/main/res/layout/top_left_overlay.xml | 2 +-
4 files changed, 61 insertions(+), 25 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 9ce5a50f4c5..5b3c31754e6 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -51,7 +51,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
private lateinit var spotlight: Spotlight
private var screenHeight: Int = 0
private var screenWidth: Int = 0
- private lateinit var anchorPosition: AnchorPosition
private lateinit var overlayBinding: Any
private var internalProfileId: Int = -1
private val isSpotlightActive = MutableLiveData(false)
@@ -160,10 +159,10 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
override fun onEnded() {
Log.d("overlay", "target end")
targetList.pop()
- val profileId = ProfileId.newBuilder()
- .setInternalId(internalProfileId)
- .build()
- spotlightStateController.markSpotlightViewed(profileId, spotlightTarget.feature)
+// val profileId = ProfileId.newBuilder()
+// .setInternalId(internalProfileId)
+// .build()
+// spotlightStateController.markSpotlightViewed(profileId, spotlightTarget.feature)
}
})
.build(spotlightTarget.anchor)
@@ -244,8 +243,9 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
return screenWidth / 2
}
- private fun calculateAnchorPosition(spotlightTarget: SpotlightTarget) {
- anchorPosition = if (spotlightTarget.anchorCentreX > getScreenCentreX()) {
+ private fun calculateAnchorPosition(spotlightTarget: SpotlightTarget): AnchorPosition {
+ Log.d("overlay", "checking anchor position. RTL = $isRTL")
+ return if (spotlightTarget.anchorCentreX > getScreenCentreX()) {
if (spotlightTarget.anchorCentreY > getScreenCentreY()) {
AnchorPosition.BottomRight
} else {
@@ -257,11 +257,11 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
AnchorPosition.TopLeft
}
- Log.d("overlay", anchorPosition.toString())
}
private fun requestOverlayResource(spotlightTarget: SpotlightTarget): View {
- calculateAnchorPosition(spotlightTarget)
+ val anchorPosition = calculateAnchorPosition(spotlightTarget)
+ Log.d("overlay", anchorPosition.toString())
return when (anchorPosition) {
AnchorPosition.TopLeft -> {
@@ -272,8 +272,11 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
}
}
AnchorPosition.TopRight -> {
- configureTopRightOverlay(spotlightTarget)
- }
+ if (isRTL) {
+ configureTopLeftOverlay(spotlightTarget)
+ } else {
+ configureTopRightOverlay(spotlightTarget)
+ } }
AnchorPosition.BottomRight -> {
if (isRTL) {
configureBottomLeftOverlay(spotlightTarget)
@@ -282,7 +285,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
}
}
AnchorPosition.BottomLeft -> {
- if (isRTL) {
+ if (false) {
configureBottomRightOverlay(spotlightTarget)
} else {
configureBottomLeftOverlay(spotlightTarget)
@@ -307,6 +310,8 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
}
private fun configureBottomLeftOverlay(spotlightTarget: SpotlightTarget): View {
+ Log.d("overlay", "bottom left overlay")
+
overlayBinding = BottomLeftOverlayBinding.inflate(this.layoutInflater)
(overlayBinding as BottomLeftOverlayBinding).let {
it.lifecycleOwner = this
@@ -319,9 +324,9 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
as ViewGroup.MarginLayoutParams
if (isRTL) {
arrowParams.setMargins(
- 10.dp,
- (spotlightTarget.anchorTop.toInt() - getArrowHeight() - 5.dp).toInt(),
screenWidth - spotlightTarget.anchorLeft.toInt(),
+ (spotlightTarget.anchorTop.toInt() - getArrowHeight() - 5.dp).toInt(),
+ 10.dp,
10.dp
)
} else {
@@ -337,7 +342,9 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
return (overlayBinding as BottomLeftOverlayBinding).root
}
+
private fun configureBottomRightOverlay(spotlightTarget: SpotlightTarget): View {
+ Log.d("overlay", "bottom right overlay")
overlayBinding = BottomRightOverlayBinding.inflate(this.layoutInflater)
(overlayBinding as BottomRightOverlayBinding).let {
it.lifecycleOwner = this
@@ -350,10 +357,10 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
as ViewGroup.MarginLayoutParams
if (isRTL) {
arrowParams.setMargins(
- 10.dp,
- (spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
screenWidth -
(spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
+ (spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
+ 10.dp,
10.dp
)
} else {
@@ -370,6 +377,8 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
}
private fun configureTopRightOverlay(spotlightTarget: SpotlightTarget): View {
+ Log.d("overlay", "top right overlay")
+
overlayBinding = TopRightOverlayBinding.inflate(layoutInflater)
(overlayBinding as TopRightOverlayBinding).let {
it.lifecycleOwner = this
@@ -382,10 +391,10 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
as ViewGroup.MarginLayoutParams
if (isRTL) {
arrowParams.setMargins(
- 10.dp,
- (spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
screenWidth -
(spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
+ (spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
+ 10.dp,
10.dp
)
} else {
@@ -402,6 +411,8 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
}
private fun configureTopLeftOverlay(spotlightTarget: SpotlightTarget): View {
+ Log.d("overlay", "top left overlay")
+
overlayBinding = TopLeftOverlayBinding.inflate(this.layoutInflater)
(overlayBinding as TopLeftOverlayBinding).let {
it.lifecycleOwner = this
@@ -414,9 +425,9 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
as ViewGroup.MarginLayoutParams
if (isRTL) {
arrowParams.setMargins(
- 10.dp,
- (spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
screenWidth - spotlightTarget.anchorLeft.toInt(),
+ (spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
+ 10.dp,
10.dp
)
} else {
@@ -432,6 +443,32 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
return (overlayBinding as TopLeftOverlayBinding).root
}
+ private fun configureTopLeftOverlayWithRTL(spotlightTarget: SpotlightTarget): View {
+ Log.d("overlay", "top left overlay with rtl")
+
+ overlayBinding = TopLeftOverlayBinding.inflate(this.layoutInflater)
+ (overlayBinding as TopLeftOverlayBinding).let {
+ it.lifecycleOwner = this
+ it.presenter = this
+ }
+
+ (overlayBinding as TopLeftOverlayBinding).customText.text = spotlightTarget.hint
+
+ val arrowParams = (overlayBinding as TopLeftOverlayBinding).arrow.layoutParams
+ as ViewGroup.MarginLayoutParams
+
+ arrowParams.setMargins(
+ spotlightTarget.anchorLeft.toInt(),
+ (spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
+ 10.dp,
+ 10.dp
+ )
+
+ (overlayBinding as TopLeftOverlayBinding).arrow.layoutParams = arrowParams
+
+ return (overlayBinding as TopLeftOverlayBinding).root
+ }
+
private val Int.dp: Int
get() = (this * Resources.getSystem().displayMetrics.density + 0.5f).toInt()
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
index 1677762cb56..ff7352efdb9 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
@@ -26,14 +26,14 @@ data class SpotlightTarget(
private fun calculateAnchorLeft(): Float {
val location = IntArray(2)
- anchor.getLocationOnScreen(location)
+ anchor.getLocationInWindow(location)
val x = location[0]
return x.toFloat()
}
private fun calculateAnchorTop(): Float {
val location = IntArray(2)
- anchor.getLocationOnScreen(location)
+ anchor.getLocationInWindow(location)
val y = location[1]
return y.toFloat()
}
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index 0de88fc1bac..76cfd4c09f3 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -24,7 +24,6 @@
android:layout_width="@dimen/arrow_width"
android:layout_height="@dimen/arrow_height"
android:rotationX="180"
- android:rotationY="180"
android:src="@drawable/ic_rounded_arrow_up_right"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -32,7 +31,7 @@
Date: Sat, 12 Nov 2022 02:38:07 +0530
Subject: [PATCH 066/138] fully configure rtl compatibility
---
.../app/spotlight/SpotlightFragment.kt | 31 ++-----------------
1 file changed, 2 insertions(+), 29 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 5b3c31754e6..ca80cd8fe5d 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -391,10 +391,9 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
as ViewGroup.MarginLayoutParams
if (isRTL) {
arrowParams.setMargins(
- screenWidth -
- (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
- (spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
10.dp,
+ (spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
+ screenWidth - (spotlightTarget.anchorLeft + getArrowWidth()).toInt(),
10.dp
)
} else {
@@ -443,32 +442,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
return (overlayBinding as TopLeftOverlayBinding).root
}
- private fun configureTopLeftOverlayWithRTL(spotlightTarget: SpotlightTarget): View {
- Log.d("overlay", "top left overlay with rtl")
-
- overlayBinding = TopLeftOverlayBinding.inflate(this.layoutInflater)
- (overlayBinding as TopLeftOverlayBinding).let {
- it.lifecycleOwner = this
- it.presenter = this
- }
-
- (overlayBinding as TopLeftOverlayBinding).customText.text = spotlightTarget.hint
-
- val arrowParams = (overlayBinding as TopLeftOverlayBinding).arrow.layoutParams
- as ViewGroup.MarginLayoutParams
-
- arrowParams.setMargins(
- spotlightTarget.anchorLeft.toInt(),
- (spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
- 10.dp,
- 10.dp
- )
-
- (overlayBinding as TopLeftOverlayBinding).arrow.layoutParams = arrowParams
-
- return (overlayBinding as TopLeftOverlayBinding).root
- }
-
private val Int.dp: Int
get() = (this * Resources.getSystem().displayMetrics.density + 0.5f).toInt()
}
From f863226d5ff0b94bf9bbc2b68a3470d98ec6d733 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sat, 12 Nov 2022 03:10:39 +0530
Subject: [PATCH 067/138] fully configure rtl compatibility + add onboarding
spotlights
---
.../onboarding/OnboardingActivityPresenter.kt | 13 ++++++++
.../app/onboarding/OnboardingFragment.kt | 6 ++++
.../onboarding/OnboardingFragmentPresenter.kt | 31 +++++++++++++++++++
.../app/spotlight/SpotlightFragment.kt | 11 ++++---
.../main/res/layout/bottom_right_overlay.xml | 1 +
.../main/res/layout/onboarding_activity.xml | 16 ++++++++--
6 files changed, 70 insertions(+), 8 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
index abbe74efc5b..b6f1bca47ec 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
@@ -1,9 +1,13 @@
package org.oppia.android.app.onboarding
+import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
import javax.inject.Inject
+import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
+import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
/** The presenter for [OnboardingActivity]. */
@ActivityScope
@@ -16,6 +20,15 @@ class OnboardingActivityPresenter @Inject constructor(private val activity: AppC
OnboardingFragment()
).commitNow()
}
+
+ val spotlightFragment = SpotlightFragment()
+ val args = Bundle()
+ args.putInt(PROFILE_ID_ARGUMENT_KEY, 0)
+ spotlightFragment.arguments = args
+ activity.supportFragmentManager.beginTransaction().add(
+ R.id.onboarding_spotlight_fragment_placeholder,
+ spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
+ ).commitNow()
}
private fun getOnboardingFragment(): OnboardingFragment? {
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
index 081abae41ee..5bd56cb3874 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
@@ -8,6 +8,7 @@ import android.view.ViewGroup
import org.oppia.android.app.fragment.FragmentComponentImpl
import org.oppia.android.app.fragment.InjectableFragment
import javax.inject.Inject
+import org.oppia.android.app.spotlight.SpotlightTarget
/** Fragment that contains an onboarding flow of the app. */
class OnboardingFragment : InjectableFragment() {
@@ -26,4 +27,9 @@ class OnboardingFragment : InjectableFragment() {
): View? {
return onboardingFragmentPresenter.handleCreateView(inflater, container)
}
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ onboardingFragmentPresenter.startSpotlights()
+ }
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index 4fc99927934..e571d6eff18 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -22,6 +22,11 @@ import org.oppia.android.util.parser.html.HtmlParser
import org.oppia.android.util.parser.html.PolicyType
import org.oppia.android.util.statusbar.StatusBarColor
import javax.inject.Inject
+import org.oppia.android.app.model.Spotlight
+import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightShape
+import org.oppia.android.app.spotlight.SpotlightTarget
+import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
/** The presenter for [OnboardingFragment]. */
@FragmentScope
@@ -55,6 +60,32 @@ class OnboardingFragmentPresenter @Inject constructor(
return binding.root
}
+ private fun getSpotlightFragment(): SpotlightFragment {
+ return activity.supportFragmentManager.findFragmentByTag(
+ SPOTLIGHT_FRAGMENT_TAG
+ ) as SpotlightFragment
+ }
+
+
+ fun startSpotlights() {
+ val skipSpotlightTarget = SpotlightTarget(
+ binding.skipTextView,
+ "Skip",
+ SpotlightShape.Circle,
+ Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON
+ )
+
+ val nextSpotlightTarget = SpotlightTarget(
+ binding.onboardingFragmentNextImageView,
+ "next",
+ SpotlightShape.Circle,
+ Spotlight.FeatureCase.PROMOTED_STORIES
+ )
+
+ getSpotlightFragment().requestSpotlightViewWithDelayedLayout(skipSpotlightTarget)
+ getSpotlightFragment().requestSpotlightViewWithDelayedLayout(nextSpotlightTarget)
+ }
+
private fun setUpViewPager() {
val onboardingViewPagerBindableAdapter = createViewPagerAdapter()
onboardingViewPagerBindableAdapter.setData(
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index ca80cd8fe5d..595eddb5a0a 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -276,7 +276,8 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
configureTopLeftOverlay(spotlightTarget)
} else {
configureTopRightOverlay(spotlightTarget)
- } }
+ }
+ }
AnchorPosition.BottomRight -> {
if (isRTL) {
configureBottomLeftOverlay(spotlightTarget)
@@ -285,7 +286,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
}
}
AnchorPosition.BottomLeft -> {
- if (false) {
+ if (isRTL) {
configureBottomRightOverlay(spotlightTarget)
} else {
configureBottomLeftOverlay(spotlightTarget)
@@ -357,10 +358,10 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
as ViewGroup.MarginLayoutParams
if (isRTL) {
arrowParams.setMargins(
- screenWidth -
- (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
- (spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
10.dp,
+ (spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
+ screenWidth -
+ (spotlightTarget.anchorLeft + getArrowWidth()).toInt(),
10.dp
)
} else {
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index 76cfd4c09f3..00716c42c12 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -24,6 +24,7 @@
android:layout_width="@dimen/arrow_width"
android:layout_height="@dimen/arrow_height"
android:rotationX="180"
+ android:rotationY="180"
android:src="@drawable/ic_rounded_arrow_up_right"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
diff --git a/app/src/main/res/layout/onboarding_activity.xml b/app/src/main/res/layout/onboarding_activity.xml
index a62631c63a3..4171e157e2f 100644
--- a/app/src/main/res/layout/onboarding_activity.xml
+++ b/app/src/main/res/layout/onboarding_activity.xml
@@ -1,7 +1,17 @@
-
+ tools:context="app.onboarding.OnboardingActivity">
+
+
+
+
+
From af177129dd9dad7399d60b4876d24ad8c1363b80 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sun, 13 Nov 2022 00:12:43 +0530
Subject: [PATCH 068/138] partial: add home activity and topic activity tests
for spotlight.
---
.../app/topic/TopicFragmentPresenter.kt | 4 +-
app/src/main/res/values/strings.xml | 2 +
.../android/app/home/HomeActivityTest.kt | 15 +++--
.../android/app/topic/TopicActivityTest.kt | 57 ++++++++++++++++++-
4 files changed, 68 insertions(+), 10 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index ba05439a3d4..22b1f4b4b48 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -81,7 +81,7 @@ class TopicFragmentPresenter @Inject constructor(
lessonsTabView?.let { lessonsTabView ->
val lessonsTabSpotlightTarget = SpotlightTarget(
lessonsTabView,
- "Find all your lessons here",
+ resourceHandler.getStringInLocale(R.string.topic_lessons_tab_spotlight_hint),
SpotlightShape.RoundedRectangle,
Spotlight.FeatureCase.TOPIC_LESSON_TAB
)
@@ -91,7 +91,7 @@ class TopicFragmentPresenter @Inject constructor(
val revisionTabView = tabLayout.getTabAt(computeTabPosition(TopicTab.REVISION))?.view
val revisionTabSpotlightTarget = SpotlightTarget(
revisionTabView!!,
- "Revise your lessons here",
+ resourceHandler.getStringInLocale(R.string.topic_revision_tab_spotlight_hint),
SpotlightShape.RoundedRectangle,
Spotlight.FeatureCase.TOPIC_REVISION_TAB
)
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8068a746071..2fadb2786a6 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -579,4 +579,6 @@
After completing a lesson, revise your concepts in the revision tab.
Practice tab
Start learning here in the lessons tab.
+ Find all your lessons here
+ Revise your lessons here
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
index f368580e5d3..b182d58565c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
@@ -144,6 +144,7 @@ import org.robolectric.annotation.LooperMode
import java.util.Locale
import javax.inject.Inject
import javax.inject.Singleton
+import org.oppia.android.testing.DisableAccessibilityChecks
// Time: Tue Apr 23 2019 23:22:00
private const val EVENING_TIMESTAMP = 1556061720000
@@ -336,18 +337,20 @@ class HomeActivityTest {
}
}
+ @DisableAccessibilityChecks
@Test
fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_spotlightAlreadySeenBefore_checkSpotlightIsNotShown() {
- logIntoUserTwice()
- launch(createHomeActivityIntent(internalProfileId1)).use {
- testCoroutineDispatchers.runCurrent()
- }
-
+ dataProviderTestMonitor.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
dataProviderTestMonitor.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
launch(createHomeActivityIntent(internalProfileId1)).use {
testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.close_target)).perform(click())
+ testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.custom_text)).check(doesNotExist())
+ it.recreate().use {
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.custom_text)).check(doesNotExist())
+ }
}
}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
index da5075c8edb..b463a22dd4d 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
@@ -8,6 +8,7 @@ import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
+import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions.scrollToPosition
import androidx.test.espresso.intent.Intents
@@ -20,6 +21,8 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import dagger.Component
+import javax.inject.Inject
+import javax.inject.Singleton
import org.junit.After
import org.junit.Before
import org.junit.Rule
@@ -101,8 +104,6 @@ import org.oppia.android.util.parser.image.GlideImageLoaderModule
import org.oppia.android.util.parser.image.ImageParsingModule
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
-import javax.inject.Inject
-import javax.inject.Singleton
/** Tests for [TopicActivity]. */
@RunWith(AndroidJUnit4::class)
@@ -168,6 +169,58 @@ class TopicActivityTest {
}
}
+ @Test
+ fun testLessonsTabSpotlight_setToShowOnFirstLogin_spotlightNeverSeenBefore_checkSpotlightShown() {
+ TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
+ launchTopicActivity(internalProfileId, FRACTIONS_TOPIC_ID).use {
+ onView(withId(R.id.custom_text)).check(matches(isDisplayed()))
+ onView(withId(R.id.custom_text)).check(
+ matches(
+ withText(
+ context.getString(R.string.topic_lessons_tab_spotlight_hint)
+ )
+ )
+ )
+ }
+ }
+
+ @Test
+ fun testLessonsTabSpotlight_spotlightAlreadySeen_checkSpotlightNotShown() {
+ TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
+ launchTopicActivity(internalProfileId, FRACTIONS_TOPIC_ID).use {
+
+ }
+ launchTopicActivity(internalProfileId, FRACTIONS_TOPIC_ID).use {
+ onView(withText(context.getString(R.string.topic_lessons_tab_spotlight_hint))).check(
+ doesNotExist()
+ )
+ }
+ }
+
+ @Test
+ fun testFirstChapterSpotlight_setToShowOnFirstLogin_checkSpotlightShown() {
+ TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
+ launchTopicActivity(internalProfileId, FRACTIONS_TOPIC_ID).use {
+ testCoroutineDispatchers.runCurrent()
+
+ // finish lessons tab spotlight first
+ onView(withId(R.id.close_target)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.custom_text)).check(
+ matches(
+ withText(
+ context.getString(R.string.topic_lessons_tab_spotlight_hint)
+ )
+ )
+ )
+ }
+ }
+
+ @Test
+ fun testFirstChapterSpotlight_spotlightAlreadySeen_checkSpotlightNotShown() {
+
+ }
+
@Test
@RunOn(TestPlatform.ROBOLECTRIC) // TODO(#3858): Enable for Espresso.
fun testTopicActivity_startPracticeSession_questionActivityStartedWithProfileId() {
From 130f781ac709fc7db02a5e77caf06fc955f09131 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 14 Nov 2022 00:25:24 +0530
Subject: [PATCH 069/138] spotlight voice-over icon after 3 logins
---
.../ExplorationFragmentPresenter.kt | 95 ++++++-------------
1 file changed, 27 insertions(+), 68 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index 2cf92c69662..bdedd9a015a 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -8,15 +8,12 @@ import android.widget.ImageButton
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.forEach
import androidx.fragment.app.Fragment
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.Transformations
+import javax.inject.Inject
import kotlinx.android.synthetic.main.exploration_activity.*
import kotlinx.android.synthetic.main.exploration_activity.view.*
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.ExplorationFragmentArguments
-import org.oppia.android.app.model.ProfileId
-import org.oppia.android.app.model.PromotedActivityList
import org.oppia.android.app.model.ReadingTextSize
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.player.state.StateFragment
@@ -33,7 +30,6 @@ import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.extensions.getProto
import org.oppia.android.util.extensions.putProto
-import javax.inject.Inject
/** The presenter for [ExplorationFragment]. */
@FragmentScope
@@ -86,41 +82,36 @@ class ExplorationFragmentPresenter @Inject constructor(
// sp can be correctly recomputed.
fragment.requireActivity().recreate()
} else {
- showSpotlights()
+ if (result is AsyncResult.Success) {
+ showSpotlights(result.value.numberOfLogins)
+ }
}
}
}
- private fun showSpotlights() {
- numberOfChaptersCompletedLiveData.observe(fragment) { numberOfChaptersCompleted ->
- if (numberOfChaptersCompleted != -1) {
- val explorationToolbar =
- (fragment.requireActivity() as AppCompatActivity).exploration_toolbar
- explorationToolbar.forEach {
- if (it is ImageButton) {
- // this toolbar contains only one image button, which is the back navigation icon
-
- val backButtonSpotlightTarget = SpotlightTarget(
- it,
- "Exit anytime using this button. We will save your progress.",
- SpotlightShape.Circle,
- Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
- )
- getSpotlightFragment().requestSpotlight(backButtonSpotlightTarget)
-
- if (
- numberOfChaptersCompleted >= 1 &&
- explorationToolbar.action_audio_player.visibility == View.VISIBLE
- ) {
- val audioPlayerSpotlightTarget = SpotlightTarget(
- explorationToolbar.action_audio_player,
- "Would you like Oppia to read for you? Tap on this button to try!",
- SpotlightShape.Circle,
- Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
- )
- getSpotlightFragment().requestSpotlight(audioPlayerSpotlightTarget)
- }
- }
+ private fun showSpotlights(numberOfLogins: Int) {
+ val explorationToolbar =
+ (fragment.requireActivity() as AppCompatActivity).exploration_toolbar
+ explorationToolbar.forEach {
+ if (it is ImageButton) {
+ // this toolbar contains only one image button, which is the back navigation icon
+ val backButtonSpotlightTarget = SpotlightTarget(
+ it,
+ fragment.requireContext().getString(R.string.exploration_exit_button_spotlight_hint),
+ SpotlightShape.Circle,
+ Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
+ )
+ getSpotlightFragment().requestSpotlight(backButtonSpotlightTarget)
+
+ // spotlight voice-over icon after 3 logins
+ if (numberOfLogins >= 3) {
+ val audioPlayerSpotlightTarget = SpotlightTarget(
+ explorationToolbar.action_audio_player,
+ "Would you like Oppia to read for you? Tap on this button to try!",
+ SpotlightShape.Circle,
+ Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
+ )
+ getSpotlightFragment().requestSpotlight(audioPlayerSpotlightTarget)
}
}
}
@@ -132,38 +123,6 @@ class ExplorationFragmentPresenter @Inject constructor(
) as SpotlightFragment
}
- private val topicListResultLiveData: LiveData> by lazy {
- topicListController.getPromotedActivityList(
- ProfileId.newBuilder().setInternalId(internalProfileId).build()
- ).toLiveData()
- }
-
- private val numberOfChaptersCompletedLiveData: LiveData by lazy {
- Transformations.map(topicListResultLiveData, ::computeNumberOfChaptersCompleted)
- }
-
- private fun computeNumberOfChaptersCompleted(
- topicListResult: AsyncResult
- ): Int {
- return when (topicListResult) {
- is AsyncResult.Failure -> -1
- is AsyncResult.Pending -> -1
- is AsyncResult.Success -> {
- var numberOfChaptersCompleted = 0
- topicListResult.value.promotedStoryList.recentlyPlayedStoryList.forEach {
- numberOfChaptersCompleted += it.completedChapterCount
- }
- topicListResult.value.promotedStoryList.suggestedStoryList.forEach {
- numberOfChaptersCompleted += it.completedChapterCount
- }
- topicListResult.value.promotedStoryList.olderPlayedStoryList.forEach {
- numberOfChaptersCompleted += it.completedChapterCount
- }
- numberOfChaptersCompleted
- }
- }
- }
-
fun handlePlayAudio() {
getStateFragment()?.handlePlayAudio()
}
From 4b64b1ce74dfad47107dbb736fe21c390dee0a42 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 14 Nov 2022 00:57:19 +0530
Subject: [PATCH 070/138] add tests to check spotlight is shown
---
...pterNotStartedContainerConstraintLayout.kt | 3 +-
.../app/customview/PromotedStoryCardView.kt | 3 +-
.../app/onboarding/OnboardingFragment.kt | 3 +-
.../onboarding/OnboardingFragmentPresenter.kt | 15 ++-----
.../player/audio/AudioFragmentPresenter.kt | 2 +-
.../ExplorationFragmentPresenter.kt | 2 +-
app/src/main/res/values/strings.xml | 6 +++
.../android/app/home/HomeActivityTest.kt | 34 +++++++-------
.../app/onboarding/OnboardingFragmentTest.kt | 7 +++
.../app/player/audio/AudioFragmentTest.kt | 13 ++++++
.../android/app/topic/TopicActivityTest.kt | 31 ++++++-------
.../topic/lessons/TopicLessonsFragmentTest.kt | 29 +++++++++++-
.../player/state/StateFragmentLocalTest.kt | 44 +++++++++++++++++++
13 files changed, 137 insertions(+), 55 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index 8b581c8eafd..40e93c8fc9a 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -6,6 +6,7 @@ import androidx.constraintlayout.widget.ConstraintLayout
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import javax.inject.Inject
+import org.oppia.android.R
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightTarget
@@ -50,7 +51,7 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
isSpotlit = true
val spotlightTarget = SpotlightTarget(
this,
- "Tap to start a chapter",
+ context.getString(R.string.first_chapter_spotlight_hint),
feature = Spotlight.FeatureCase.FIRST_CHAPTER
)
getSpotlightFragment().requestSpotlightOnFirstRecyclerItem(this, index, spotlightTarget)
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
index a70bbb132f4..38b992e1f16 100644
--- a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -10,6 +10,7 @@ import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
import javax.inject.Inject
+import org.oppia.android.R
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightTarget
@@ -41,7 +42,7 @@ class PromotedStoryCardView @JvmOverloads constructor(
isSpotlit = true
val spotlightTarget = SpotlightTarget(
this,
- "From now, you can see stories recommended for you here",
+ context.getString(R.string.promoted_story_spotlight_hint),
feature = Spotlight.FeatureCase.PROMOTED_STORIES
)
getSpotlightFragment().requestSpotlightOnFirstRecyclerItem(this, index, spotlightTarget)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
index 5bd56cb3874..64dc76f9fac 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
@@ -8,7 +8,6 @@ import android.view.ViewGroup
import org.oppia.android.app.fragment.FragmentComponentImpl
import org.oppia.android.app.fragment.InjectableFragment
import javax.inject.Inject
-import org.oppia.android.app.spotlight.SpotlightTarget
/** Fragment that contains an onboarding flow of the app. */
class OnboardingFragment : InjectableFragment() {
@@ -30,6 +29,6 @@ class OnboardingFragment : InjectableFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- onboardingFragmentPresenter.startSpotlights()
+ onboardingFragmentPresenter.startSpotlight()
}
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index e571d6eff18..48e0fbb893f 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -67,22 +67,13 @@ class OnboardingFragmentPresenter @Inject constructor(
}
- fun startSpotlights() {
- val skipSpotlightTarget = SpotlightTarget(
- binding.skipTextView,
- "Skip",
- SpotlightShape.Circle,
- Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON
- )
-
+ fun startSpotlight() {
val nextSpotlightTarget = SpotlightTarget(
binding.onboardingFragmentNextImageView,
- "next",
+ fragment.requireContext().getString(R.string.onboarding_next_button_spotlight_hint),
SpotlightShape.Circle,
- Spotlight.FeatureCase.PROMOTED_STORIES
+ Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON
)
-
- getSpotlightFragment().requestSpotlightViewWithDelayedLayout(skipSpotlightTarget)
getSpotlightFragment().requestSpotlightViewWithDelayedLayout(nextSpotlightTarget)
}
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index 83413c8ec39..38c955e6496 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -132,7 +132,7 @@ class AudioFragmentPresenter @Inject constructor(
private fun startSpotlights() {
val audioLanguageIconSpotlightTarget = SpotlightTarget(
binding.audioLanguageIcon,
- "Tap to change",
+ context.getString(R.string.voiceover_language_icon_spotlight_hint),
SpotlightShape.Circle,
Spotlight.FeatureCase.VOICEOVER_LANGUAGE_ICON
)
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index bdedd9a015a..67d533210c7 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -107,7 +107,7 @@ class ExplorationFragmentPresenter @Inject constructor(
if (numberOfLogins >= 3) {
val audioPlayerSpotlightTarget = SpotlightTarget(
explorationToolbar.action_audio_player,
- "Would you like Oppia to read for you? Tap on this button to try!",
+ fragment.requireContext().getString(R.string.voiceover_icon_spotlight_hint),
SpotlightShape.Circle,
Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
)
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2fadb2786a6..cc09fc7632d 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -581,4 +581,10 @@
Start learning here in the lessons tab.
Find all your lessons here
Revise your lessons here
+ Tap to start a chapter
+ Exit anytime using this button. We will save your progress.
+ Would you like Oppia to read for you? Tap on this button to try!
+ Tap to change voiceover language
+ Next
+ From now, you can see stories recommended for you here
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
index b182d58565c..8282b6cfe9e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
@@ -330,29 +330,29 @@ class HomeActivityTest {
onView(withId(R.id.custom_text)).check(
matches(
withText(
- "From now, here you can view stories you might be interested in"
+ R.string.promoted_story_spotlight_hint
)
)
)
}
}
- @DisableAccessibilityChecks
- @Test
- fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_spotlightAlreadySeenBefore_checkSpotlightIsNotShown() {
- dataProviderTestMonitor.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
- dataProviderTestMonitor.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
- launch(createHomeActivityIntent(internalProfileId1)).use {
- testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.close_target)).perform(click())
- testCoroutineDispatchers.runCurrent()
-
- it.recreate().use {
- testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.custom_text)).check(doesNotExist())
- }
- }
- }
+// @DisableAccessibilityChecks
+// @Test
+// fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_spotlightAlreadySeenBefore_checkSpotlightIsNotShown() {
+// dataProviderTestMonitor.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
+// dataProviderTestMonitor.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
+// launch(createHomeActivityIntent(internalProfileId1)).use {
+// testCoroutineDispatchers.runCurrent()
+// onView(withId(R.id.close_target)).perform(click())
+// testCoroutineDispatchers.runCurrent()
+//
+// it.recreate().use {
+// testCoroutineDispatchers.runCurrent()
+// onView(withId(R.id.custom_text)).check(doesNotExist())
+// }
+// }
+// }
@Test
fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_checkNotShownOnFirstLogin() {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
index 9116a556f27..903ba33f6a3 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
@@ -173,6 +173,13 @@ class OnboardingFragmentTest {
}
}
+ @Test
+ fun testNextButtonSpotlight_setToShowOnStartup_neverSeenBefore_checkSpotlightIsShown() {
+ launch(OnboardingActivity::class.java).use {
+ onView(withText(R.string.onboarding_next_button_spotlight_hint)).check(matches(isDisplayed()))
+ }
+ }
+
@Test
fun testOnboardingFragment_checkDefaultSlideDescription_isCorrect() {
launch(OnboardingActivity::class.java).use {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt
index f45fb12cb31..c1a20db54ff 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt
@@ -197,6 +197,19 @@ class AudioFragmentTest {
}
}
+ @Test
+ fun testVoiceoverLangIconSpotlight_setToShowOnIconClick_neverSeenBefore_checkSpotlightIsShown() {
+ addMediaInfo()
+ launch(
+ createAudioFragmentTestIntent(
+ internalProfileId
+ )
+ ).use {
+ testCoroutineDispatchers.runCurrent()
+ onView(withText(R.string.voiceover_language_icon_spotlight_hint)).check(matches(isDisplayed()))
+ }
+ }
+
@Test
fun testAudioFragment_languageIcon_hasContentDescription() {
addMediaInfo()
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
index b463a22dd4d..b3fa91ed96a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
@@ -184,18 +184,18 @@ class TopicActivityTest {
}
}
- @Test
- fun testLessonsTabSpotlight_spotlightAlreadySeen_checkSpotlightNotShown() {
- TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
- launchTopicActivity(internalProfileId, FRACTIONS_TOPIC_ID).use {
-
- }
- launchTopicActivity(internalProfileId, FRACTIONS_TOPIC_ID).use {
- onView(withText(context.getString(R.string.topic_lessons_tab_spotlight_hint))).check(
- doesNotExist()
- )
- }
- }
+// @Test
+// fun testLessonsTabSpotlight_spotlightAlreadySeen_checkSpotlightNotShown() {
+// TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
+// launchTopicActivity(internalProfileId, FRACTIONS_TOPIC_ID).use {
+//
+// }
+// launchTopicActivity(internalProfileId, FRACTIONS_TOPIC_ID).use {
+// onView(withText(context.getString(R.string.topic_lessons_tab_spotlight_hint))).check(
+// doesNotExist()
+// )
+// }
+// }
@Test
fun testFirstChapterSpotlight_setToShowOnFirstLogin_checkSpotlightShown() {
@@ -209,18 +209,13 @@ class TopicActivityTest {
onView(withId(R.id.custom_text)).check(
matches(
withText(
- context.getString(R.string.topic_lessons_tab_spotlight_hint)
+ context.getString(R.string.first_chapter_spotlight_hint)
)
)
)
}
}
- @Test
- fun testFirstChapterSpotlight_spotlightAlreadySeen_checkSpotlightNotShown() {
-
- }
-
@Test
@RunOn(TestPlatform.ROBOLECTRIC) // TODO(#3858): Enable for Espresso.
fun testTopicActivity_startPracticeSession_questionActivityStartedWithProfileId() {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
index d01401649b9..250e169403f 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
@@ -28,6 +28,8 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.protobuf.MessageLite
import dagger.Component
+import javax.inject.Inject
+import javax.inject.Singleton
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.hamcrest.Matchers.allOf
@@ -134,8 +136,6 @@ import org.oppia.android.util.platformparameter.EnableExtraTopicTabsUi
import org.oppia.android.util.platformparameter.PlatformParameterValue
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
-import javax.inject.Inject
-import javax.inject.Singleton
/** Tests for [TopicLessonsFragment]. */
@RunWith(AndroidJUnit4::class)
@@ -209,6 +209,31 @@ class TopicLessonsFragmentTest {
}
}
+ @Test
+ fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_notSeenBefore_checkIsShown() {
+ TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
+ storyProgressTestHelper.markCompletedRatiosTopic(profileId, false)
+ launch(createTopicActivityIntent(internalProfileId, RATIOS_TOPIC_ID)).use {
+ // mark lessons spotlight seen
+ onView(withId(R.id.close_target)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+
+ onView(withText(R.string.topic_revision_tab_spotlight_hint)).check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_chaptersNotComplete_checkIsNotShown() {
+ TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
+ launch(createTopicActivityIntent(internalProfileId, RATIOS_TOPIC_ID)).use {
+ // mark lessons spotlight seen
+ onView(withId(R.id.close_target)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+
+ onView(withText(R.string.topic_revision_tab_spotlight_hint)).check(matches(not(isDisplayed())))
+ }
+ }
+
@Test
fun testLessonsPlayFragment_loadRatiosTopic_completeStoryProgress_isDisplayed() {
storyProgressTestHelper.markCompletedRatiosStory0(
diff --git a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
index 40c10395201..73181e323e3 100644
--- a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
@@ -167,6 +167,7 @@ import java.util.Locale
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Singleton
+import org.oppia.android.testing.story.StoryProgressTestHelper
/**
* Tests for [StateFragment] that can only be run locally, e.g. using Robolectric, and not on an
@@ -214,6 +215,9 @@ class StateFragmentLocalTest {
@Inject
lateinit var fakeAccessibilityService: FakeAccessibilityService
+ @Inject
+ lateinit var storyProgressTestHelper: StoryProgressTestHelper
+
private val profileId = ProfileId.newBuilder().apply { internalId = 1 }.build()
private val solutionIndex: Int = 4
@@ -283,6 +287,40 @@ class StateFragmentLocalTest {
}
}
+ @Test
+ fun testBackButtonSpotlight_setToShowOnFirstLogin_neverSeenBefore_checkSpotlightIsShown() {
+ launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {
+ startPlayingExploration()
+
+ onView(withText(R.string.exploration_exit_button_spotlight_hint)).check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testVoiceoverIconSpotlight_setToShowOn3rdLoginChapterComplete_neverSeenBefore_checkSpotlightIsShown() {
+ logIntoUserThrice()
+ launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {
+ startPlayingExploration()
+ // mark exit button spotlight seen
+ onView(withId(R.id.close_target)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+
+ onView(withText(R.string.voiceover_icon_spotlight_hint)).check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testVoiceoverIconSpotlight_setToShowOn3rdLoginChapterComplete_1stLogin_checkSpotlightIsNotShown() {
+ launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {
+ startPlayingExploration()
+ // mark exit button spotlight seen
+ onView(withId(R.id.close_target)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+
+ onView(withText(R.string.voiceover_icon_spotlight_hint)).check(matches(not(isDisplayed())))
+ }
+ }
+
@Test
fun testStateFragment_nextState_wait10seconds_noHintAvailable() {
launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {
@@ -2313,6 +2351,12 @@ class StateFragmentLocalTest {
Locale.setDefault(locale)
}
+ private fun logIntoUserThrice() {
+ monitorFactory.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
+ monitorFactory.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
+ monitorFactory.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
+ }
+
/**
* Returns a [ViewAssertion] that can be used to check the specified matcher applies the specified
* number of times for children against the view under test. If the count does not exactly match,
From 0836a2208bf3cceb42e4d1625c7c5a8820661b4a Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 14 Nov 2022 03:15:02 +0530
Subject: [PATCH 071/138] problem with tests
---
.../android/app/topic/TopicActivityTest.kt | 48 +------------------
.../android/app/topic/TopicFragmentTest.kt | 41 +++++++++++-----
2 files changed, 29 insertions(+), 60 deletions(-)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
index b3fa91ed96a..18292803051 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
@@ -169,53 +169,6 @@ class TopicActivityTest {
}
}
- @Test
- fun testLessonsTabSpotlight_setToShowOnFirstLogin_spotlightNeverSeenBefore_checkSpotlightShown() {
- TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
- launchTopicActivity(internalProfileId, FRACTIONS_TOPIC_ID).use {
- onView(withId(R.id.custom_text)).check(matches(isDisplayed()))
- onView(withId(R.id.custom_text)).check(
- matches(
- withText(
- context.getString(R.string.topic_lessons_tab_spotlight_hint)
- )
- )
- )
- }
- }
-
-// @Test
-// fun testLessonsTabSpotlight_spotlightAlreadySeen_checkSpotlightNotShown() {
-// TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
-// launchTopicActivity(internalProfileId, FRACTIONS_TOPIC_ID).use {
-//
-// }
-// launchTopicActivity(internalProfileId, FRACTIONS_TOPIC_ID).use {
-// onView(withText(context.getString(R.string.topic_lessons_tab_spotlight_hint))).check(
-// doesNotExist()
-// )
-// }
-// }
-
- @Test
- fun testFirstChapterSpotlight_setToShowOnFirstLogin_checkSpotlightShown() {
- TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
- launchTopicActivity(internalProfileId, FRACTIONS_TOPIC_ID).use {
- testCoroutineDispatchers.runCurrent()
-
- // finish lessons tab spotlight first
- onView(withId(R.id.close_target)).perform(click())
- testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.custom_text)).check(
- matches(
- withText(
- context.getString(R.string.first_chapter_spotlight_hint)
- )
- )
- )
- }
- }
-
@Test
@RunOn(TestPlatform.ROBOLECTRIC) // TODO(#3858): Enable for Espresso.
fun testTopicActivity_startPracticeSession_questionActivityStartedWithProfileId() {
@@ -250,6 +203,7 @@ class TopicActivityTest {
)
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.topic_name_text_view)).check(matches(isDisplayed()))
+ testCoroutineDispatchers.runCurrent()
return scenario
}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
index 0b2761e378e..f0fda4dfa6d 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
@@ -16,6 +16,7 @@ import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.matcher.ViewMatchers.assertThat
+import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
import androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.isRoot
@@ -27,6 +28,9 @@ import androidx.test.rule.ActivityTestRule
import asia.ivity.android.marqueeview.MarqueeView
import com.google.common.truth.Truth.assertThat
import dagger.Component
+import javax.inject.Inject
+import javax.inject.Singleton
+import kotlinx.coroutines.delay
import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.CoreMatchers.instanceOf
import org.hamcrest.Matchers.allOf
@@ -84,6 +88,7 @@ import org.oppia.android.domain.topic.FRACTIONS_STORY_ID_0
import org.oppia.android.domain.topic.FRACTIONS_TOPIC_ID
import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule
+import org.oppia.android.testing.DisableAccessibilityChecks
import org.oppia.android.testing.OppiaTestRule
import org.oppia.android.testing.TestLogReportingModule
import org.oppia.android.testing.junit.InitializeDefaultLocaleRule
@@ -110,8 +115,6 @@ import org.oppia.android.util.platformparameter.EnableExtraTopicTabsUi
import org.oppia.android.util.platformparameter.PlatformParameterValue
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
-import javax.inject.Inject
-import javax.inject.Singleton
private const val INFO_TAB_POSITION = 0
private const val LESSON_TAB_POSITION = 1
@@ -169,8 +172,21 @@ class TopicFragmentTest {
}
}
+// @Test
+// fun testLessonsTabSpotlight_spotlightAlreadySeen_checkSpotlightNotShown() {
+// TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
+// launchTopicActivity(internalProfileId, FRACTIONS_TOPIC_ID).use {
+//
+// }
+// launchTopicActivity(internalProfileId, FRACTIONS_TOPIC_ID).use {
+// onView(withText(context.getString(R.string.topic_lessons_tab_spotlight_hint))).check(
+// doesNotExist()
+// )
+// }
+// }
+
@Test
- fun testTopicLessonTabSpotlight_spotlightNotSeenBefore_checkSpotlightIsShown() {
+ fun testFirstChapterSpotlight_setToShowOnFirstLogin_checkSpotlightShown() {
initializeApplicationComponent(false)
activityTestRule.launchActivity(
createTopicActivityIntent(
@@ -179,11 +195,17 @@ class TopicFragmentTest {
)
)
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.custom_text)).check(matches(withText("Find all your lessons here")))
+
+ // finish lessons tab spotlight first
+ onView(withText("Done")).perform(click())
+ testCoroutineDispatchers.runCurrent()
+ testCoroutineDispatchers.advanceUntilIdle()
+ onView(withId(R.id.custom_text)).check(matches(withText(R.string.first_chapter_spotlight_hint))
+ )
}
@Test
- fun testTopicLessonTabSpotlight_spotlightSeen_checkSpotlightIsNotShown() {
+ fun testTopicLessonTabSpotlight_spotlightNotSeenBefore_checkSpotlightIsShown() {
initializeApplicationComponent(false)
activityTestRule.launchActivity(
createTopicActivityIntent(
@@ -192,14 +214,7 @@ class TopicFragmentTest {
)
)
testCoroutineDispatchers.runCurrent()
- activityTestRule.launchActivity(
- createTopicActivityIntent(
- internalProfileId,
- FRACTIONS_TOPIC_ID
- )
- )
- testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.custom_text)).check(doesNotExist())
+ onView(withId(R.id.custom_text)).check(matches(withText(R.string.topic_lessons_tab_spotlight_hint)))
}
@Test
From 09caa0d5a0a646620749e7e68e230e796b0f0bfa Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 14 Nov 2022 03:57:07 +0530
Subject: [PATCH 072/138] add create functions for the spotlight fragments
---
...pterNotStartedContainerConstraintLayout.kt | 6 ++---
.../app/customview/PromotedStoryCardView.kt | 6 ++---
.../android/app/home/HomeActivityPresenter.kt | 24 +++++++++++------
.../onboarding/OnboardingActivityPresenter.kt | 26 +++++++++++++------
.../ExplorationActivityPresenter.kt | 8 ++++++
.../ExplorationFragmentPresenter.kt | 8 +++---
.../app/topic/TopicActivityPresenter.kt | 24 +++++++++++------
.../app/topic/TopicFragmentPresenter.kt | 8 +++---
8 files changed, 72 insertions(+), 38 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index 40e93c8fc9a..8d842765acc 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -33,10 +33,10 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
this.index = index
}
- private fun getSpotlightFragment(): SpotlightFragment {
+ private fun getSpotlightFragment(): SpotlightFragment? {
return fragment.requireActivity().supportFragmentManager.findFragmentByTag(
SPOTLIGHT_FRAGMENT_TAG
- ) as SpotlightFragment
+ ) as SpotlightFragment?
}
override fun onAttachedToWindow() {
@@ -54,7 +54,7 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
context.getString(R.string.first_chapter_spotlight_hint),
feature = Spotlight.FeatureCase.FIRST_CHAPTER
)
- getSpotlightFragment().requestSpotlightOnFirstRecyclerItem(this, index, spotlightTarget)
+ checkNotNull(getSpotlightFragment()).requestSpotlightOnFirstRecyclerItem(this, index, spotlightTarget)
}
}
}
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
index 38b992e1f16..8d8f0e36573 100644
--- a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -45,15 +45,15 @@ class PromotedStoryCardView @JvmOverloads constructor(
context.getString(R.string.promoted_story_spotlight_hint),
feature = Spotlight.FeatureCase.PROMOTED_STORIES
)
- getSpotlightFragment().requestSpotlightOnFirstRecyclerItem(this, index, spotlightTarget)
+ checkNotNull(getSpotlightFragment()).requestSpotlightOnFirstRecyclerItem(this, index, spotlightTarget)
}
}
- private fun getSpotlightFragment(): SpotlightFragment {
+ private fun getSpotlightFragment(): SpotlightFragment? {
return fragment.requireActivity().supportFragmentManager.findFragmentByTag(
SPOTLIGHT_FRAGMENT_TAG
- ) as SpotlightFragment
+ ) as SpotlightFragment?
}
override fun onAttachedToWindow() {
diff --git a/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
index ba3bddb9eb4..3673b81c988 100644
--- a/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
@@ -31,14 +31,16 @@ class HomeActivityPresenter @Inject constructor(private val activity: AppCompatA
).commitNow()
}
- val spotlightFragment = SpotlightFragment()
- val args = Bundle()
- args.putInt(PROFILE_ID_ARGUMENT_KEY, internalProfileId)
- spotlightFragment.arguments = args
- activity.supportFragmentManager.beginTransaction().add(
- R.id.home_spotlight_fragment_placeholder,
- spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
- ).commitNow()
+ if (getSpotlightFragment() == null) {
+ val spotlightFragment = SpotlightFragment()
+ val args = Bundle()
+ args.putInt(PROFILE_ID_ARGUMENT_KEY, internalProfileId)
+ spotlightFragment.arguments = args
+ activity.supportFragmentManager.beginTransaction().add(
+ R.id.home_spotlight_fragment_placeholder,
+ spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
+ ).commitNow()
+ }
}
fun handleOnRestart() {
@@ -63,4 +65,10 @@ class HomeActivityPresenter @Inject constructor(private val activity: AppCompatA
R.id.home_fragment_placeholder
) as HomeFragment?
}
+
+ private fun getSpotlightFragment(): SpotlightFragment? {
+ return activity.supportFragmentManager.findFragmentById(
+ R.id.home_spotlight_fragment_placeholder
+ ) as SpotlightFragment?
+ }
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
index b6f1bca47ec..3eb2c1c26d1 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
@@ -21,14 +21,16 @@ class OnboardingActivityPresenter @Inject constructor(private val activity: AppC
).commitNow()
}
- val spotlightFragment = SpotlightFragment()
- val args = Bundle()
- args.putInt(PROFILE_ID_ARGUMENT_KEY, 0)
- spotlightFragment.arguments = args
- activity.supportFragmentManager.beginTransaction().add(
- R.id.onboarding_spotlight_fragment_placeholder,
- spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
- ).commitNow()
+ if (getSpotlightFragment() == null) {
+ val spotlightFragment = SpotlightFragment()
+ val args = Bundle()
+ args.putInt(PROFILE_ID_ARGUMENT_KEY, 0)
+ spotlightFragment.arguments = args
+ activity.supportFragmentManager.beginTransaction().add(
+ R.id.onboarding_spotlight_fragment_placeholder,
+ spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
+ ).commitNow()
+ }
}
private fun getOnboardingFragment(): OnboardingFragment? {
@@ -38,4 +40,12 @@ class OnboardingActivityPresenter @Inject constructor(private val activity: AppC
R.id.onboarding_fragment_placeholder
) as OnboardingFragment?
}
+
+ private fun getSpotlightFragment(): SpotlightFragment? {
+ return activity
+ .supportFragmentManager
+ .findFragmentById(
+ R.id.onboarding_spotlight_fragment_placeholder
+ ) as SpotlightFragment?
+ }
}
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
index edbd12e1673..40c6a35ea4d 100644
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
@@ -127,7 +127,9 @@ class ExplorationActivityPresenter @Inject constructor(
ExplorationManagerFragment.createNewInstance(profileId),
TAG_EXPLORATION_MANAGER_FRAGMENT
).commitNow()
+ }
+ if (getSpotlightFragment() == null) {
val spotlightFragment = SpotlightFragment()
val args = Bundle()
args.putInt(PROFILE_ID_ARGUMENT_KEY, profileId.internalId)
@@ -139,6 +141,12 @@ class ExplorationActivityPresenter @Inject constructor(
}
}
+ private fun getSpotlightFragment(): SpotlightFragment? {
+ return activity.supportFragmentManager.findFragmentByTag(
+ SPOTLIGHT_FRAGMENT_TAG
+ ) as SpotlightFragment?
+ }
+
fun loadExplorationFragment(readingTextSize: ReadingTextSize) {
if (getExplorationFragment() == null) {
activity.supportFragmentManager.beginTransaction().add(
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index 67d533210c7..775a3aa985f 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -101,7 +101,7 @@ class ExplorationFragmentPresenter @Inject constructor(
SpotlightShape.Circle,
Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
)
- getSpotlightFragment().requestSpotlight(backButtonSpotlightTarget)
+ checkNotNull(getSpotlightFragment()).requestSpotlight(backButtonSpotlightTarget)
// spotlight voice-over icon after 3 logins
if (numberOfLogins >= 3) {
@@ -111,16 +111,16 @@ class ExplorationFragmentPresenter @Inject constructor(
SpotlightShape.Circle,
Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
)
- getSpotlightFragment().requestSpotlight(audioPlayerSpotlightTarget)
+ checkNotNull(getSpotlightFragment()).requestSpotlight(audioPlayerSpotlightTarget)
}
}
}
}
- private fun getSpotlightFragment(): SpotlightFragment {
+ private fun getSpotlightFragment(): SpotlightFragment? {
return fragment.requireActivity().supportFragmentManager.findFragmentByTag(
SPOTLIGHT_FRAGMENT_TAG
- ) as SpotlightFragment
+ ) as SpotlightFragment?
}
fun handlePlayAudio() {
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
index d1eb9844378..45cbfae3d22 100755
--- a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
@@ -40,14 +40,16 @@ class TopicActivityPresenter @Inject constructor(private val activity: AppCompat
).commitNow()
}
- val spotlightFragment = SpotlightFragment()
- val args = Bundle()
- args.putInt(PROFILE_ID_ARGUMENT_KEY, internalProfileId)
- spotlightFragment.arguments = args
- activity.supportFragmentManager.beginTransaction().add(
- R.id.topic_spotlight_fragment_placeholder,
- spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
- ).commitNow()
+ if (getSpotlightFragment() == null) {
+ val spotlightFragment = SpotlightFragment()
+ val args = Bundle()
+ args.putInt(PROFILE_ID_ARGUMENT_KEY, internalProfileId)
+ spotlightFragment.arguments = args
+ activity.supportFragmentManager.beginTransaction().add(
+ R.id.topic_spotlight_fragment_placeholder,
+ spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
+ ).commitNow()
+ }
}
private fun getTopicFragment(): TopicFragment? {
@@ -57,4 +59,10 @@ class TopicActivityPresenter @Inject constructor(private val activity: AppCompat
R.id.topic_fragment_placeholder
) as TopicFragment?
}
+
+ private fun getSpotlightFragment(): SpotlightFragment? {
+ return activity.supportFragmentManager.findFragmentByTag(
+ SPOTLIGHT_FRAGMENT_TAG
+ ) as SpotlightFragment?
+ }
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 22b1f4b4b48..d5fb91ffd63 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -85,7 +85,7 @@ class TopicFragmentPresenter @Inject constructor(
SpotlightShape.RoundedRectangle,
Spotlight.FeatureCase.TOPIC_LESSON_TAB
)
- getSpotlightFragment().requestSpotlight(lessonsTabSpotlightTarget)
+ checkNotNull(getSpotlightFragment()).requestSpotlight(lessonsTabSpotlightTarget)
if (numberOfChaptersCompleted > 2) {
val revisionTabView = tabLayout.getTabAt(computeTabPosition(TopicTab.REVISION))?.view
@@ -95,17 +95,17 @@ class TopicFragmentPresenter @Inject constructor(
SpotlightShape.RoundedRectangle,
Spotlight.FeatureCase.TOPIC_REVISION_TAB
)
- getSpotlightFragment().requestSpotlight(revisionTabSpotlightTarget)
+ checkNotNull(getSpotlightFragment()).requestSpotlight(revisionTabSpotlightTarget)
}
}
}
}
}
- private fun getSpotlightFragment(): SpotlightFragment {
+ private fun getSpotlightFragment(): SpotlightFragment? {
return activity.supportFragmentManager.findFragmentByTag(
SPOTLIGHT_FRAGMENT_TAG
- ) as SpotlightFragment
+ ) as SpotlightFragment?
}
private fun setCurrentTab(tab: TopicTab) {
From c4ea52df411c86b19d6ca25f24c3a064beb6893c Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 14 Nov 2022 04:06:24 +0530
Subject: [PATCH 073/138] commit review suggestions
---
.../exploration/ExplorationFragmentPresenter.kt | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index 775a3aa985f..cd70152c87e 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -9,8 +9,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.forEach
import androidx.fragment.app.Fragment
import javax.inject.Inject
-import kotlinx.android.synthetic.main.exploration_activity.*
-import kotlinx.android.synthetic.main.exploration_activity.view.*
+import kotlinx.android.synthetic.main.toolbar.*
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.ExplorationFragmentArguments
@@ -91,7 +90,7 @@ class ExplorationFragmentPresenter @Inject constructor(
private fun showSpotlights(numberOfLogins: Int) {
val explorationToolbar =
- (fragment.requireActivity() as AppCompatActivity).exploration_toolbar
+ fragment.requireActivity().toolbar
explorationToolbar.forEach {
if (it is ImageButton) {
// this toolbar contains only one image button, which is the back navigation icon
@@ -102,11 +101,11 @@ class ExplorationFragmentPresenter @Inject constructor(
Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
)
checkNotNull(getSpotlightFragment()).requestSpotlight(backButtonSpotlightTarget)
-
- // spotlight voice-over icon after 3 logins
- if (numberOfLogins >= 3) {
+ }
+ if (it.id == R.id.action_audio_player){
+ if (numberOfLogins >= 3) { // spotlight voice-over icon after 3 logins
val audioPlayerSpotlightTarget = SpotlightTarget(
- explorationToolbar.action_audio_player,
+ it,
fragment.requireContext().getString(R.string.voiceover_icon_spotlight_hint),
SpotlightShape.Circle,
Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
From 6f8b475924654f91e3dd677e220fb55c3f249679 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 14 Nov 2022 17:06:58 +0530
Subject: [PATCH 074/138] dont use synthetic
---
.../ExplorationFragmentPresenter.kt | 33 ++++++++++---------
1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index cd70152c87e..e41a87aa9f2 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -1,15 +1,15 @@
package org.oppia.android.app.player.exploration
import android.content.Context
+import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
-import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.Toolbar
import androidx.core.view.forEach
import androidx.fragment.app.Fragment
import javax.inject.Inject
-import kotlinx.android.synthetic.main.toolbar.*
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.ExplorationFragmentArguments
@@ -24,7 +24,6 @@ import org.oppia.android.app.utility.FontScaleConfigurationUtil
import org.oppia.android.databinding.ExplorationFragmentBinding
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.profile.ProfileManagementController
-import org.oppia.android.domain.topic.TopicListController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.extensions.getProto
@@ -37,7 +36,6 @@ class ExplorationFragmentPresenter @Inject constructor(
private val oppiaLogger: OppiaLogger,
private val fontScaleConfigurationUtil: FontScaleConfigurationUtil,
private val profileManagementController: ProfileManagementController,
- private val topicListController: TopicListController
) {
private var internalProfileId: Int = -1
@@ -89,8 +87,9 @@ class ExplorationFragmentPresenter @Inject constructor(
}
private fun showSpotlights(numberOfLogins: Int) {
+ Log.d("overlay", "login count: $numberOfLogins")
val explorationToolbar =
- fragment.requireActivity().toolbar
+ fragment.requireActivity().findViewById(R.id.exploration_toolbar) as Toolbar
explorationToolbar.forEach {
if (it is ImageButton) {
// this toolbar contains only one image button, which is the back navigation icon
@@ -102,17 +101,19 @@ class ExplorationFragmentPresenter @Inject constructor(
)
checkNotNull(getSpotlightFragment()).requestSpotlight(backButtonSpotlightTarget)
}
- if (it.id == R.id.action_audio_player){
- if (numberOfLogins >= 3) { // spotlight voice-over icon after 3 logins
- val audioPlayerSpotlightTarget = SpotlightTarget(
- it,
- fragment.requireContext().getString(R.string.voiceover_icon_spotlight_hint),
- SpotlightShape.Circle,
- Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
- )
- checkNotNull(getSpotlightFragment()).requestSpotlight(audioPlayerSpotlightTarget)
- }
- }
+ }
+
+ val voiceoverIcon = fragment.requireActivity().findViewById(R.id.action_audio_player)
+ if (numberOfLogins >= 3) { // spotlight voice-over icon after 3 logins
+ val audioPlayerSpotlightTarget = SpotlightTarget(
+ voiceoverIcon,
+ fragment.requireContext().getString(R.string.voiceover_icon_spotlight_hint),
+ SpotlightShape.Circle,
+ Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
+ )
+ checkNotNull(getSpotlightFragment()).requestSpotlightViewWithDelayedLayout(
+ audioPlayerSpotlightTarget
+ )
}
}
From f452f29ea4a512fa7449dc677ab1c6bb52a939f0 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 14 Nov 2022 17:38:11 +0530
Subject: [PATCH 075/138] make sure voiceover icon is visible as well
---
.../app/player/exploration/ExplorationFragmentPresenter.kt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index e41a87aa9f2..621307072b7 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -104,7 +104,8 @@ class ExplorationFragmentPresenter @Inject constructor(
}
val voiceoverIcon = fragment.requireActivity().findViewById(R.id.action_audio_player)
- if (numberOfLogins >= 3) { // spotlight voice-over icon after 3 logins
+ if (numberOfLogins >= 3 && voiceoverIcon.visibility == View.VISIBLE) {
+ // spotlight voice-over icon after 3 logins
val audioPlayerSpotlightTarget = SpotlightTarget(
voiceoverIcon,
fragment.requireContext().getString(R.string.voiceover_icon_spotlight_hint),
From dcee36c664852b1ff89d849e44aeb1addf0f5704 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 14 Nov 2022 20:42:42 +0530
Subject: [PATCH 076/138] add forced announcement for hints
---
.../android/app/player/state/StateFragmentPresenter.kt | 6 ++++++
1 file changed, 6 insertions(+)
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 1f9a6116436..31d668a8cff 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
@@ -1,6 +1,7 @@
package org.oppia.android.app.player.state
import android.content.Context
+import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -216,6 +217,7 @@ class StateFragmentPresenter @Inject constructor(
fun onHintAvailable(helpIndex: HelpIndex, isCurrentStatePendingState: Boolean) {
this.helpIndex = helpIndex
showHintsAndSolutions(helpIndex, isCurrentStatePendingState)
+
}
private fun createRecyclerViewAssembler(
@@ -462,6 +464,7 @@ 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)
@@ -495,6 +498,7 @@ class StateFragmentPresenter @Inject constructor(
private fun setHintOpenedAndUnRevealed(isHintUnrevealed: Boolean) {
viewModel.setHintOpenedAndUnRevealedVisibility(isHintUnrevealed)
if (isHintUnrevealed) {
+
val hintBulbAnimation = AnimationUtils.loadAnimation(
context,
R.anim.hint_bulb_animation
@@ -506,6 +510,8 @@ class StateFragmentPresenter @Inject constructor(
activity.runPeriodically(delayMillis = 5_000, periodMillis = 30_000) {
return@runPeriodically viewModel.isHintOpenedAndUnRevealed.get()!!.also { playAnim ->
if (playAnim) binding.hintBulb.startAnimation(hintBulbAnimation)
+ Log.d("hints", "announcement expected now")
+ binding.hintsAndSolutionFragmentContainer.announceForAccessibility("Go to the bottom of the screen for hint")
}
}
}
From fc0b20f71e8f582fe2dac1b3e460a326986c4272 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Mon, 14 Nov 2022 22:39:25 +0530
Subject: [PATCH 077/138] move test to another file
---
.../app/player/audio/AudioFragmentTest.kt | 13 ---------
.../exploration/ExplorationActivityTest.kt | 27 +++++++++++++++++++
2 files changed, 27 insertions(+), 13 deletions(-)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt
index c1a20db54ff..f45fb12cb31 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt
@@ -197,19 +197,6 @@ class AudioFragmentTest {
}
}
- @Test
- fun testVoiceoverLangIconSpotlight_setToShowOnIconClick_neverSeenBefore_checkSpotlightIsShown() {
- addMediaInfo()
- launch(
- createAudioFragmentTestIntent(
- internalProfileId
- )
- ).use {
- testCoroutineDispatchers.runCurrent()
- onView(withText(R.string.voiceover_language_icon_spotlight_hint)).check(matches(isDisplayed()))
- }
- }
-
@Test
fun testAudioFragment_languageIcon_hasContentDescription() {
addMediaInfo()
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
index 485226f4e34..cc88da97738 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
@@ -409,6 +409,33 @@ class ExplorationActivityTest {
explorationDataController.stopPlayingExploration(isCompletion = false)
}
+
+ @Test
+ fun testVoiceoverLangIconSpotlight_setToShowOnIconClick_neverSeenBefore_checkSpotlightIsShown() {
+ setUpAudioForFractionLesson()
+ launch(
+ createExplorationActivityIntent(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0,
+ shouldSavePartialProgress = false
+ )
+ ).use {
+ explorationDataController.startPlayingNewExploration(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0
+ )
+ networkConnectionUtil.setCurrentConnectionStatus(ProdConnectionStatus.LOCAL)
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.action_audio_player)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+ onView(withText(R.string.voiceover_language_icon_spotlight_hint)).check(matches(isDisplayed()))
+ }
+ }
+
@Test
fun testExploration_clickAudioIcon_contentDescription_changesCorrectly() {
setUpAudioForFractionLesson()
From be64cb995e8829dcf8f72bf040543878f07907e3 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Wed, 16 Nov 2022 18:40:36 +0530
Subject: [PATCH 078/138] add all tests for individual spotlights
---
.../android/app/home/HomeActivityTest.kt | 45 ++--
.../app/onboarding/OnboardingFragmentTest.kt | 7 +
.../exploration/ExplorationActivityTest.kt | 242 +++++++++++++++++-
.../android/app/topic/TopicFragmentTest.kt | 157 ++++++++++--
.../topic/lessons/TopicLessonsFragmentTest.kt | 33 +--
.../player/state/StateFragmentLocalTest.kt | 40 ---
6 files changed, 403 insertions(+), 121 deletions(-)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
index 8282b6cfe9e..fb4452ce6eb 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
@@ -321,44 +321,39 @@ class HomeActivityTest {
}
}
+ @DisableAccessibilityChecks
@Test
fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_spotlightNeverSeenBefore_checkSpotlightShown() {
logIntoUserTwice()
launch(createHomeActivityIntent(internalProfileId1)).use {
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.custom_text)).check(matches(isDisplayed()))
- onView(withId(R.id.custom_text)).check(
- matches(
- withText(
- R.string.promoted_story_spotlight_hint
- )
- )
- )
+ onView(withText(R.string.promoted_story_spotlight_hint)).check(matches(isDisplayed()))
}
}
-// @DisableAccessibilityChecks
-// @Test
-// fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_spotlightAlreadySeenBefore_checkSpotlightIsNotShown() {
-// dataProviderTestMonitor.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
-// dataProviderTestMonitor.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
-// launch(createHomeActivityIntent(internalProfileId1)).use {
-// testCoroutineDispatchers.runCurrent()
-// onView(withId(R.id.close_target)).perform(click())
-// testCoroutineDispatchers.runCurrent()
-//
-// it.recreate().use {
-// testCoroutineDispatchers.runCurrent()
-// onView(withId(R.id.custom_text)).check(doesNotExist())
-// }
-// }
-// }
+ @DisableAccessibilityChecks
+ @Test
+ fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_pressDone_checkSpotlightIsNotShownAgain() {
+ logIntoUserTwice()
+ launch(createHomeActivityIntent(internalProfileId1)).use {
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.close_target)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+ }
+
+ // re-launch the activity
+ launch(createHomeActivityIntent(internalProfileId1)).use {
+ testCoroutineDispatchers.runCurrent()
+ onView(withText(R.string.promoted_story_spotlight_hint)).check(doesNotExist())
+ }
+ }
+ @DisableAccessibilityChecks
@Test
fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_checkNotShownOnFirstLogin() {
launch(createHomeActivityIntent(internalProfileId1)).use {
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.custom_text)).check(doesNotExist())
+ onView(withText(R.string.promoted_story_spotlight_hint)).check(doesNotExist())
}
}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
index 903ba33f6a3..d1c8b1d2d20 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
@@ -229,6 +229,13 @@ class OnboardingFragmentTest {
}
}
+ @Test
+ fun testNextButtonSpotlight_setToShowOnStartup_checkSpotlightIsShown() {
+ launch(OnboardingActivity::class.java).use {
+ onView(withText(R.string.onboarding_next_button_spotlight_hint)).check(matches(isDisplayed()))
+ }
+ }
+
@Test
fun testOnboardingFragment_checkDefaultSlide_clickSkipButton_shiftsToLastSlide() {
launch(OnboardingActivity::class.java).use {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
index cc88da97738..2cd8500e790 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
@@ -46,6 +46,10 @@ import com.google.common.truth.Truth.assertThat
import dagger.Component
import dagger.Module
import dagger.Provides
+import java.io.IOException
+import java.util.concurrent.TimeoutException
+import javax.inject.Inject
+import javax.inject.Singleton
import org.hamcrest.BaseMatcher
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.containsString
@@ -76,6 +80,7 @@ import org.oppia.android.app.model.ExplorationActivityParams
import org.oppia.android.app.model.OppiaLanguage
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.ScreenName
+import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.model.WrittenTranslationLanguageSelection
import org.oppia.android.app.options.OptionsActivity
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -115,6 +120,7 @@ import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
+import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.domain.topic.FRACTIONS_EXPLORATION_ID_0
import org.oppia.android.domain.topic.FRACTIONS_EXPLORATION_ID_1
import org.oppia.android.domain.topic.FRACTIONS_STORY_ID_0
@@ -129,6 +135,7 @@ import org.oppia.android.domain.topic.TEST_TOPIC_ID_0
import org.oppia.android.domain.translation.TranslationController
import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule
import org.oppia.android.testing.BuildEnvironment
+import org.oppia.android.testing.DisableAccessibilityChecks
import org.oppia.android.testing.OppiaTestRule
import org.oppia.android.testing.RunOn
import org.oppia.android.testing.TestLogReportingModule
@@ -139,6 +146,7 @@ import org.oppia.android.testing.junit.InitializeDefaultLocaleRule
import org.oppia.android.testing.lightweightcheckpointing.ExplorationCheckpointTestHelper
import org.oppia.android.testing.lightweightcheckpointing.FRACTIONS_STORY_0_EXPLORATION_1_CURRENT_VERSION
import org.oppia.android.testing.lightweightcheckpointing.RATIOS_STORY_0_EXPLORATION_0_CURRENT_VERSION
+import org.oppia.android.testing.profile.ProfileTestHelper
import org.oppia.android.testing.robolectric.IsOnRobolectric
import org.oppia.android.testing.robolectric.RobolectricModule
import org.oppia.android.testing.threading.TestCoroutineDispatchers
@@ -165,10 +173,6 @@ import org.oppia.android.util.parser.image.GlideImageLoaderModule
import org.oppia.android.util.parser.image.ImageParsingModule
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
-import java.io.IOException
-import java.util.concurrent.TimeoutException
-import javax.inject.Inject
-import javax.inject.Singleton
/** Tests for [ExplorationActivity]. */
@RunWith(AndroidJUnit4::class)
@@ -177,6 +181,7 @@ import javax.inject.Singleton
application = ExplorationActivityTest.TestApplication::class,
qualifiers = "port-xxhdpi"
)
+
class ExplorationActivityTest {
@get:Rule
val initializeDefaultLocaleRule = InitializeDefaultLocaleRule()
@@ -187,6 +192,12 @@ class ExplorationActivityTest {
@Inject
lateinit var explorationCheckpointTestHelper: ExplorationCheckpointTestHelper
+ @Inject
+ lateinit var profileTestHelper: ProfileTestHelper
+
+ @Inject
+ lateinit var spotlightStateController: SpotlightStateController
+
@Inject
lateinit var explorationDataController: ExplorationDataController
@@ -221,6 +232,7 @@ class ExplorationActivityTest {
Intents.init()
setUpTestApplicationComponent()
testCoroutineDispatchers.registerIdlingResource()
+ profileTestHelper.initializeProfiles()
fakeOppiaClock.setFakeTimeMode(FakeOppiaClock.FakeTimeMode.MODE_UPTIME_MILLIS)
}
@@ -409,7 +421,6 @@ class ExplorationActivityTest {
explorationDataController.stopPlayingExploration(isCompletion = false)
}
-
@Test
fun testVoiceoverLangIconSpotlight_setToShowOnIconClick_neverSeenBefore_checkSpotlightIsShown() {
setUpAudioForFractionLesson()
@@ -436,6 +447,209 @@ class ExplorationActivityTest {
}
}
+ @Test
+ fun testVoiceoverLangIconSpotlight_setToShowOnIconClick_alreadySeen_checkSpotlightIsNotShown() {
+ setUpAudioForFractionLesson()
+ launch(
+ createExplorationActivityIntent(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0,
+ shouldSavePartialProgress = false
+ )
+ ).use {
+ explorationDataController.startPlayingNewExploration(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0
+ )
+ networkConnectionUtil.setCurrentConnectionStatus(ProdConnectionStatus.LOCAL)
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.action_audio_player)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.close_target)).perform(click())
+ }
+
+ launch(
+ createExplorationActivityIntent(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0,
+ shouldSavePartialProgress = false
+ )
+ ).use {
+ explorationDataController.startPlayingNewExploration(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0
+ )
+ networkConnectionUtil.setCurrentConnectionStatus(ProdConnectionStatus.LOCAL)
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.action_audio_player)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+ onView(withText(R.string.voiceover_language_icon_spotlight_hint)).check(doesNotExist())
+ }
+ }
+
+ @Test
+ fun testBackButtonSpotlight_setToShowOnFirstLogin_neverSeenBefore_checkSpotlightIsShown() {
+ launch(
+ createExplorationActivityIntent(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0,
+ shouldSavePartialProgress = false
+ )
+ ).use {
+ explorationDataController.startPlayingNewExploration(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0
+ )
+
+ onView(withText(R.string.exploration_exit_button_spotlight_hint)).check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testBackButtonSpotlight_setToShowOnFirstLogin_alreadySeen_checkSpotlightIsNotShown() {
+ markSpotlightSeen(Spotlight.FeatureCase.VOICEOVER_LANGUAGE_ICON)
+ launch(
+ createExplorationActivityIntent(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0,
+ shouldSavePartialProgress = false
+ )
+ ).use {
+ explorationDataController.startPlayingNewExploration(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0
+ )
+ onView(withId(R.id.close_target)).perform(click())
+ }
+
+ launch(
+ createExplorationActivityIntent(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0,
+ shouldSavePartialProgress = false
+ )
+ ).use {
+ explorationDataController.startPlayingNewExploration(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0
+ )
+ onView(withText(R.string.exploration_exit_button_spotlight_hint)).check(doesNotExist())
+ }
+ }
+
+ @Test
+ fun testVoiceoverIconSpotlight_setToShowOn3rdLoginChapterComplete_neverSeenBefore_checkSpotlightIsShown() {
+ logIntoUserThrice()
+ markSpotlightSeen(Spotlight.FeatureCase.LESSONS_BACK_BUTTON)
+ launch(
+ createExplorationActivityIntent(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0,
+ shouldSavePartialProgress = false
+ )
+ ).use {
+ explorationDataController.startPlayingNewExploration(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0
+ )
+ testCoroutineDispatchers.runCurrent()
+
+ onView(withText(R.string.voiceover_icon_spotlight_hint)).check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testVoiceoverIconSpotlight_setToShowOn3rdLoginChapterComplete_alreadySeen_checkSpotlightIsNotShown() {
+ logIntoUserThrice()
+ markSpotlightSeen(Spotlight.FeatureCase.LESSONS_BACK_BUTTON)
+ launch(
+ createExplorationActivityIntent(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0,
+ shouldSavePartialProgress = false
+ )
+ ).use {
+ explorationDataController.startPlayingNewExploration(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0
+ )
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.close_target)).perform(click())
+ }
+
+ launch(
+ createExplorationActivityIntent(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0,
+ shouldSavePartialProgress = false
+ )
+ ).use {
+ explorationDataController.startPlayingNewExploration(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0
+ )
+ testCoroutineDispatchers.runCurrent()
+
+ onView(withText(R.string.voiceover_icon_spotlight_hint)).check(doesNotExist())
+ }
+ }
+
+ @Test
+ fun testVoiceoverIconSpotlight_setToShowOn3rdLoginChapterComplete_1stLogin_checkSpotlightIsNotShown() {
+ markSpotlightSeen(Spotlight.FeatureCase.LESSONS_BACK_BUTTON)
+ launch(
+ createExplorationActivityIntent(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0,
+ shouldSavePartialProgress = false
+ )
+ ).use {
+ explorationDataController.startPlayingNewExploration(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0,
+ FRACTIONS_EXPLORATION_ID_0
+ )
+ testCoroutineDispatchers.runCurrent()
+
+ onView(withText(R.string.voiceover_icon_spotlight_hint)).check(doesNotExist())
+ }
+ }
+
@Test
fun testExploration_clickAudioIcon_contentDescription_changesCorrectly() {
setUpAudioForFractionLesson()
@@ -1921,6 +2135,24 @@ class ExplorationActivityTest {
}
}
+ private fun markSpotlightSeen(feature: Spotlight.FeatureCase) {
+ val profileId = ProfileId.newBuilder()
+ .setInternalId(internalProfileId)
+ .build()
+ monitorFactory.waitForNextSuccessfulResult(
+ spotlightStateController.markSpotlightViewed(
+ profileId,
+ feature
+ )
+ )
+ }
+
+ private fun logIntoUserThrice() {
+ monitorFactory.waitForNextSuccessfulResult(profileTestHelper.logIntoAdmin())
+ monitorFactory.waitForNextSuccessfulResult(profileTestHelper.logIntoAdmin())
+ monitorFactory.waitForNextSuccessfulResult(profileTestHelper.logIntoAdmin())
+ }
+
private fun createExplorationActivityIntent(
internalProfileId: Int,
topicId: String,
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
index f0fda4dfa6d..26996a461c7 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
@@ -16,7 +16,6 @@ import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.matcher.ViewMatchers.assertThat
-import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
import androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.isRoot
@@ -30,9 +29,10 @@ import com.google.common.truth.Truth.assertThat
import dagger.Component
import javax.inject.Inject
import javax.inject.Singleton
-import kotlinx.coroutines.delay
import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.CoreMatchers.instanceOf
+import org.hamcrest.CoreMatchers.not
+import org.hamcrest.Matchers
import org.hamcrest.Matchers.allOf
import org.junit.After
import org.junit.Before
@@ -51,6 +51,8 @@ import org.oppia.android.app.application.ApplicationStartupListenerModule
import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
+import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPositionOnView
import org.oppia.android.app.shim.ViewBindingShimModule
@@ -84,9 +86,11 @@ import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModul
import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
+import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.domain.topic.FRACTIONS_STORY_ID_0
import org.oppia.android.domain.topic.FRACTIONS_TOPIC_ID
import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
+import org.oppia.android.domain.topic.RATIOS_TOPIC_ID
import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule
import org.oppia.android.testing.DisableAccessibilityChecks
import org.oppia.android.testing.OppiaTestRule
@@ -94,6 +98,7 @@ import org.oppia.android.testing.TestLogReportingModule
import org.oppia.android.testing.junit.InitializeDefaultLocaleRule
import org.oppia.android.testing.platformparameter.TestPlatformParameterModule
import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.story.StoryProgressTestHelper
import org.oppia.android.testing.threading.TestCoroutineDispatchers
import org.oppia.android.testing.threading.TestDispatcherModule
import org.oppia.android.testing.time.FakeOppiaClockModule
@@ -145,6 +150,12 @@ class TopicFragmentTest {
@Inject
lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
+ @Inject
+ lateinit var spotlightStateController: SpotlightStateController
+
+ @Inject
+ lateinit var storyProgressTestHelper: StoryProgressTestHelper
+
@field:[Inject EnableExtraTopicTabsUi]
lateinit var enableExtraTopicTabsUi: PlatformParameterValue
@@ -172,21 +183,26 @@ class TopicFragmentTest {
}
}
-// @Test
-// fun testLessonsTabSpotlight_spotlightAlreadySeen_checkSpotlightNotShown() {
-// TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
-// launchTopicActivity(internalProfileId, FRACTIONS_TOPIC_ID).use {
-//
-// }
-// launchTopicActivity(internalProfileId, FRACTIONS_TOPIC_ID).use {
-// onView(withText(context.getString(R.string.topic_lessons_tab_spotlight_hint))).check(
-// doesNotExist()
-// )
-// }
-// }
+ @DisableAccessibilityChecks
+ @Test
+ fun testLessonsTabSpotlight_spotlightAlreadySeen_checkSpotlightNotShown() {
+ initializeApplicationComponent(false)
+ markFirstChapterSpotlightSeen()
+ launch(createTopicActivityIntent(internalProfileId, FRACTIONS_TOPIC_ID)).use {
+ // mark lessons spotlight seen
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.close_target)).perform(click())
+ }
+
+ launch(createTopicActivityIntent(internalProfileId, FRACTIONS_TOPIC_ID)).use {
+ testCoroutineDispatchers.runCurrent()
+ onView(withText(R.string.topic_lessons_tab_spotlight_hint)).check(doesNotExist())
+ }
+ }
+ @DisableAccessibilityChecks
@Test
- fun testFirstChapterSpotlight_setToShowOnFirstLogin_checkSpotlightShown() {
+ fun testTopicLessonTabSpotlight_spotlightNotSeenBefore_checkSpotlightIsShown() {
initializeApplicationComponent(false)
activityTestRule.launchActivity(
createTopicActivityIntent(
@@ -195,26 +211,99 @@ class TopicFragmentTest {
)
)
testCoroutineDispatchers.runCurrent()
-
- // finish lessons tab spotlight first
- onView(withText("Done")).perform(click())
- testCoroutineDispatchers.runCurrent()
- testCoroutineDispatchers.advanceUntilIdle()
- onView(withId(R.id.custom_text)).check(matches(withText(R.string.first_chapter_spotlight_hint))
- )
+ onView(withText(R.string.topic_lessons_tab_spotlight_hint)).check(matches(isDisplayed()))
}
+ @DisableAccessibilityChecks
@Test
- fun testTopicLessonTabSpotlight_spotlightNotSeenBefore_checkSpotlightIsShown() {
+ fun testFirstChapterSpotlight_setToShowOnFirstLogin_checkSpotlightShown() {
initializeApplicationComponent(false)
+ markLessonsSpotlightSeen()
activityTestRule.launchActivity(
- createTopicActivityIntent(
+ createTopicPlayStoryActivityIntent(
internalProfileId,
- FRACTIONS_TOPIC_ID
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0
)
)
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.custom_text)).check(matches(withText(R.string.topic_lessons_tab_spotlight_hint)))
+ onView(withText(R.string.first_chapter_spotlight_hint)).check(matches(isDisplayed()))
+ }
+
+ @DisableAccessibilityChecks
+ @Test
+ fun testFirstChapterSpotlight_setToShowOnFirstLogin_alreadySeen_checkSpotlightNotShown() {
+ TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
+ launch(
+ createTopicPlayStoryActivityIntent(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0
+ )
+ ).use {
+ // mark first chapter spotlight seen
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.close_target)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.close_target)).perform(click())
+ }
+
+ launch(
+ createTopicPlayStoryActivityIntent(
+ internalProfileId,
+ FRACTIONS_TOPIC_ID,
+ FRACTIONS_STORY_ID_0
+ )
+ ).use {
+ testCoroutineDispatchers.runCurrent()
+ onView(withText(R.string.first_chapter_spotlight_hint)).check(doesNotExist())
+ }
+ }
+
+ @Test
+ fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_notSeenBefore_checkIsShown() {
+ TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
+ markFirstChapterSpotlightSeen()
+ markLessonsSpotlightSeen()
+ val profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
+ storyProgressTestHelper.markCompletedRatiosTopic(profileId, false)
+ launch(createTopicActivityIntent(internalProfileId, RATIOS_TOPIC_ID)).use {
+ // mark lessons spotlight seen
+ onView(withId(R.id.close_target)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+
+ onView(withText(R.string.topic_revision_tab_spotlight_hint)).check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_chaptersNotComplete_checkIsNotShown() {
+ TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
+ markLessonsSpotlightSeen()
+ markFirstChapterSpotlightSeen()
+ launch(createTopicActivityIntent(internalProfileId, RATIOS_TOPIC_ID)).use {
+ testCoroutineDispatchers.runCurrent()
+ onView(withText(R.string.topic_revision_tab_spotlight_hint)).check(doesNotExist())
+ }
+ }
+
+ @Test
+ fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_alreadyBefore_checkIsNotShown() {
+ TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
+ markLessonsSpotlightSeen()
+ markFirstChapterSpotlightSeen()
+ val profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
+ storyProgressTestHelper.markCompletedRatiosTopic(profileId, false)
+ launch(createTopicActivityIntent(internalProfileId, RATIOS_TOPIC_ID)).use {
+ testCoroutineDispatchers.runCurrent()
+ // mark revision tab spotlight seen
+ onView(withId(R.id.close_target)).perform(click())
+ }
+
+ launch(createTopicActivityIntent(internalProfileId, RATIOS_TOPIC_ID)).use {
+ testCoroutineDispatchers.runCurrent()
+ onView(withText(R.string.topic_revision_tab_spotlight_hint)).check(doesNotExist())
+ }
}
@Test
@@ -705,6 +794,22 @@ class TopicFragmentTest {
)
}
+ private fun markLessonsSpotlightSeen() {
+ val profileId = ProfileId.newBuilder()
+ .setInternalId(internalProfileId)
+ .build()
+ spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_LESSON_TAB)
+ testCoroutineDispatchers.runCurrent()
+ }
+
+ private fun markFirstChapterSpotlightSeen() {
+ val profileId = ProfileId.newBuilder()
+ .setInternalId(internalProfileId)
+ .build()
+ spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.FIRST_CHAPTER)
+ testCoroutineDispatchers.runCurrent()
+ }
+
private fun initializeApplicationComponent(enableExtraTabsUi: Boolean) {
TestPlatformParameterModule.forceEnableExtraTopicTabsUi(enableExtraTabsUi)
setUpTestApplicationComponent()
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
index 250e169403f..93679090ca6 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
@@ -57,6 +57,7 @@ import org.oppia.android.app.model.ExplorationActivityParams
import org.oppia.android.app.model.ExplorationCheckpoint
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.ResumeLessonActivityParams
+import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.player.exploration.ExplorationActivity
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPosition
@@ -96,6 +97,7 @@ import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModul
import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
+import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.domain.topic.FRACTIONS_EXPLORATION_ID_0
import org.oppia.android.domain.topic.FRACTIONS_STORY_ID_0
import org.oppia.android.domain.topic.FRACTIONS_TOPIC_ID
@@ -103,8 +105,11 @@ import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
import org.oppia.android.domain.topic.RATIOS_STORY_ID_0
import org.oppia.android.domain.topic.RATIOS_TOPIC_ID
import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule
+import org.oppia.android.testing.DisableAccessibilityChecks
import org.oppia.android.testing.OppiaTestRule
+import org.oppia.android.testing.RunOn
import org.oppia.android.testing.TestLogReportingModule
+import org.oppia.android.testing.TestPlatform
import org.oppia.android.testing.junit.InitializeDefaultLocaleRule
import org.oppia.android.testing.lightweightcheckpointing.ExplorationCheckpointTestHelper
import org.oppia.android.testing.lightweightcheckpointing.FRACTIONS_STORY_0_EXPLORATION_0_CURRENT_VERSION
@@ -163,6 +168,9 @@ class TopicLessonsFragmentTest {
@Inject
lateinit var fakeAccessibilityService: FakeAccessibilityService
+ @Inject
+ lateinit var spotlightStateController: SpotlightStateController
+
@Inject
lateinit var explorationCheckpointTestHelper: ExplorationCheckpointTestHelper
@@ -209,31 +217,6 @@ class TopicLessonsFragmentTest {
}
}
- @Test
- fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_notSeenBefore_checkIsShown() {
- TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
- storyProgressTestHelper.markCompletedRatiosTopic(profileId, false)
- launch(createTopicActivityIntent(internalProfileId, RATIOS_TOPIC_ID)).use {
- // mark lessons spotlight seen
- onView(withId(R.id.close_target)).perform(click())
- testCoroutineDispatchers.runCurrent()
-
- onView(withText(R.string.topic_revision_tab_spotlight_hint)).check(matches(isDisplayed()))
- }
- }
-
- @Test
- fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_chaptersNotComplete_checkIsNotShown() {
- TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
- launch(createTopicActivityIntent(internalProfileId, RATIOS_TOPIC_ID)).use {
- // mark lessons spotlight seen
- onView(withId(R.id.close_target)).perform(click())
- testCoroutineDispatchers.runCurrent()
-
- onView(withText(R.string.topic_revision_tab_spotlight_hint)).check(matches(not(isDisplayed())))
- }
- }
-
@Test
fun testLessonsPlayFragment_loadRatiosTopic_completeStoryProgress_isDisplayed() {
storyProgressTestHelper.markCompletedRatiosStory0(
diff --git a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
index 73181e323e3..750db41d7d9 100644
--- a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
@@ -287,40 +287,6 @@ class StateFragmentLocalTest {
}
}
- @Test
- fun testBackButtonSpotlight_setToShowOnFirstLogin_neverSeenBefore_checkSpotlightIsShown() {
- launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {
- startPlayingExploration()
-
- onView(withText(R.string.exploration_exit_button_spotlight_hint)).check(matches(isDisplayed()))
- }
- }
-
- @Test
- fun testVoiceoverIconSpotlight_setToShowOn3rdLoginChapterComplete_neverSeenBefore_checkSpotlightIsShown() {
- logIntoUserThrice()
- launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {
- startPlayingExploration()
- // mark exit button spotlight seen
- onView(withId(R.id.close_target)).perform(click())
- testCoroutineDispatchers.runCurrent()
-
- onView(withText(R.string.voiceover_icon_spotlight_hint)).check(matches(isDisplayed()))
- }
- }
-
- @Test
- fun testVoiceoverIconSpotlight_setToShowOn3rdLoginChapterComplete_1stLogin_checkSpotlightIsNotShown() {
- launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {
- startPlayingExploration()
- // mark exit button spotlight seen
- onView(withId(R.id.close_target)).perform(click())
- testCoroutineDispatchers.runCurrent()
-
- onView(withText(R.string.voiceover_icon_spotlight_hint)).check(matches(not(isDisplayed())))
- }
- }
-
@Test
fun testStateFragment_nextState_wait10seconds_noHintAvailable() {
launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {
@@ -2351,12 +2317,6 @@ class StateFragmentLocalTest {
Locale.setDefault(locale)
}
- private fun logIntoUserThrice() {
- monitorFactory.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
- monitorFactory.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
- monitorFactory.waitForNextSuccessfulResult(profileTestHelper.logIntoUser())
- }
-
/**
* Returns a [ViewAssertion] that can be used to check the specified matcher applies the specified
* number of times for children against the view under test. If the count does not exactly match,
From 4e99502f12efedbf1cc07fcc58ae9c756843fcb8 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 17 Nov 2022 00:38:50 +0530
Subject: [PATCH 079/138] overlay design changes
---
app/src/main/res/layout/bottom_left_overlay.xml | 4 +++-
app/src/main/res/layout/bottom_right_overlay.xml | 4 +++-
app/src/main/res/layout/top_left_overlay.xml | 4 +++-
app/src/main/res/layout/top_right_overlay.xml | 4 +++-
4 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 93e87a50b0b..cde8bba118d 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -46,7 +46,9 @@
android:id="@+id/close_target"
style="@style/StateButtonActive"
android:layout_width="160dp"
- android:layout_height="36dp"
+ android:layout_height="48dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
android:textSize="14dp"
android:gravity="center"
android:focusable="true"
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index 00716c42c12..139dcfd4080 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -47,7 +47,9 @@
android:id="@+id/close_target"
style="@style/StateButtonActive"
android:layout_width="160dp"
- android:layout_height="36dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:layout_height="48dp"
android:textSize="14dp"
android:gravity="center"
android:focusable="true"
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index 36e261c3b95..fbd6c194518 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -45,8 +45,10 @@
Date: Thu, 17 Nov 2022 00:43:07 +0530
Subject: [PATCH 080/138] some tests in exploration activity tests are failing
---
.../onboarding/OnboardingActivityPresenter.kt | 2 +-
.../player/exploration/ExplorationActivity.kt | 7 +-
.../ExplorationActivityPresenter.kt | 21 +++++-
.../ExplorationFragmentPresenter.kt | 18 +----
.../RequestVoiceOverIconSpotlightListener.kt | 5 ++
.../player/state/StateFragmentPresenter.kt | 2 -
.../app/spotlight/SpotlightFragment.kt | 17 ++---
.../testing/SpotlightFragmentTestActivity.kt | 4 ++
.../app/topic/TopicFragmentPresenter.kt | 2 +-
.../oppia/android/app/topic/TopicViewModel.kt | 8 +--
.../exploration/ExplorationActivityTest.kt | 49 ++++++++++---
.../android/app/topic/TopicFragmentTest.kt | 69 ++++++++++++-------
12 files changed, 135 insertions(+), 69 deletions(-)
create mode 100644 app/src/main/java/org/oppia/android/app/player/exploration/RequestVoiceOverIconSpotlightListener.kt
create mode 100644 app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
index 3eb2c1c26d1..9db8bfbb490 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
@@ -24,7 +24,7 @@ class OnboardingActivityPresenter @Inject constructor(private val activity: AppC
if (getSpotlightFragment() == null) {
val spotlightFragment = SpotlightFragment()
val args = Bundle()
- args.putInt(PROFILE_ID_ARGUMENT_KEY, 0)
+ args.putInt(PROFILE_ID_ARGUMENT_KEY, -1)
spotlightFragment.arguments = args
activity.supportFragmentManager.beginTransaction().add(
R.id.onboarding_spotlight_fragment_placeholder,
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivity.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivity.kt
index 65648b4c727..0698e869113 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivity.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivity.kt
@@ -41,7 +41,8 @@ class ExplorationActivity :
DefaultFontSizeStateListener,
HintsAndSolutionExplorationManagerListener,
ConceptCardListener,
- BottomSheetOptionsMenuItemClickListener {
+ BottomSheetOptionsMenuItemClickListener,
+ RequestVoiceOverIconSpotlightListener {
@Inject lateinit var explorationActivityPresenter: ExplorationActivityPresenter
@@ -184,4 +185,8 @@ class ExplorationActivity :
}
override fun dismissConceptCard() = explorationActivityPresenter.dismissConceptCard()
+
+ override fun requestVoiceOverIconSpotlight(numberOfLogins: Int) {
+ explorationActivityPresenter.requestVoiceOverIconSpotlight(numberOfLogins)
+ }
}
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
index 40c6a35ea4d..38644fcf301 100644
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
@@ -34,6 +34,9 @@ import org.oppia.android.domain.translation.TranslationController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import javax.inject.Inject
+import org.oppia.android.app.model.Spotlight
+import org.oppia.android.app.spotlight.SpotlightShape
+import org.oppia.android.app.spotlight.SpotlightTarget
private const val TAG_UNSAVED_EXPLORATION_DIALOG = "UNSAVED_EXPLORATION_DIALOG"
private const val TAG_STOP_EXPLORATION_DIALOG = "STOP_EXPLORATION_DIALOG"
@@ -65,6 +68,7 @@ class ExplorationActivityPresenter @Inject constructor(
private lateinit var oldestCheckpointExplorationId: String
private lateinit var oldestCheckpointExplorationTitle: String
+ private lateinit var binding: ExplorationActivityBinding
private val exploreViewModel by lazy {
getExplorationViewModel()
@@ -79,7 +83,7 @@ class ExplorationActivityPresenter @Inject constructor(
parentScreen: ExplorationActivityParams.ParentScreen,
isCheckpointingEnabled: Boolean
) {
- val binding = DataBindingUtil.setContentView(
+ binding = DataBindingUtil.setContentView(
activity,
R.layout.exploration_activity
)
@@ -141,6 +145,21 @@ class ExplorationActivityPresenter @Inject constructor(
}
}
+ fun requestVoiceOverIconSpotlight(numberOfLogins: Int) {
+ if (numberOfLogins >= 3) {
+ // spotlight voice-over icon after 3 logins
+ val audioPlayerSpotlightTarget = SpotlightTarget(
+ binding.actionAudioPlayer,
+ activity.getString(R.string.voiceover_icon_spotlight_hint),
+ SpotlightShape.Circle,
+ Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
+ )
+ checkNotNull(getSpotlightFragment()).requestSpotlightViewWithDelayedLayout(
+ audioPlayerSpotlightTarget
+ )
+ }
+ }
+
private fun getSpotlightFragment(): SpotlightFragment? {
return activity.supportFragmentManager.findFragmentByTag(
SPOTLIGHT_FRAGMENT_TAG
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index 621307072b7..db1b4279d05 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -1,7 +1,6 @@
package org.oppia.android.app.player.exploration
import android.content.Context
-import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -87,7 +86,6 @@ class ExplorationFragmentPresenter @Inject constructor(
}
private fun showSpotlights(numberOfLogins: Int) {
- Log.d("overlay", "login count: $numberOfLogins")
val explorationToolbar =
fragment.requireActivity().findViewById(R.id.exploration_toolbar) as Toolbar
explorationToolbar.forEach {
@@ -97,25 +95,13 @@ class ExplorationFragmentPresenter @Inject constructor(
it,
fragment.requireContext().getString(R.string.exploration_exit_button_spotlight_hint),
SpotlightShape.Circle,
- Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
+ Spotlight.FeatureCase.LESSONS_BACK_BUTTON
)
checkNotNull(getSpotlightFragment()).requestSpotlight(backButtonSpotlightTarget)
}
}
- val voiceoverIcon = fragment.requireActivity().findViewById(R.id.action_audio_player)
- if (numberOfLogins >= 3 && voiceoverIcon.visibility == View.VISIBLE) {
- // spotlight voice-over icon after 3 logins
- val audioPlayerSpotlightTarget = SpotlightTarget(
- voiceoverIcon,
- fragment.requireContext().getString(R.string.voiceover_icon_spotlight_hint),
- SpotlightShape.Circle,
- Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
- )
- checkNotNull(getSpotlightFragment()).requestSpotlightViewWithDelayedLayout(
- audioPlayerSpotlightTarget
- )
- }
+ (fragment.requireActivity() as RequestVoiceOverIconSpotlightListener).requestVoiceOverIconSpotlight(numberOfLogins)
}
private fun getSpotlightFragment(): SpotlightFragment? {
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/RequestVoiceOverIconSpotlightListener.kt b/app/src/main/java/org/oppia/android/app/player/exploration/RequestVoiceOverIconSpotlightListener.kt
new file mode 100644
index 00000000000..c6ee800387d
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/RequestVoiceOverIconSpotlightListener.kt
@@ -0,0 +1,5 @@
+package org.oppia.android.app.player.exploration
+
+interface RequestVoiceOverIconSpotlightListener {
+ fun requestVoiceOverIconSpotlight(numberOfLogins: Int)
+}
\ No newline at end of file
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 31d668a8cff..b831399a935 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
@@ -1,7 +1,6 @@
package org.oppia.android.app.player.state
import android.content.Context
-import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -510,7 +509,6 @@ class StateFragmentPresenter @Inject constructor(
activity.runPeriodically(delayMillis = 5_000, periodMillis = 30_000) {
return@runPeriodically viewModel.isHintOpenedAndUnRevealed.get()!!.also { playAnim ->
if (playAnim) binding.hintBulb.startAnimation(hintBulbAnimation)
- Log.d("hints", "announcement expected now")
binding.hintsAndSolutionFragmentContainer.announceForAccessibility("Go to the bottom of the screen for hint")
}
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 595eddb5a0a..453324011f5 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -80,6 +80,9 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
fun requestSpotlightViewWithDelayedLayout(spotlightTarget: SpotlightTarget) {
spotlightTarget.anchor.doOnPreDraw {
+ if (it.visibility != View.VISIBLE) {
+ return@doOnPreDraw
+ }
val targetAfterViewFullyDrawn = SpotlightTarget(
it,
spotlightTarget.hint,
@@ -153,16 +156,14 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
- Log.d("overlay", "target start")
}
override fun onEnded() {
- Log.d("overlay", "target end")
targetList.pop()
-// val profileId = ProfileId.newBuilder()
-// .setInternalId(internalProfileId)
-// .build()
-// spotlightStateController.markSpotlightViewed(profileId, spotlightTarget.feature)
+ val profileId = ProfileId.newBuilder()
+ .setInternalId(internalProfileId)
+ .build()
+ spotlightStateController.markSpotlightViewed(profileId, spotlightTarget.feature)
}
})
.build(spotlightTarget.anchor)
@@ -182,14 +183,10 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
.setAnimation(DecelerateInterpolator(2f))
.setOnSpotlightListener(object : OnSpotlightListener {
override fun onStarted() {
- Log.d("overlay", "spotlight start")
-
isSpotlightActive.value = true
}
override fun onEnded() {
- Log.d("overlay", "spotlight end")
-
isSpotlightActive.value = false
startSpotlight()
}
diff --git a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
new file mode 100644
index 00000000000..d502ade9d4f
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
@@ -0,0 +1,4 @@
+package org.oppia.android.app.testing
+
+class SpotlightFragmentTestActivity {
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index d5fb91ffd63..6f4454feeb5 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -76,7 +76,7 @@ class TopicFragmentPresenter @Inject constructor(
fun startSpotlight() {
viewModel.numberOfChaptersCompletedLiveData.observe(fragment) { numberOfChaptersCompleted ->
- if (numberOfChaptersCompleted != -1) {
+ if (numberOfChaptersCompleted != null) {
val lessonsTabView = tabLayout.getTabAt(computeTabPosition(TopicTab.LESSONS))?.view
lessonsTabView?.let { lessonsTabView ->
val lessonsTabSpotlightTarget = SpotlightTarget(
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt b/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
index a141e418379..d953a06547b 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
@@ -48,12 +48,12 @@ class TopicViewModel @Inject constructor(
private fun computeNumberOfChaptersCompleted(
topicListResult: AsyncResult
- ): Int {
+ ): Int? {
+ var numberOfChaptersCompleted = 0
return when (topicListResult) {
- is AsyncResult.Failure -> -1
- is AsyncResult.Pending -> -1
+ is AsyncResult.Failure -> null
+ is AsyncResult.Pending -> null
is AsyncResult.Success -> {
- var numberOfChaptersCompleted = 0
topicListResult.value.promotedStoryList.recentlyPlayedStoryList.forEach {
numberOfChaptersCompleted += it.completedChapterCount
}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
index 2cd8500e790..c5a2d653797 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
@@ -286,6 +286,7 @@ class ExplorationActivityTest {
@Test
fun testExplorationActivity_hasCorrectActivityLabel() {
+ markAllSpotlightsSeen()
explorationActivityTestRule.launchActivity(
createExplorationActivityIntent(
internalProfileId,
@@ -328,6 +329,7 @@ class ExplorationActivityTest {
@Test
fun testExploration_toolbarTitle_marqueeInRtl_isDisplayedCorrectly() {
+ markAllSpotlightsSeen()
explorationActivityTestRule.launchActivity(
createExplorationActivityIntent(
internalProfileId,
@@ -350,6 +352,7 @@ class ExplorationActivityTest {
@Test
fun testExploration_toolbarTitle_marqueeInLtr_isDisplayedCorrectly() {
+ markAllSpotlightsSeen()
explorationActivityTestRule.launchActivity(
createExplorationActivityIntent(
internalProfileId,
@@ -424,6 +427,8 @@ class ExplorationActivityTest {
@Test
fun testVoiceoverLangIconSpotlight_setToShowOnIconClick_neverSeenBefore_checkSpotlightIsShown() {
setUpAudioForFractionLesson()
+ markSpotlightSeen(Spotlight.FeatureCase.LESSONS_BACK_BUTTON)
+ markSpotlightSeen(Spotlight.FeatureCase.VOICEOVER_PLAY_ICON)
launch(
createExplorationActivityIntent(
internalProfileId,
@@ -450,6 +455,8 @@ class ExplorationActivityTest {
@Test
fun testVoiceoverLangIconSpotlight_setToShowOnIconClick_alreadySeen_checkSpotlightIsNotShown() {
setUpAudioForFractionLesson()
+ markSpotlightSeen(Spotlight.FeatureCase.LESSONS_BACK_BUTTON)
+ markSpotlightSeen(Spotlight.FeatureCase.VOICEOVER_PLAY_ICON)
launch(
createExplorationActivityIntent(
internalProfileId,
@@ -519,7 +526,7 @@ class ExplorationActivityTest {
@Test
fun testBackButtonSpotlight_setToShowOnFirstLogin_alreadySeen_checkSpotlightIsNotShown() {
- markSpotlightSeen(Spotlight.FeatureCase.VOICEOVER_LANGUAGE_ICON)
+ markSpotlightSeen(Spotlight.FeatureCase.VOICEOVER_PLAY_ICON)
launch(
createExplorationActivityIntent(
internalProfileId,
@@ -560,6 +567,7 @@ class ExplorationActivityTest {
@Test
fun testVoiceoverIconSpotlight_setToShowOn3rdLoginChapterComplete_neverSeenBefore_checkSpotlightIsShown() {
logIntoUserThrice()
+ setUpAudioForFractionLesson()
markSpotlightSeen(Spotlight.FeatureCase.LESSONS_BACK_BUTTON)
launch(
createExplorationActivityIntent(
@@ -585,6 +593,7 @@ class ExplorationActivityTest {
@Test
fun testVoiceoverIconSpotlight_setToShowOn3rdLoginChapterComplete_alreadySeen_checkSpotlightIsNotShown() {
logIntoUserThrice()
+ setUpAudioForFractionLesson()
markSpotlightSeen(Spotlight.FeatureCase.LESSONS_BACK_BUTTON)
launch(
createExplorationActivityIntent(
@@ -652,6 +661,7 @@ class ExplorationActivityTest {
@Test
fun testExploration_clickAudioIcon_contentDescription_changesCorrectly() {
+ markAllSpotlightsSeen()
setUpAudioForFractionLesson()
launch(
createExplorationActivityIntent(
@@ -752,6 +762,7 @@ class ExplorationActivityTest {
@Test
fun testAudioWithNoConnection_openRatioExploration_clickAudioIcon_checkOpensNoConnectionDialog() {
+ markAllSpotlightsSeen()
setUpAudio()
launch(
createExplorationActivityIntent(
@@ -780,6 +791,7 @@ class ExplorationActivityTest {
@Test
fun testAudioWithCellular_openRatioExploration_clickAudioIcon_checkOpensCellularAudioDialog() {
+ markAllSpotlightsSeen()
setUpAudio()
launch(
createExplorationActivityIntent(
@@ -806,6 +818,7 @@ class ExplorationActivityTest {
@Test
fun testAudioCellular_ratioExp_audioIcon_configChange_opensCellularAudioDialog() {
+ markAllSpotlightsSeen()
setUpAudio()
launch(
createExplorationActivityIntent(
@@ -869,6 +882,7 @@ class ExplorationActivityTest {
@Test
fun testAudioCellular_ratioExp_audioIcon_clickPositive_checkAudioFragmentIsVisible() {
+ markAllSpotlightsSeen()
setUpAudio()
launch(
createExplorationActivityIntent(
@@ -914,6 +928,7 @@ class ExplorationActivityTest {
@Test
fun testAudioCellular_ratioExp_check_negative_audioIcon_audioFragHiddenDialogNotDisplay() {
+ markAllSpotlightsSeen()
setUpAudio()
launch(
createExplorationActivityIntent(
@@ -954,6 +969,7 @@ class ExplorationActivityTest {
@Test
fun testAudioCellular_ratioExp_checkPositive_audioIconTwice_audioFragVisDialogNotDisplay() {
+ markAllSpotlightsSeen()
setUpAudio()
launch(
createExplorationActivityIntent(
@@ -1036,6 +1052,7 @@ class ExplorationActivityTest {
@Test
fun testAudioWifi_fractionsExp_changeLang_next_langIsHinglish() {
+ markAllSpotlightsSeen()
setUpAudioForFractionLesson()
launch(
createExplorationActivityIntent(
@@ -1136,6 +1153,7 @@ class ExplorationActivityTest {
@Test
fun testExplorationActivity_loadExplorationFragment_hasDummyString() {
+ markAllSpotlightsSeen()
launch(
createExplorationActivityIntent(
internalProfileId,
@@ -1179,6 +1197,7 @@ class ExplorationActivityTest {
@Test
fun testExplorationActivity_onToolbarClosePressed_showsUnsavedExplorationDialog() {
+ markAllSpotlightsSeen()
setUpAudioForFractionLesson()
launch(
createExplorationActivityIntent(
@@ -1208,6 +1227,7 @@ class ExplorationActivityTest {
// TODO(#89): Check this test case too. It works in pair with below test cases.
@Test
fun testExpActivity_showUnsavedExpDialog_cancel_dismissesDialog() {
+ markAllSpotlightsSeen()
setUpAudioForFractionLesson()
explorationActivityTestRule.launchActivity(
createExplorationActivityIntent(
@@ -1262,6 +1282,7 @@ class ExplorationActivityTest {
@Test
fun testExpActivity_showUnsavedExpDialog_cancel_checkOldestProgressIsSaved() {
+ markAllSpotlightsSeen()
explorationCheckpointTestHelper.saveCheckpointForRatiosStory0Exploration0(
profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build(),
version = RATIOS_STORY_0_EXPLORATION_0_CURRENT_VERSION
@@ -1297,6 +1318,7 @@ class ExplorationActivityTest {
// TODO(#89): Check this test case too. It works in pair with test cases ignored above.
@Test
fun testExpActivity_showUnsavedExpDialog_leave_checkOldestProgressIsSaved() {
+ markAllSpotlightsSeen()
explorationCheckpointTestHelper.saveCheckpointForRatiosStory0Exploration0(
profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build(),
version = RATIOS_STORY_0_EXPLORATION_0_CURRENT_VERSION
@@ -1391,6 +1413,7 @@ class ExplorationActivityTest {
// TODO(#89): Check this test case too. It works in pair with test cases ignored above.
@Test
fun testExpActivity_progressSaved_onBackPress_checkNoProgressDeleted() {
+ markAllSpotlightsSeen()
explorationCheckpointTestHelper.saveCheckpointForRatiosStory0Exploration0(
profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build(),
version = RATIOS_STORY_0_EXPLORATION_0_CURRENT_VERSION
@@ -1462,6 +1485,7 @@ class ExplorationActivityTest {
@Test
fun testExplorationActivity_databaseFull_onToolbarClosePressed_showsProgressDatabaseFullDialog() {
+ markAllSpotlightsSeen()
explorationCheckpointTestHelper.saveCheckpointForRatiosStory0Exploration0(
profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build(),
version = RATIOS_STORY_0_EXPLORATION_0_CURRENT_VERSION
@@ -1498,6 +1522,7 @@ class ExplorationActivityTest {
// TODO(#89): Check this test case too. It works in pair with below test cases.
@Test
fun testExplorationActivity_showProgressDatabaseFullDialog_backToLesson_checkDialogDismisses() {
+ markAllSpotlightsSeen()
explorationCheckpointTestHelper.saveCheckpointForRatiosStory0Exploration0(
profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build(),
version = RATIOS_STORY_0_EXPLORATION_0_CURRENT_VERSION
@@ -2018,6 +2043,7 @@ class ExplorationActivityTest {
@Test
fun testExplorationActivity_initialise_openBottomSheet_showsBottomSheet() {
+ markAllSpotlightsSeen()
launch(
createExplorationActivityIntent(
internalProfileId,
@@ -2043,6 +2069,7 @@ class ExplorationActivityTest {
@Test
fun testExplorationActivity_openBottomsheet_selectHelpInBottomsheet_opensHelpActivity() {
+ markAllSpotlightsSeen()
launch(
createExplorationActivityIntent(
internalProfileId,
@@ -2076,6 +2103,7 @@ class ExplorationActivityTest {
@Test
fun testExplorationActivity_openBottomsheet_selectOptionsInBottomsheet_opensOptionsActivity() {
+ markAllSpotlightsSeen()
launch(
createExplorationActivityIntent(
internalProfileId,
@@ -2109,6 +2137,7 @@ class ExplorationActivityTest {
@Test
fun testExplorationActivity_openBottomsheet_selectCloseOption_bottomSheetCloses() {
+ markAllSpotlightsSeen()
launch(
createExplorationActivityIntent(
internalProfileId,
@@ -2136,15 +2165,15 @@ class ExplorationActivityTest {
}
private fun markSpotlightSeen(feature: Spotlight.FeatureCase) {
- val profileId = ProfileId.newBuilder()
- .setInternalId(internalProfileId)
- .build()
- monitorFactory.waitForNextSuccessfulResult(
- spotlightStateController.markSpotlightViewed(
- profileId,
- feature
- )
- )
+ val profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
+ spotlightStateController.markSpotlightViewed(profileId, feature)
+ testCoroutineDispatchers.runCurrent()
+ }
+
+ private fun markAllSpotlightsSeen() {
+ markSpotlightSeen(Spotlight.FeatureCase.LESSONS_BACK_BUTTON)
+ markSpotlightSeen(Spotlight.FeatureCase.VOICEOVER_PLAY_ICON)
+ markSpotlightSeen(Spotlight.FeatureCase.VOICEOVER_LANGUAGE_ICON)
}
private fun logIntoUserThrice() {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
index 26996a461c7..beee6151519 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
@@ -31,8 +31,6 @@ import javax.inject.Inject
import javax.inject.Singleton
import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.CoreMatchers.instanceOf
-import org.hamcrest.CoreMatchers.not
-import org.hamcrest.Matchers
import org.hamcrest.Matchers.allOf
import org.junit.After
import org.junit.Before
@@ -90,9 +88,9 @@ import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.domain.topic.FRACTIONS_STORY_ID_0
import org.oppia.android.domain.topic.FRACTIONS_TOPIC_ID
import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
+import org.oppia.android.domain.topic.RATIOS_STORY_ID_0
import org.oppia.android.domain.topic.RATIOS_TOPIC_ID
import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule
-import org.oppia.android.testing.DisableAccessibilityChecks
import org.oppia.android.testing.OppiaTestRule
import org.oppia.android.testing.TestLogReportingModule
import org.oppia.android.testing.junit.InitializeDefaultLocaleRule
@@ -101,6 +99,7 @@ import org.oppia.android.testing.robolectric.RobolectricModule
import org.oppia.android.testing.story.StoryProgressTestHelper
import org.oppia.android.testing.threading.TestCoroutineDispatchers
import org.oppia.android.testing.threading.TestDispatcherModule
+import org.oppia.android.testing.time.FakeOppiaClock
import org.oppia.android.testing.time.FakeOppiaClockModule
import org.oppia.android.util.accessibility.AccessibilityTestModule
import org.oppia.android.util.caching.AssetModule
@@ -153,6 +152,9 @@ class TopicFragmentTest {
@Inject
lateinit var spotlightStateController: SpotlightStateController
+ @Inject
+ lateinit var fakeOppiaClock: FakeOppiaClock
+
@Inject
lateinit var storyProgressTestHelper: StoryProgressTestHelper
@@ -183,7 +185,6 @@ class TopicFragmentTest {
}
}
- @DisableAccessibilityChecks
@Test
fun testLessonsTabSpotlight_spotlightAlreadySeen_checkSpotlightNotShown() {
initializeApplicationComponent(false)
@@ -200,7 +201,6 @@ class TopicFragmentTest {
}
}
- @DisableAccessibilityChecks
@Test
fun testTopicLessonTabSpotlight_spotlightNotSeenBefore_checkSpotlightIsShown() {
initializeApplicationComponent(false)
@@ -214,11 +214,10 @@ class TopicFragmentTest {
onView(withText(R.string.topic_lessons_tab_spotlight_hint)).check(matches(isDisplayed()))
}
- @DisableAccessibilityChecks
@Test
fun testFirstChapterSpotlight_setToShowOnFirstLogin_checkSpotlightShown() {
initializeApplicationComponent(false)
- markLessonsSpotlightSeen()
+ markLessonsTabSpotlightSeen()
activityTestRule.launchActivity(
createTopicPlayStoryActivityIntent(
internalProfileId,
@@ -230,10 +229,9 @@ class TopicFragmentTest {
onView(withText(R.string.first_chapter_spotlight_hint)).check(matches(isDisplayed()))
}
- @DisableAccessibilityChecks
@Test
fun testFirstChapterSpotlight_setToShowOnFirstLogin_alreadySeen_checkSpotlightNotShown() {
- TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
+ initializeApplicationComponent(false)
launch(
createTopicPlayStoryActivityIntent(
internalProfileId,
@@ -262,12 +260,14 @@ class TopicFragmentTest {
@Test
fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_notSeenBefore_checkIsShown() {
- TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
+ initializeApplicationComponent(false)
markFirstChapterSpotlightSeen()
- markLessonsSpotlightSeen()
+ markLessonsTabSpotlightSeen()
val profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
- storyProgressTestHelper.markCompletedRatiosTopic(profileId, false)
- launch(createTopicActivityIntent(internalProfileId, RATIOS_TOPIC_ID)).use {
+ storyProgressTestHelper.markCompletedRatiosStory0(profileId, false)
+ storyProgressTestHelper.markCompletedRatiosStory1(profileId, false)
+ testCoroutineDispatchers.runCurrent()
+ launch(createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)).use {
// mark lessons spotlight seen
onView(withId(R.id.close_target)).perform(click())
testCoroutineDispatchers.runCurrent()
@@ -278,29 +278,31 @@ class TopicFragmentTest {
@Test
fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_chaptersNotComplete_checkIsNotShown() {
- TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
- markLessonsSpotlightSeen()
+ initializeApplicationComponent(false)
+ markLessonsTabSpotlightSeen()
markFirstChapterSpotlightSeen()
- launch(createTopicActivityIntent(internalProfileId, RATIOS_TOPIC_ID)).use {
+ launch(createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)).use {
testCoroutineDispatchers.runCurrent()
onView(withText(R.string.topic_revision_tab_spotlight_hint)).check(doesNotExist())
}
}
@Test
- fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_alreadyBefore_checkIsNotShown() {
- TestPlatformParameterModule.forceEnableExtraTopicTabsUi(false)
- markLessonsSpotlightSeen()
+ fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_alreadySeen_checkIsNotShown() {
+ initializeApplicationComponent(false)
+ markLessonsTabSpotlightSeen()
markFirstChapterSpotlightSeen()
val profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
- storyProgressTestHelper.markCompletedRatiosTopic(profileId, false)
- launch(createTopicActivityIntent(internalProfileId, RATIOS_TOPIC_ID)).use {
+ fakeOppiaClock.setFakeTimeMode(FakeOppiaClock.FakeTimeMode.MODE_UPTIME_MILLIS)
+ storyProgressTestHelper.markCompletedRatiosStory0(profileId, false)
+ storyProgressTestHelper.markCompletedRatiosStory1(profileId, false)
+ launch(createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)).use {
testCoroutineDispatchers.runCurrent()
// mark revision tab spotlight seen
onView(withId(R.id.close_target)).perform(click())
}
- launch(createTopicActivityIntent(internalProfileId, RATIOS_TOPIC_ID)).use {
+ launch(createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)).use {
testCoroutineDispatchers.runCurrent()
onView(withText(R.string.topic_revision_tab_spotlight_hint)).check(doesNotExist())
}
@@ -438,6 +440,7 @@ class TopicFragmentTest {
@Test
fun testTopicFragment_clickOnLessonsTab_showsPlayTabWithContentMatched() {
initializeApplicationComponent(enableExtraTabsUi = true)
+ markAllSpotlightsSeen()
launchTopicActivityIntent(internalProfileId, FRACTIONS_TOPIC_ID).use {
testCoroutineDispatchers.runCurrent()
clickTabAtPosition(position = LESSON_TAB_POSITION)
@@ -509,6 +512,7 @@ class TopicFragmentTest {
@Test
fun testTopicFragment_enableExtraTabs_clickOnPracticeTab_showsPracticeTabWithContentMatched() {
initializeApplicationComponent(enableExtraTabsUi = true)
+ markAllSpotlightsSeen()
launchTopicActivityIntent(internalProfileId, FRACTIONS_TOPIC_ID).use {
testCoroutineDispatchers.runCurrent()
clickTabAtPosition(position = PRACTICE_TAB_POSITION)
@@ -534,6 +538,7 @@ class TopicFragmentTest {
@Test
fun testTopicFragment_clickOnReviewTab_showsReviewTabWithContentMatched() {
initializeApplicationComponent(enableExtraTabsUi = false)
+ markAllSpotlightsSeen()
launchTopicActivityIntent(internalProfileId, FRACTIONS_TOPIC_ID).use {
testCoroutineDispatchers.runCurrent()
clickTabAtPosition(position = REVISION_TAB_POSITION_EXTRA_TABS_DISABLED)
@@ -595,6 +600,7 @@ class TopicFragmentTest {
@Test
fun enableExtraTabs_clickOnPracticeTab_configChange_showsSameTabAndItsContent() {
initializeApplicationComponent(enableExtraTabsUi = true)
+ markAllSpotlightsSeen()
launchTopicActivityIntent(internalProfileId, FRACTIONS_TOPIC_ID).use {
testCoroutineDispatchers.runCurrent()
clickTabAtPosition(position = PRACTICE_TAB_POSITION)
@@ -620,6 +626,7 @@ class TopicFragmentTest {
@Test
fun testTopicFragment_clickOnReviewTab_configChange_showsSameTabAndItsContent() {
initializeApplicationComponent(enableExtraTabsUi = false)
+ markAllSpotlightsSeen()
launchTopicActivityIntent(internalProfileId, FRACTIONS_TOPIC_ID).use {
testCoroutineDispatchers.runCurrent()
clickTabAtPosition(position = REVISION_TAB_POSITION_EXTRA_TABS_DISABLED)
@@ -678,6 +685,7 @@ class TopicFragmentTest {
@Test
fun enableExtraTabs_withStoryId_clickOnPracticeTab_configChange_showsSameTabAndItsContent() {
initializeApplicationComponent(enableExtraTabsUi = true)
+ markAllSpotlightsSeen()
launchTopicPlayStoryActivityIntent(
internalProfileId,
FRACTIONS_TOPIC_ID,
@@ -794,7 +802,21 @@ class TopicFragmentTest {
)
}
- private fun markLessonsSpotlightSeen() {
+ private fun markAllSpotlightsSeen() {
+ markLessonsTabSpotlightSeen()
+ markFirstChapterSpotlightSeen()
+ markRevisionTabSpotlightSeen()
+ }
+
+ private fun markRevisionTabSpotlightSeen() {
+ val profileId = ProfileId.newBuilder()
+ .setInternalId(internalProfileId)
+ .build()
+ spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_REVISION_TAB)
+ testCoroutineDispatchers.runCurrent()
+ }
+
+ private fun markLessonsTabSpotlightSeen() {
val profileId = ProfileId.newBuilder()
.setInternalId(internalProfileId)
.build()
@@ -814,6 +836,7 @@ class TopicFragmentTest {
TestPlatformParameterModule.forceEnableExtraTopicTabsUi(enableExtraTabsUi)
setUpTestApplicationComponent()
testCoroutineDispatchers.registerIdlingResource()
+ fakeOppiaClock.setFakeTimeMode(FakeOppiaClock.FakeTimeMode.MODE_UPTIME_MILLIS)
}
private fun setUpTestApplicationComponent() {
From 3262e9fe794bd5b87dc45dd47eef508cd1cec493 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 17 Nov 2022 02:07:42 +0530
Subject: [PATCH 081/138] adjust tests for homeactivitytest
---
.../android/app/home/HomeActivityTest.kt | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
index fb4452ce6eb..162c45bca3c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
@@ -144,6 +144,8 @@ import org.robolectric.annotation.LooperMode
import java.util.Locale
import javax.inject.Inject
import javax.inject.Singleton
+import org.oppia.android.app.model.Spotlight
+import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.testing.DisableAccessibilityChecks
// Time: Tue Apr 23 2019 23:22:00
@@ -189,6 +191,9 @@ class HomeActivityTest {
@Inject
lateinit var fakeOppiaClock: FakeOppiaClock
+ @Inject
+ lateinit var spotlightStateController: SpotlightStateController
+
@Inject
lateinit var appLanguageLocaleHandler: AppLanguageLocaleHandler
@@ -321,7 +326,6 @@ class HomeActivityTest {
}
}
- @DisableAccessibilityChecks
@Test
fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_spotlightNeverSeenBefore_checkSpotlightShown() {
logIntoUserTwice()
@@ -331,7 +335,6 @@ class HomeActivityTest {
}
}
- @DisableAccessibilityChecks
@Test
fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_pressDone_checkSpotlightIsNotShownAgain() {
logIntoUserTwice()
@@ -348,7 +351,6 @@ class HomeActivityTest {
}
}
- @DisableAccessibilityChecks
@Test
fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_checkNotShownOnFirstLogin() {
launch(createHomeActivityIntent(internalProfileId1)).use {
@@ -779,6 +781,7 @@ class HomeActivityTest {
@Test
fun testHomeActivity_clickViewAll_opensRecentlyPlayedActivity() {
+ markSpotlightSeen(profileId1)
fakeOppiaClock.setFakeTimeMode(FakeOppiaClock.FakeTimeMode.MODE_UPTIME_MILLIS)
storyProgressTestHelper.markInProgressSavedFractionsStory0Exp0(
profileId = profileId1,
@@ -906,6 +909,7 @@ class HomeActivityTest {
@Test
fun testHomeActivity_clickPromotedStory_opensTopicActivity() {
+ markSpotlightSeen(profileId1)
fakeOppiaClock.setFakeTimeMode(FakeOppiaClock.FakeTimeMode.MODE_UPTIME_MILLIS)
storyProgressTestHelper.markInProgressSavedFractionsStory0Exp0(
profileId = profileId1,
@@ -955,6 +959,7 @@ class HomeActivityTest {
@Test
fun testHomeActivity_firstTestTopic_topicSummary_opensTopicActivityThroughPlayIntent() {
logIntoUserTwice()
+ markSpotlightSeen(profileId1)
launch(createHomeActivityIntent(internalProfileId1)).use {
testCoroutineDispatchers.runCurrent()
scrollToPosition(5)
@@ -1125,6 +1130,7 @@ class HomeActivityTest {
@Test
fun testHomeActivity_clickTopicSummary_opensTopicActivity() {
logIntoUserTwice()
+ markSpotlightSeen(profileId1)
launch(createHomeActivityIntent(internalProfileId1)).use {
testCoroutineDispatchers.runCurrent()
scrollToPosition(position = 3)
@@ -1344,6 +1350,7 @@ class HomeActivityTest {
fun testHomeActivity_noTopicsStarted_tabletPortraitDisplaysTopicsIn3Columns() {
// Only new users will have no progress for any topics.
logIntoAdminTwice()
+ markSpotlightSeen(profileId)
launch(createHomeActivityIntent(internalProfileId)).use {
testCoroutineDispatchers.runCurrent()
verifyHomeRecyclerViewHasGridColumnCount(columnCount = 3)
@@ -1359,6 +1366,7 @@ class HomeActivityTest {
fun testHomeActivity_noTopicsStarted_tabletLandscapeDisplaysTopicsIn4Columns() {
// Only new users will have no progress for any topics.
logIntoAdminTwice()
+ markSpotlightSeen(profileId)
launch(createHomeActivityIntent(internalProfileId)).use {
testCoroutineDispatchers.runCurrent()
onView(isRoot()).perform(orientationLandscape())
@@ -1733,6 +1741,11 @@ class HomeActivityTest {
}
}
+ private fun markSpotlightSeen(profileId: ProfileId) {
+ spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.PROMOTED_STORIES)
+ testCoroutineDispatchers.runCurrent()
+ }
+
private fun createHomeActivityIntent(profileId: Int): Intent {
return HomeActivity.createHomeActivity(context, profileId)
}
From 4164c1ea14534ed136212c93ce609ee9b66da437 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 17 Nov 2022 04:39:07 +0530
Subject: [PATCH 082/138] re adjust test
---
.../org/oppia/android/app/topic/TopicFragmentTest.kt | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
index 803b369e5fb..c610c2062c6 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
@@ -265,8 +265,9 @@ class TopicFragmentTest {
markFirstChapterSpotlightSeen()
markLessonsTabSpotlightSeen()
val profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
- storyProgressTestHelper.markCompletedRatiosStory0(profileId, false)
- storyProgressTestHelper.markCompletedRatiosStory1(profileId, false)
+ storyProgressTestHelper.markCompletedFractionsStory0Exp0(profileId, false)
+ storyProgressTestHelper.markCompletedRatiosStory0Exp0(profileId, false)
+ storyProgressTestHelper.markCompletedRatiosStory1Exp0(profileId, false)
testCoroutineDispatchers.runCurrent()
launch(createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)).use {
// mark lessons spotlight seen
@@ -295,8 +296,9 @@ class TopicFragmentTest {
markFirstChapterSpotlightSeen()
val profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
fakeOppiaClock.setFakeTimeMode(FakeOppiaClock.FakeTimeMode.MODE_UPTIME_MILLIS)
- storyProgressTestHelper.markCompletedRatiosStory0(profileId, false)
- storyProgressTestHelper.markCompletedRatiosStory1(profileId, false)
+ storyProgressTestHelper.markCompletedFractionsStory0Exp0(profileId, false)
+ storyProgressTestHelper.markCompletedRatiosStory0Exp0(profileId, false)
+ storyProgressTestHelper.markCompletedRatiosStory1Exp0(profileId, false)
launch(createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)).use {
testCoroutineDispatchers.runCurrent()
// mark revision tab spotlight seen
From 9543ce12f5caa9ee077df63012de7182ef68e36d Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 17 Nov 2022 20:54:52 +0530
Subject: [PATCH 083/138] setup tests for spotlight fragment
---
.../testing/SpotlightFragmentTestActivity.kt | 37 +-
.../SpotlightFragmentTestActivityPresenter.kt | 42 ++
.../spotlight_fragment_test_activity.xml | 25 ++
.../app/spotlight/SpotlightFragmentTest.kt | 372 ++++++++++++++++++
4 files changed, 475 insertions(+), 1 deletion(-)
create mode 100644 app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt
create mode 100644 app/src/main/res/layout/spotlight_fragment_test_activity.xml
create mode 100644 app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
diff --git a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
index d502ade9d4f..ccacd8e927f 100644
--- a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
+++ b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
@@ -1,4 +1,39 @@
package org.oppia.android.app.testing
-class SpotlightFragmentTestActivity {
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import javax.inject.Inject
+import org.oppia.android.app.activity.ActivityComponentImpl
+import org.oppia.android.app.testing.activity.TestActivity
+import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
+
+class SpotlightFragmentTestActivity : TestActivity() {
+
+ @Inject
+ lateinit var spotlightFragmentTestActivityPresenter: SpotlightFragmentTestActivityPresenter
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ (activityComponent as ActivityComponentImpl).inject(this)
+
+ spotlightFragmentTestActivityPresenter.handleOnCreate(
+ intent.getIntExtra(
+ PROFILE_ID_ARGUMENT_KEY, -1
+ )
+ )
+ }
+
+ fun getSpotlightFragment() = spotlightFragmentTestActivityPresenter.getSpotlightFragment()
+
+ fun getSampleSpotlightTarget() = spotlightFragmentTestActivityPresenter.getSampleSpotlightTarget()
+
+ companion object {
+ /** Returns the [Intent] for opening [SpotlightFragmentTestActivity]. */
+ fun createSpotlightFragmentTestActivity(context: Context): Intent {
+ return Intent(context, SpotlightFragmentTestActivity::class.java).also {
+ it.putExtra(PROFILE_ID_ARGUMENT_KEY, 0)
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt
new file mode 100644
index 00000000000..284eff4afeb
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt
@@ -0,0 +1,42 @@
+package org.oppia.android.app.testing
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import javax.inject.Inject
+import org.oppia.android.R
+import org.oppia.android.app.activity.ActivityScope
+import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
+import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
+import org.oppia.android.databinding.SpotlightFragmentTestActivityBinding
+
+@ActivityScope
+class SpotlightFragmentTestActivityPresenter @Inject constructor(
+ private val activity: AppCompatActivity
+ ) {
+
+ private lateinit var binding: SpotlightFragmentTestActivityBinding
+
+ fun handleOnCreate(internalProfileId: Int) {
+ activity.setContentView(R.layout.spotlight_fragment_test_activity)
+
+ if (getSpotlightFragment() == null) {
+ val spotlightFragment = SpotlightFragment()
+ val args = Bundle()
+ args.putInt(PROFILE_ID_ARGUMENT_KEY, internalProfileId)
+ spotlightFragment.arguments = args
+ activity.supportFragmentManager.beginTransaction().add(
+ R.id.test_spotlight_overlay_placeholder,
+ spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
+ ).commitNow()
+ }
+ }
+
+ fun getSpotlightFragment(): SpotlightFragment? {
+ return activity.supportFragmentManager.findFragmentByTag(
+ SPOTLIGHT_FRAGMENT_TAG
+ ) as SpotlightFragment?
+ }
+
+ fun getSampleSpotlightTarget() = binding.sampleSpotlightTarget
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/spotlight_fragment_test_activity.xml b/app/src/main/res/layout/spotlight_fragment_test_activity.xml
new file mode 100644
index 00000000000..4ef5945233a
--- /dev/null
+++ b/app/src/main/res/layout/spotlight_fragment_test_activity.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
new file mode 100644
index 00000000000..1788dd1ccab
--- /dev/null
+++ b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
@@ -0,0 +1,372 @@
+package org.oppia.android.app.spotlight
+
+import android.app.Application
+import android.content.Context
+import android.content.Intent
+import android.text.Spannable
+import androidx.appcompat.app.AppCompatActivity
+import androidx.test.core.app.ActivityScenario.launch
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.espresso.Espresso.onView
+import androidx.test.espresso.action.ViewActions.click
+import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
+import androidx.test.espresso.assertion.ViewAssertions.matches
+import androidx.test.espresso.intent.Intents
+import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
+import androidx.test.espresso.matcher.ViewMatchers.withId
+import androidx.test.espresso.matcher.ViewMatchers.withText
+import androidx.test.ext.junit.rules.ActivityScenarioRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import dagger.Component
+import javax.inject.Inject
+import javax.inject.Singleton
+import kotlin.reflect.KClass
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.RuleChain
+import org.junit.rules.TestRule
+import org.junit.runner.RunWith
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+import org.oppia.android.R
+import org.oppia.android.app.activity.ActivityComponent
+import org.oppia.android.app.activity.ActivityComponentFactory
+import org.oppia.android.app.activity.route.ActivityRouterModule
+import org.oppia.android.app.application.ApplicationComponent
+import org.oppia.android.app.application.ApplicationInjector
+import org.oppia.android.app.application.ApplicationInjectorProvider
+import org.oppia.android.app.application.ApplicationModule
+import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
+import org.oppia.android.app.devoptions.DeveloperOptionsModule
+import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
+import org.oppia.android.app.model.Spotlight
+import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
+import org.oppia.android.app.shim.ViewBindingShimModule
+import org.oppia.android.app.testing.SpotlightFragmentTestActivity
+import org.oppia.android.app.testing.SpotlightFragmentTestActivity.Companion.createSpotlightFragmentTestActivity
+import org.oppia.android.app.translation.AppLanguageLocaleHandler
+import org.oppia.android.app.translation.testing.ActivityRecreatorTestModule
+import org.oppia.android.app.utility.clickPoint
+import org.oppia.android.data.backends.gae.NetworkConfigProdModule
+import org.oppia.android.data.backends.gae.NetworkModule
+import org.oppia.android.domain.classify.InteractionsModule
+import org.oppia.android.domain.classify.rules.algebraicexpressioninput.AlgebraicExpressionInputModule
+import org.oppia.android.domain.classify.rules.continueinteraction.ContinueModule
+import org.oppia.android.domain.classify.rules.dragAndDropSortInput.DragDropSortInputModule
+import org.oppia.android.domain.classify.rules.fractioninput.FractionInputModule
+import org.oppia.android.domain.classify.rules.imageClickInput.ImageClickInputModule
+import org.oppia.android.domain.classify.rules.itemselectioninput.ItemSelectionInputModule
+import org.oppia.android.domain.classify.rules.mathequationinput.MathEquationInputModule
+import org.oppia.android.domain.classify.rules.multiplechoiceinput.MultipleChoiceInputModule
+import org.oppia.android.domain.classify.rules.numberwithunits.NumberWithUnitsRuleModule
+import org.oppia.android.domain.classify.rules.numericexpressioninput.NumericExpressionInputModule
+import org.oppia.android.domain.classify.rules.numericinput.NumericInputRuleModule
+import org.oppia.android.domain.classify.rules.ratioinput.RatioInputModule
+import org.oppia.android.domain.classify.rules.textinput.TextInputRuleModule
+import org.oppia.android.domain.exploration.ExplorationStorageModule
+import org.oppia.android.domain.hintsandsolution.HintsAndSolutionConfigModule
+import org.oppia.android.domain.hintsandsolution.HintsAndSolutionProdModule
+import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
+import org.oppia.android.domain.oppialogger.LogStorageModule
+import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
+import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
+import org.oppia.android.domain.oppialogger.analytics.CpuPerformanceSnapshotterModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
+import org.oppia.android.domain.platformparameter.PlatformParameterModule
+import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
+import org.oppia.android.domain.question.QuestionModule
+import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
+import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule
+import org.oppia.android.testing.OppiaTestRule
+import org.oppia.android.testing.TestImageLoaderModule
+import org.oppia.android.testing.TestLogReportingModule
+import org.oppia.android.testing.junit.InitializeDefaultLocaleRule
+import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.threading.TestCoroutineDispatchers
+import org.oppia.android.testing.threading.TestDispatcherModule
+import org.oppia.android.testing.time.FakeOppiaClockModule
+import org.oppia.android.util.accessibility.AccessibilityTestModule
+import org.oppia.android.util.caching.AssetModule
+import org.oppia.android.util.caching.testing.CachingTestModule
+import org.oppia.android.util.gcsresource.DefaultResourceBucketName
+import org.oppia.android.util.gcsresource.GcsResourceModule
+import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
+import org.oppia.android.util.logging.LoggerModule
+import org.oppia.android.util.logging.SyncStatusModule
+import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
+import org.oppia.android.util.networking.NetworkConnectionDebugUtilModule
+import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
+import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule
+import org.oppia.android.util.parser.image.ImageParsingModule
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+
+/** Tests for [SpotlightFragment]. */
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(
+ application = SpotlightFragmentTest.TestApplication::class,
+ qualifiers = "port-xxhdpi"
+)
+class SpotlightFragmentTest {
+
+ private val initializeDefaultLocaleRule by lazy { InitializeDefaultLocaleRule() }
+
+ @Inject
+ lateinit var context: Context
+
+ @get:Rule
+ val oppiaTestRule = OppiaTestRule()
+
+ @field:[Rule JvmField]
+ val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
+ @Inject
+ lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
+
+ @Inject
+ lateinit var appLanguageLocaleHandler: AppLanguageLocaleHandler
+
+ @Inject
+ @field:DefaultResourceBucketName
+ lateinit var resourceBucketName: String
+
+ @get:Rule
+ var activityScenarioRule: ActivityScenarioRule =
+ ActivityScenarioRule(
+ Intent(
+ ApplicationProvider.getApplicationContext(),
+ SpotlightFragmentTestActivity::class.java
+ )
+ )
+
+ // Note that the locale rule must be initialized first since the scenario rule can depend on the
+ // locale being initialized.
+ @get:Rule
+ val chain: TestRule =
+ RuleChain.outerRule(initializeDefaultLocaleRule).around(activityScenarioRule)
+
+ private val sampleSpotlightText = "Sample spotlight hint text"
+ private val sampleSecondSpotlightText = "Sample hint text for second spotlight"
+
+ @Before
+ fun setUp() {
+ Intents.init()
+ setUpTestApplicationComponent()
+ testCoroutineDispatchers.registerIdlingResource()
+ }
+
+ @After
+ fun tearDown() {
+ Intents.release()
+ testCoroutineDispatchers.unregisterIdlingResource()
+ }
+
+ @Test
+ fun testSpotlightFragment_requestSpotlight_shouldShowSpotlight() {
+ launch(
+ createSpotlightFragmentTestActivity(ApplicationProvider.getApplicationContext())
+ ).use {
+ testCoroutineDispatchers.runCurrent()
+ it.onActivity { activity ->
+ val spotlightTarget = SpotlightTarget(
+ activity.getSampleSpotlightTarget(),
+ sampleSpotlightText,
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.PROMOTED_STORIES
+ )
+
+ checkNotNull(activity.getSpotlightFragment()).requestSpotlight(spotlightTarget)
+ testCoroutineDispatchers.runCurrent()
+ }
+ onView(withText(sampleSpotlightText)).check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testSpotlightFragment_requestDelayedSpotlight_shouldShowSpotlight() {
+ launch(
+ createSpotlightFragmentTestActivity(ApplicationProvider.getApplicationContext())
+ ).use {
+ testCoroutineDispatchers.runCurrent()
+ it.onActivity { activity ->
+ val spotlightTarget = SpotlightTarget(
+ activity.getSampleSpotlightTarget(),
+ sampleSpotlightText,
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.PROMOTED_STORIES
+ )
+
+ checkNotNull(
+ activity.getSpotlightFragment()
+ ).requestSpotlightViewWithDelayedLayout(spotlightTarget)
+ testCoroutineDispatchers.runCurrent()
+ }
+ onView(withText(sampleSpotlightText)).check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testSpotlightFragment_markSpotlightSeen_checkSpotlightIsNotShowAgain() {
+ launch(
+ createSpotlightFragmentTestActivity(ApplicationProvider.getApplicationContext())
+ ).use {
+ it.onActivity { activity->
+ val spotlightTarget = SpotlightTarget(
+ activity.getSampleSpotlightTarget(),
+ sampleSpotlightText,
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.PROMOTED_STORIES
+ )
+
+ checkNotNull(activity.getSpotlightFragment()).requestSpotlight(spotlightTarget)
+ testCoroutineDispatchers.runCurrent()
+ }
+ onView(withId(R.id.close_target)).perform(click())
+ }
+
+ launch(
+ createSpotlightFragmentTestActivity(ApplicationProvider.getApplicationContext())
+ ).use {
+ it.onActivity { activity->
+ val spotlightTarget = SpotlightTarget(
+ activity.getSampleSpotlightTarget(),
+ sampleSpotlightText,
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.PROMOTED_STORIES
+ )
+
+ checkNotNull(activity.getSpotlightFragment()).requestSpotlight(spotlightTarget)
+ testCoroutineDispatchers.runCurrent()
+ }
+ onView(withText(sampleSpotlightText)).check(doesNotExist())
+ }
+ }
+
+ @Test
+ fun testSpotlightQueuing_requestTwoSpotlights_checkFirstSpotlightShown() {
+ launch(
+ createSpotlightFragmentTestActivity(ApplicationProvider.getApplicationContext())
+ ).use {
+ testCoroutineDispatchers.runCurrent()
+ it.onActivity { activity ->
+ val firstSpotlightTarget = SpotlightTarget(
+ activity.getSampleSpotlightTarget(),
+ sampleSpotlightText,
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.PROMOTED_STORIES
+ )
+
+ val secondSpotlightTarget = SpotlightTarget(
+ activity.getSampleSpotlightTarget(),
+ sampleSecondSpotlightText,
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.FIRST_CHAPTER
+ )
+
+ checkNotNull(activity.getSpotlightFragment()).requestSpotlight(firstSpotlightTarget)
+ testCoroutineDispatchers.runCurrent()
+ checkNotNull(activity.getSpotlightFragment()).requestSpotlight(secondSpotlightTarget)
+ testCoroutineDispatchers.runCurrent()
+ }
+ onView(withText(sampleSpotlightText)).check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testSpotlightQueuing_requestTwoSpotlights_pressDone_checkSecondSpotlightShown() {
+ launch(
+ createSpotlightFragmentTestActivity(ApplicationProvider.getApplicationContext())
+ ).use {
+ testCoroutineDispatchers.runCurrent()
+ it.onActivity { activity ->
+ val firstSpotlightTarget = SpotlightTarget(
+ activity.getSampleSpotlightTarget(),
+ sampleSpotlightText,
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.PROMOTED_STORIES
+ )
+
+ val secondSpotlightTarget = SpotlightTarget(
+ activity.getSampleSpotlightTarget(),
+ sampleSecondSpotlightText,
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.FIRST_CHAPTER
+ )
+
+ checkNotNull(activity.getSpotlightFragment()).requestSpotlight(firstSpotlightTarget)
+ testCoroutineDispatchers.runCurrent()
+ checkNotNull(activity.getSpotlightFragment()).requestSpotlight(secondSpotlightTarget)
+ testCoroutineDispatchers.runCurrent()
+ }
+ onView(withId(R.id.close_target)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+ onView(withText(sampleSecondSpotlightText)).check(matches(isDisplayed()))
+ }
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ // TODO(#59): Figure out a way to reuse modules instead of needing to re-declare them.
+ @Singleton
+ @Component(
+ modules = [
+ RobolectricModule::class,
+ PlatformParameterModule::class, PlatformParameterSingletonModule::class,
+ TestDispatcherModule::class, ApplicationModule::class,
+ LoggerModule::class, ContinueModule::class, FractionInputModule::class,
+ ItemSelectionInputModule::class, MultipleChoiceInputModule::class,
+ NumberWithUnitsRuleModule::class, NumericInputRuleModule::class, TextInputRuleModule::class,
+ DragDropSortInputModule::class, ImageClickInputModule::class, InteractionsModule::class,
+ GcsResourceModule::class, TestImageLoaderModule::class, ImageParsingModule::class,
+ HtmlParserEntityTypeModule::class, QuestionModule::class, TestLogReportingModule::class,
+ AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
+ PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
+ ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
+ HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
+ FirebaseLogUploaderModule::class, FakeOppiaClockModule::class,
+ DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
+ ExplorationStorageModule::class, NetworkModule::class, NetworkConfigProdModule::class,
+ NetworkConnectionUtilDebugModule::class, NetworkConnectionDebugUtilModule::class,
+ AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
+ NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
+ MathEquationInputModule::class, SplitScreenInteractionModule::class,
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class, ActivityRouterModule::class,
+ CpuPerformanceSnapshotterModule::class
+ ]
+ )
+ interface TestApplicationComponent : ApplicationComponent {
+ @Component.Builder
+ interface Builder : ApplicationComponent.Builder
+
+ fun inject(spotlightFragmentTest: SpotlightFragmentTest)
+ }
+
+ class TestApplication : Application(), ActivityComponentFactory, ApplicationInjectorProvider {
+ private val component: TestApplicationComponent by lazy {
+ DaggerSpotlightFragmentTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build() as TestApplicationComponent
+ }
+
+ fun inject(spotlightFragmentTest: SpotlightFragmentTest) {
+ component.inject(spotlightFragmentTest)
+ }
+
+ override fun createActivityComponent(activity: AppCompatActivity): ActivityComponent {
+ return component.getActivityComponentBuilderProvider().get().setActivity(activity).build()
+ }
+
+ override fun getApplicationInjector(): ApplicationInjector = component
+ }
+}
\ No newline at end of file
From 385fe76d739f51629b8bb669cc6006b95f1ea204 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 17 Nov 2022 21:58:52 +0530
Subject: [PATCH 084/138] add kdocs
---
.../app/spotlight/SpotlightFragment.kt | 32 ++++++++++++++++++-
.../android/app/spotlight/SpotlightShape.kt | 1 +
.../android/app/spotlight/SpotlightTarget.kt | 8 +++++
3 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 453324011f5..ad8b3cad862 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -37,6 +37,11 @@ import java.util.LinkedList
import java.util.Locale
import javax.inject.Inject
+/**
+ * Fragment to hold the spotlights on elements. This fragments provides a single place for all the spotlight
+ * interactions, and handles lifecycle related functionality for spotlights, such as surviving orientation changes
+ * and marking spotlights as seen.
+ */
class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
@Inject
lateinit var activity: AppCompatActivity
@@ -64,6 +69,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
screenWidth = displayMetrics.widthPixels
}
+ /** LiveData to monitor spotlight activity status. */
fun getSpotlightStatusLiveData(): MutableLiveData {
return isSpotlightActive
}
@@ -78,6 +84,16 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
checkIsRTL()
}
+ /**
+ * Requests a spotlight to be shown on the [SpotlightTarget]. The spotlight is enqueued if it
+ * hasn't been shown before in a FIFO buffer. This API can ensure proper spotlighting of a [SpotlightTarget]
+ * which is laid out after an animation. For the spotlights to work correctly, we must know the
+ * [SpotlightTarget]'s anchor's size and position. For a view that is laid out after an animation, we must
+ * wait until the final size and positions of the anchor view are measured, which can be achieved by using
+ * doOnPreDraw (refer: https://betterprogramming.pub/stop-using-post-postdelayed-in-your-android-views-9d1c8eeaadf2).
+ *
+ * @param spotlightTarget The [SpotlightTarget] for which the spotlight is requested
+ */
fun requestSpotlightViewWithDelayedLayout(spotlightTarget: SpotlightTarget) {
spotlightTarget.anchor.doOnPreDraw {
if (it.visibility != View.VISIBLE) {
@@ -93,6 +109,16 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
}
}
+ /**
+ * Requests a spotlight to be shown on the first item of a recycler view. The API is designed to work
+ * with custom views used as recycler view items. [requestSpotlightViewWithDelayedLayout] should be used
+ * as a replacement for this API, since we must wait for the views to be laid out first (for which
+ * onPreDraw is used), and only then the index of the item should be checked for the spotlight to work correctly.
+ *
+ * @param customView The custom view being used as the recycler view item
+ * @param index The position of the custom view object inside the recycler view
+ * @param spotlightTarget The [SpotlightTarget] for which the spotlight is requested
+ */
fun requestSpotlightOnFirstRecyclerItem(customView: View, index: Int, spotlightTarget: SpotlightTarget) {
customView.doOnPreDraw {
if (index == 0) {
@@ -109,7 +135,11 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
/**
* Requests a spotlight to be shown on the [SpotlightTarget]. The spotlight is enqueued if it
- * hasn't been shown before in a FIFO buffer.
+ * hasn't been shown before in a FIFO buffer. This API can ensure proper spotlighting of a [SpotlightTarget]
+ * when it is laid out late due to a data provider call. It cannot ensure the same if the view has to be
+ * spotlight immediately after an animation. It also cannot spotlight targets which are a part of a
+ * recycler view which are laid out after a data provider call. If TalkBack is turned on, no spotlight shall
+ * be shown.
*
* @param spotlightTarget The [SpotlightTarget] for which the spotlight is requested
*/
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt
index fda6c4dcb91..37cf4c3d38c 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt
@@ -1,5 +1,6 @@
package org.oppia.android.app.spotlight
+/** The shape of the overlay screen cutout surrounding the spotlit view. */
sealed class SpotlightShape {
object RoundedRectangle : SpotlightShape()
object Circle : SpotlightShape()
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
index ff7352efdb9..eaff01571e5 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
@@ -2,6 +2,14 @@ package org.oppia.android.app.spotlight
import android.view.View
+/**
+ * Data class to hold a [SpotlightTarget].
+ *
+ * @param anchor the view that should be spotlit
+ * @param hint the hint text that should be shown on the spotlight overlay
+ * @param shape [SpotlightShape] of the spotlight
+ * @param feature The [Spotlight] feature-case corresponding to the spotlight target
+ */
data class SpotlightTarget(
val anchor: View,
val hint: String = "",
From 03caa7847ad12a761bd3d657f5c486b8059a46a5 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 18 Nov 2022 00:24:15 +0530
Subject: [PATCH 085/138] use correct test configuration
---
app/src/main/AndroidManifest.xml | 4 ++
.../app/activity/ActivityComponentImpl.kt | 2 +
.../SpotlightFragmentTestActivityPresenter.kt | 3 +-
.../app/spotlight/SpotlightFragmentTest.kt | 48 +++++++------------
4 files changed, 26 insertions(+), 31 deletions(-)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 1f2250c4152..cad3ad03568 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -36,6 +36,10 @@
android:name=".app.testing.AdministratorControlsFragmentTestActivity"
android:label="@string/administrator_controls_fragment_test_activity_label"
android:theme="@style/OppiaThemeWithoutActionBar" />
+
=
- ActivityScenarioRule(
- Intent(
- ApplicationProvider.getApplicationContext(),
- SpotlightFragmentTestActivity::class.java
- )
- )
-
- // Note that the locale rule must be initialized first since the scenario rule can depend on the
- // locale being initialized.
- @get:Rule
- val chain: TestRule =
- RuleChain.outerRule(initializeDefaultLocaleRule).around(activityScenarioRule)
+// @get:Rule
+// var activityScenarioRule: ActivityScenarioRule =
+// ActivityScenarioRule(
+// Intent(
+// ApplicationProvider.getApplicationContext(),
+// SpotlightFragmentTestActivity::class.java
+// )
+// )
private val sampleSpotlightText = "Sample spotlight hint text"
private val sampleSecondSpotlightText = "Sample hint text for second spotlight"
@@ -170,7 +158,7 @@ class SpotlightFragmentTest {
@Test
fun testSpotlightFragment_requestSpotlight_shouldShowSpotlight() {
launch(
- createSpotlightFragmentTestActivity(ApplicationProvider.getApplicationContext())
+ createSpotlightFragmentTestActivity(context)
).use {
testCoroutineDispatchers.runCurrent()
it.onActivity { activity ->
@@ -191,7 +179,7 @@ class SpotlightFragmentTest {
@Test
fun testSpotlightFragment_requestDelayedSpotlight_shouldShowSpotlight() {
launch(
- createSpotlightFragmentTestActivity(ApplicationProvider.getApplicationContext())
+ createSpotlightFragmentTestActivity(context)
).use {
testCoroutineDispatchers.runCurrent()
it.onActivity { activity ->
@@ -205,8 +193,8 @@ class SpotlightFragmentTest {
checkNotNull(
activity.getSpotlightFragment()
).requestSpotlightViewWithDelayedLayout(spotlightTarget)
- testCoroutineDispatchers.runCurrent()
}
+ testCoroutineDispatchers.advanceUntilIdle()
onView(withText(sampleSpotlightText)).check(matches(isDisplayed()))
}
}
@@ -214,7 +202,7 @@ class SpotlightFragmentTest {
@Test
fun testSpotlightFragment_markSpotlightSeen_checkSpotlightIsNotShowAgain() {
launch(
- createSpotlightFragmentTestActivity(ApplicationProvider.getApplicationContext())
+ createSpotlightFragmentTestActivity(context)
).use {
it.onActivity { activity->
val spotlightTarget = SpotlightTarget(
@@ -231,9 +219,9 @@ class SpotlightFragmentTest {
}
launch(
- createSpotlightFragmentTestActivity(ApplicationProvider.getApplicationContext())
+ createSpotlightFragmentTestActivity(context)
).use {
- it.onActivity { activity->
+ it.onActivity { activity ->
val spotlightTarget = SpotlightTarget(
activity.getSampleSpotlightTarget(),
sampleSpotlightText,
@@ -251,7 +239,7 @@ class SpotlightFragmentTest {
@Test
fun testSpotlightQueuing_requestTwoSpotlights_checkFirstSpotlightShown() {
launch(
- createSpotlightFragmentTestActivity(ApplicationProvider.getApplicationContext())
+ createSpotlightFragmentTestActivity(context)
).use {
testCoroutineDispatchers.runCurrent()
it.onActivity { activity ->
@@ -281,7 +269,7 @@ class SpotlightFragmentTest {
@Test
fun testSpotlightQueuing_requestTwoSpotlights_pressDone_checkSecondSpotlightShown() {
launch(
- createSpotlightFragmentTestActivity(ApplicationProvider.getApplicationContext())
+ createSpotlightFragmentTestActivity(context)
).use {
testCoroutineDispatchers.runCurrent()
it.onActivity { activity ->
From 10e0acaad6889feb549882ee3da59eee3ecb8799 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 18 Nov 2022 04:12:53 +0530
Subject: [PATCH 086/138] suggetive fixes
---
...pterNotStartedContainerConstraintLayout.kt | 4 +-
.../app/customview/PromotedStoryCardView.kt | 4 +-
.../app/spotlight/SpotlightFragment.kt | 62 ++++++-------------
app/src/main/res/values/dimens.xml | 3 +
4 files changed, 27 insertions(+), 46 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index 8d842765acc..cb918cceb39 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -54,7 +54,9 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
context.getString(R.string.first_chapter_spotlight_hint),
feature = Spotlight.FeatureCase.FIRST_CHAPTER
)
- checkNotNull(getSpotlightFragment()).requestSpotlightOnFirstRecyclerItem(this, index, spotlightTarget)
+ if (index == 0) {
+ checkNotNull(getSpotlightFragment()).requestSpotlightViewWithDelayedLayout(spotlightTarget)
+ }
}
}
}
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
index 8d8f0e36573..c7c06eba190 100644
--- a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -45,7 +45,9 @@ class PromotedStoryCardView @JvmOverloads constructor(
context.getString(R.string.promoted_story_spotlight_hint),
feature = Spotlight.FeatureCase.PROMOTED_STORIES
)
- checkNotNull(getSpotlightFragment()).requestSpotlightOnFirstRecyclerItem(this, index, spotlightTarget)
+ if (index == 0) {
+ checkNotNull(getSpotlightFragment()).requestSpotlightViewWithDelayedLayout(spotlightTarget)
+ }
}
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index ad8b3cad862..697be419f9f 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -18,6 +18,8 @@ import com.takusemba.spotlight.Target
import com.takusemba.spotlight.shape.Circle
import com.takusemba.spotlight.shape.RoundedRectangle
import com.takusemba.spotlight.shape.Shape
+import java.util.*
+import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentComponentImpl
import org.oppia.android.app.fragment.InjectableFragment
@@ -33,9 +35,6 @@ import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.util.accessibility.AccessibilityServiceImpl
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
-import java.util.LinkedList
-import java.util.Locale
-import javax.inject.Inject
/**
* Fragment to hold the spotlights on elements. This fragments provides a single place for all the spotlight
@@ -109,30 +108,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
}
}
- /**
- * Requests a spotlight to be shown on the first item of a recycler view. The API is designed to work
- * with custom views used as recycler view items. [requestSpotlightViewWithDelayedLayout] should be used
- * as a replacement for this API, since we must wait for the views to be laid out first (for which
- * onPreDraw is used), and only then the index of the item should be checked for the spotlight to work correctly.
- *
- * @param customView The custom view being used as the recycler view item
- * @param index The position of the custom view object inside the recycler view
- * @param spotlightTarget The [SpotlightTarget] for which the spotlight is requested
- */
- fun requestSpotlightOnFirstRecyclerItem(customView: View, index: Int, spotlightTarget: SpotlightTarget) {
- customView.doOnPreDraw {
- if (index == 0) {
- val targetAfterViewFullyDrawn = SpotlightTarget(
- it,
- spotlightTarget.hint,
- spotlightTarget.shape,
- spotlightTarget.feature
- )
- requestSpotlight(targetAfterViewFullyDrawn)
- }
- }
- }
-
/**
* Requests a spotlight to be shown on the [SpotlightTarget]. The spotlight is enqueued if it
* hasn't been shown before in a FIFO buffer. This API can ensure proper spotlighting of a [SpotlightTarget]
@@ -354,15 +329,15 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
arrowParams.setMargins(
screenWidth - spotlightTarget.anchorLeft.toInt(),
(spotlightTarget.anchorTop.toInt() - getArrowHeight() - 5.dp).toInt(),
- 10.dp,
- 10.dp
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
} else {
arrowParams.setMargins(
spotlightTarget.anchorLeft.toInt(),
(spotlightTarget.anchorTop.toInt() - getArrowHeight() - 5.dp).toInt(),
- 10.dp,
- 10.dp
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
}
(overlayBinding as BottomLeftOverlayBinding).arrow.layoutParams = arrowParams
@@ -370,7 +345,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
return (overlayBinding as BottomLeftOverlayBinding).root
}
-
private fun configureBottomRightOverlay(spotlightTarget: SpotlightTarget): View {
Log.d("overlay", "bottom right overlay")
overlayBinding = BottomRightOverlayBinding.inflate(this.layoutInflater)
@@ -385,18 +359,18 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
as ViewGroup.MarginLayoutParams
if (isRTL) {
arrowParams.setMargins(
- 10.dp,
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
(spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
screenWidth -
(spotlightTarget.anchorLeft + getArrowWidth()).toInt(),
- 10.dp
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
} else {
arrowParams.setMargins(
(spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
(spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
- 10.dp,
- 10.dp
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
}
(overlayBinding as BottomRightOverlayBinding).arrow.layoutParams = arrowParams
@@ -419,17 +393,17 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
as ViewGroup.MarginLayoutParams
if (isRTL) {
arrowParams.setMargins(
- 10.dp,
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
(spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
screenWidth - (spotlightTarget.anchorLeft + getArrowWidth()).toInt(),
- 10.dp
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
} else {
arrowParams.setMargins(
(spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
(spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
- 10.dp,
- 10.dp
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
}
(overlayBinding as TopRightOverlayBinding).arrow.layoutParams = arrowParams
@@ -454,15 +428,15 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
arrowParams.setMargins(
screenWidth - spotlightTarget.anchorLeft.toInt(),
(spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
- 10.dp,
- 10.dp
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
} else {
arrowParams.setMargins(
spotlightTarget.anchorLeft.toInt(),
(spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
- 10.dp,
- 10.dp
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
}
(overlayBinding as TopLeftOverlayBinding).arrow.layoutParams = arrowParams
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 4638fd73a36..6e88b2e53c1 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -451,6 +451,9 @@
60dp
80dp
+
+ 10dp
+
80dp
60dp
From c6ecbf83ba2bccd882bfe7e449baf958f551dee0 Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Fri, 18 Nov 2022 07:05:22 +0530
Subject: [PATCH 087/138] add bazel config
add bazel config
---
WORKSPACE | 7 ++++
app/BUILD.bazel | 7 ++++
...pterNotStartedContainerConstraintLayout.kt | 9 +++---
.../app/customview/PromotedStoryCardView.kt | 19 +++--------
.../android/app/home/HomeActivityPresenter.kt | 4 +--
.../onboarding/OnboardingActivityPresenter.kt | 4 +--
.../onboarding/OnboardingFragmentPresenter.kt | 4 +--
.../player/audio/AudioFragmentPresenter.kt | 4 +--
.../ExplorationActivityPresenter.kt | 6 ++--
.../ExplorationFragmentPresenter.kt | 4 +--
.../oppia/android/app/spotlight/BUILD.bazel | 25 +++++++++++++++
.../app/spotlight/SpotlightFragment.kt | 21 ++++++------
.../android/app/spotlight/SpotlightManager.kt | 32 +++++++++++++++++++
.../SpotlightNavigationListener.kt | 2 +-
.../android/app/spotlight/SpotlightTarget.kt | 3 +-
.../SpotlightFragmentTestActivityPresenter.kt | 6 ++--
.../app/topic/TopicActivityPresenter.kt | 6 ++--
.../app/topic/TopicFragmentPresenter.kt | 3 +-
.../main/res/layout/bottom_left_overlay.xml | 6 ++--
.../main/res/layout/bottom_right_overlay.xml | 6 ++--
app/src/main/res/layout/top_left_overlay.xml | 6 ++--
app/src/main/res/layout/top_right_overlay.xml | 6 ++--
third_party/BUILD.bazel | 8 +++++
23 files changed, 133 insertions(+), 65 deletions(-)
create mode 100644 app/src/main/java/org/oppia/android/app/spotlight/BUILD.bazel
create mode 100644 app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt
rename app/src/main/java/org/oppia/android/app/{onboarding => spotlight}/SpotlightNavigationListener.kt (68%)
diff --git a/WORKSPACE b/WORKSPACE
index cb0f252e6d8..ef456170c0c 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -130,6 +130,13 @@ git_repository(
shallow_since = "1647295507 -0700",
)
+git_repository(
+ name = "android-spotlight",
+ commit = "1ba764bb9e3685947433f115120448910ef737ed",
+ remote = "https://github.com/oppia/android-spotlight",
+ shallow_since = "1667677977 -0500",
+)
+
# A custom fork of KotliTeX that removes resources artifacts that break the build, and updates the
# min target SDK version to be compatible with Oppia.
git_repository(
diff --git a/app/BUILD.bazel b/app/BUILD.bazel
index f07ec2229fb..b35ba3e9538 100644
--- a/app/BUILD.bazel
+++ b/app/BUILD.bazel
@@ -394,7 +394,9 @@ VIEW_MODELS = [
# keep sorted
VIEWS_WITH_RESOURCE_IMPORTS = [
+ "src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt",
"src/main/java/org/oppia/android/app/customview/LessonThumbnailImageView.kt",
+ "src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt",
"src/main/java/org/oppia/android/app/customview/SegmentedCircularProgressView.kt",
"src/main/java/org/oppia/android/app/customview/VerticalDashedLineView.kt",
"src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt",
@@ -575,6 +577,7 @@ android_library(
":resources",
":view_models",
":views",
+ "//app/src/main/java/org/oppia/android/app/spotlight",
"//app/src/main/java/org/oppia/android/app/translation:app_language_activity_injector_provider",
"//app/src/main/java/org/oppia/android/app/translation:app_language_resource_handler",
"//model/src/main/proto:interaction_object_java_proto_lite",
@@ -631,6 +634,7 @@ kt_android_library(
":snap_helper",
":view_models",
"//app/src/main/java/org/oppia/android/app/shim:view_binding_shim",
+ "//app/src/main/java/org/oppia/android/app/spotlight",
"//app/src/main/java/org/oppia/android/app/view:view_component_factory",
"//app/src/main/java/org/oppia/android/app/view:view_scope",
"//third_party:androidx_appcompat_appcompat",
@@ -745,6 +749,7 @@ kt_android_library(
"//app/src/main/java/org/oppia/android/app/fragment:FragmentComponentImpl.kt",
"//app/src/main/java/org/oppia/android/app/fragment:FragmentModule.kt",
"//app/src/main/java/org/oppia/android/app/view:ViewComponentBuilderModule.kt",
+ "//app/src/main/java/org/oppia/android/app/spotlight:SpotlightFragment_updated.kt",
],
custom_package = "org.oppia.android.app.ui",
enable_data_binding = 1,
@@ -779,6 +784,8 @@ kt_android_library(
"//third_party:androidx_viewpager2_viewpager2",
"//third_party:androidx_viewpager_viewpager",
"//third_party:com_caverock_androidsvg",
+ "//third_party:com_github_takusemba_spotlight",
+ "//domain/src/main/java/org/oppia/android/domain/spotlight:spotlight_state_controller",
"//third_party:com_google_android_flexbox_flexbox",
"//third_party:javax_annotation_javax_annotation-api_jar",
"//utility",
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index cb918cceb39..6caa76b98d2 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -8,9 +8,8 @@ import androidx.fragment.app.FragmentManager
import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.model.Spotlight
-import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.spotlight.SpotlightTarget
-import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
@@ -33,10 +32,10 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
this.index = index
}
- private fun getSpotlightFragment(): SpotlightFragment? {
+ private fun getSpotlightFragment(): SpotlightManager? {
return fragment.requireActivity().supportFragmentManager.findFragmentByTag(
- SPOTLIGHT_FRAGMENT_TAG
- ) as SpotlightFragment?
+ SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
+ ) as? SpotlightManager
}
override fun onAttachedToWindow() {
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
index c7c06eba190..edd21a2c048 100644
--- a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -5,13 +5,12 @@ import android.util.AttributeSet
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import com.google.android.material.card.MaterialCardView
-import org.oppia.android.app.spotlight.SpotlightFragment
-import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.model.Spotlight
+import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.spotlight.SpotlightTarget
class PromotedStoryCardView @JvmOverloads constructor(
@@ -28,16 +27,6 @@ class PromotedStoryCardView @JvmOverloads constructor(
private var isSpotlit = false
fun setIndex(index: Int) {
-// if (index == 0) {
-// val promotesStorySpotlightTarget = SpotlightTarget(
-// this,
-// "From now, here you can view stories you might be interested in",
-// SpotlightShape.RoundedRectangle,
-// Spotlight.FeatureCase.PROMOTED_STORIES
-// )
-// getSpotlightFragment().requestSpotlight(promotesStorySpotlightTarget)
-// }
-
if (!isSpotlit) {
isSpotlit = true
val spotlightTarget = SpotlightTarget(
@@ -52,10 +41,10 @@ class PromotedStoryCardView @JvmOverloads constructor(
}
- private fun getSpotlightFragment(): SpotlightFragment? {
+ private fun getSpotlightFragment(): SpotlightManager? {
return fragment.requireActivity().supportFragmentManager.findFragmentByTag(
- SPOTLIGHT_FRAGMENT_TAG
- ) as SpotlightFragment?
+ SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
+ ) as? SpotlightManager
}
override fun onAttachedToWindow() {
diff --git a/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
index 3673b81c988..9135b8f8d49 100644
--- a/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
@@ -10,8 +10,8 @@ import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.drawer.NavigationDrawerFragment
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
-import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import javax.inject.Inject
+import org.oppia.android.app.spotlight.SpotlightManager
const val TAG_HOME_FRAGMENT = "HOME_FRAGMENT"
@@ -38,7 +38,7 @@ class HomeActivityPresenter @Inject constructor(private val activity: AppCompatA
spotlightFragment.arguments = args
activity.supportFragmentManager.beginTransaction().add(
R.id.home_spotlight_fragment_placeholder,
- spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
+ spotlightFragment, SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
).commitNow()
}
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
index 9db8bfbb490..db15ccf7675 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
@@ -6,8 +6,8 @@ import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
import javax.inject.Inject
import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
-import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
/** The presenter for [OnboardingActivity]. */
@ActivityScope
@@ -28,7 +28,7 @@ class OnboardingActivityPresenter @Inject constructor(private val activity: AppC
spotlightFragment.arguments = args
activity.supportFragmentManager.beginTransaction().add(
R.id.onboarding_spotlight_fragment_placeholder,
- spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
+ spotlightFragment, SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
).commitNow()
}
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index 48e0fbb893f..e0a255124f2 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -24,9 +24,9 @@ import org.oppia.android.util.statusbar.StatusBarColor
import javax.inject.Inject
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
-import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
/** The presenter for [OnboardingFragment]. */
@FragmentScope
@@ -62,7 +62,7 @@ class OnboardingFragmentPresenter @Inject constructor(
private fun getSpotlightFragment(): SpotlightFragment {
return activity.supportFragmentManager.findFragmentByTag(
- SPOTLIGHT_FRAGMENT_TAG
+ SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
) as SpotlightFragment
}
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index 38c955e6496..d26189c60f1 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -24,9 +24,9 @@ import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.model.State
import org.oppia.android.app.player.audio.AudioViewModel.UiAudioPlayStatus
import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
-import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.AudioFragmentBinding
@@ -142,7 +142,7 @@ class AudioFragmentPresenter @Inject constructor(
private fun getSpotlightFragment(): SpotlightFragment {
return activity.supportFragmentManager.findFragmentByTag(
- SPOTLIGHT_FRAGMENT_TAG
+ SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
) as SpotlightFragment
}
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
index 0bf0f32e5af..2178358ef70 100644
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
@@ -23,7 +23,6 @@ import org.oppia.android.app.player.stopplaying.ProgressDatabaseFullDialogFragme
import org.oppia.android.app.player.stopplaying.UnsavedExplorationDialogFragment
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
-import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.app.topic.TopicActivity
import org.oppia.android.app.utility.FontScaleConfigurationUtil
import org.oppia.android.app.viewmodel.ViewModelProvider
@@ -35,6 +34,7 @@ import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import javax.inject.Inject
import org.oppia.android.app.model.Spotlight
+import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
@@ -140,7 +140,7 @@ class ExplorationActivityPresenter @Inject constructor(
spotlightFragment.arguments = args
activity.supportFragmentManager.beginTransaction().add(
R.id.exploration_spotlight_fragment_placeholder,
- spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
+ spotlightFragment, SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
).commitNow()
}
}
@@ -162,7 +162,7 @@ class ExplorationActivityPresenter @Inject constructor(
private fun getSpotlightFragment(): SpotlightFragment? {
return activity.supportFragmentManager.findFragmentByTag(
- SPOTLIGHT_FRAGMENT_TAG
+ SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
) as SpotlightFragment?
}
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index db1b4279d05..f668bec91dd 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -16,9 +16,9 @@ import org.oppia.android.app.model.ReadingTextSize
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.player.state.StateFragment
import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
-import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.app.utility.FontScaleConfigurationUtil
import org.oppia.android.databinding.ExplorationFragmentBinding
import org.oppia.android.domain.oppialogger.OppiaLogger
@@ -106,7 +106,7 @@ class ExplorationFragmentPresenter @Inject constructor(
private fun getSpotlightFragment(): SpotlightFragment? {
return fragment.requireActivity().supportFragmentManager.findFragmentByTag(
- SPOTLIGHT_FRAGMENT_TAG
+ SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
) as SpotlightFragment?
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/BUILD.bazel b/app/src/main/java/org/oppia/android/app/spotlight/BUILD.bazel
new file mode 100644
index 00000000000..fc04a936671
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/spotlight/BUILD.bazel
@@ -0,0 +1,25 @@
+load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library")
+
+genrule(
+ name = "update_SpotlightFragment",
+ srcs = ["SpotlightFragment.kt"],
+ outs = ["SpotlightFragment_updated.kt"],
+ cmd = """
+ cat $(SRCS) |
+ sed 's/import org.oppia.android.R/import org.oppia.android.app.R/g' |
+ sed 's/import org.oppia.android.databinding./import org.oppia.android.app.databinding.databinding./g' > $(OUTS)
+ """,
+ visibility = ["//app:app_visibility"],
+)
+
+kt_android_library(
+ name = "spotlight",
+ srcs = [
+ "SpotlightManager.kt",
+ "SpotlightNavigationListener.kt",
+ "SpotlightShape.kt",
+ "SpotlightTarget.kt",
+ ],
+ visibility = ["//app:app_visibility"],
+ deps = ["//model/src/main/proto:spotlight_java_proto_lite"],
+)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 697be419f9f..fc3dffbe3bd 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -25,14 +25,13 @@ import org.oppia.android.app.fragment.FragmentComponentImpl
import org.oppia.android.app.fragment.InjectableFragment
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.SpotlightViewState
-import org.oppia.android.app.onboarding.SpotlightNavigationListener
import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
import org.oppia.android.databinding.BottomLeftOverlayBinding
import org.oppia.android.databinding.BottomRightOverlayBinding
import org.oppia.android.databinding.TopLeftOverlayBinding
import org.oppia.android.databinding.TopRightOverlayBinding
import org.oppia.android.domain.spotlight.SpotlightStateController
-import org.oppia.android.util.accessibility.AccessibilityServiceImpl
+import org.oppia.android.util.accessibility.AccessibilityService
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
@@ -41,7 +40,7 @@ import org.oppia.android.util.data.DataProviders.Companion.toLiveData
* interactions, and handles lifecycle related functionality for spotlights, such as surviving orientation changes
* and marking spotlights as seen.
*/
-class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
+class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, SpotlightManager {
@Inject
lateinit var activity: AppCompatActivity
@@ -49,7 +48,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
lateinit var spotlightStateController: SpotlightStateController
@Inject
- lateinit var accessibilityServiceImpl: AccessibilityServiceImpl
+ lateinit var accessibilityService: AccessibilityService
private var targetList = LinkedList()
private lateinit var spotlight: Spotlight
@@ -93,7 +92,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
*
* @param spotlightTarget The [SpotlightTarget] for which the spotlight is requested
*/
- fun requestSpotlightViewWithDelayedLayout(spotlightTarget: SpotlightTarget) {
+ override fun requestSpotlightViewWithDelayedLayout(spotlightTarget: SpotlightTarget) {
spotlightTarget.anchor.doOnPreDraw {
if (it.visibility != View.VISIBLE) {
return@doOnPreDraw
@@ -118,9 +117,9 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
*
* @param spotlightTarget The [SpotlightTarget] for which the spotlight is requested
*/
- fun requestSpotlight(spotlightTarget: SpotlightTarget) {
+ override fun requestSpotlight(spotlightTarget: SpotlightTarget) {
- if (accessibilityServiceImpl.isScreenReaderEnabled()) return
+ if (accessibilityService.isScreenReaderEnabled()) return
val profileId = ProfileId.newBuilder()
.setInternalId(internalProfileId)
@@ -318,7 +317,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
overlayBinding = BottomLeftOverlayBinding.inflate(this.layoutInflater)
(overlayBinding as BottomLeftOverlayBinding).let {
it.lifecycleOwner = this
- it.presenter = this
+ it.listener = this
}
(overlayBinding as BottomLeftOverlayBinding).customText.text = spotlightTarget.hint
@@ -350,7 +349,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
overlayBinding = BottomRightOverlayBinding.inflate(this.layoutInflater)
(overlayBinding as BottomRightOverlayBinding).let {
it.lifecycleOwner = this
- it.presenter = this
+ it.listener = this
}
(overlayBinding as BottomRightOverlayBinding).customText.text = spotlightTarget.hint
@@ -384,7 +383,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
overlayBinding = TopRightOverlayBinding.inflate(layoutInflater)
(overlayBinding as TopRightOverlayBinding).let {
it.lifecycleOwner = this
- it.presenter = this
+ it.listener = this
}
(overlayBinding as TopRightOverlayBinding).customText.text = spotlightTarget.hint
@@ -417,7 +416,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener {
overlayBinding = TopLeftOverlayBinding.inflate(this.layoutInflater)
(overlayBinding as TopLeftOverlayBinding).let {
it.lifecycleOwner = this
- it.presenter = this
+ it.listener = this
}
(overlayBinding as TopLeftOverlayBinding).customText.text = spotlightTarget.hint
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt
new file mode 100644
index 00000000000..1b7d78f68c9
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt
@@ -0,0 +1,32 @@
+package org.oppia.android.app.spotlight
+
+interface SpotlightManager {
+ /**
+ * Requests a spotlight to be shown on the [SpotlightTarget]. The spotlight is enqueued if it
+ * hasn't been shown before in a FIFO buffer. This API can ensure proper spotlighting of a [SpotlightTarget]
+ * which is laid out after an animation. For the spotlights to work correctly, we must know the
+ * [SpotlightTarget]'s anchor's size and position. For a view that is laid out after an animation, we must
+ * wait until the final size and positions of the anchor view are measured, which can be achieved by using
+ * doOnPreDraw (refer: https://betterprogramming.pub/stop-using-post-postdelayed-in-your-android-views-9d1c8eeaadf2).
+ *
+ * @param spotlightTarget The [SpotlightTarget] for which the spotlight is requested
+ */
+ fun requestSpotlightViewWithDelayedLayout(spotlightTarget: SpotlightTarget)
+
+ /**
+ * Requests a spotlight to be shown on the [SpotlightTarget]. The spotlight is enqueued if it
+ * hasn't been shown before in a FIFO buffer. This API can ensure proper spotlighting of a [SpotlightTarget]
+ * when it is laid out late due to a data provider call. It cannot ensure the same if the view has to be
+ * spotlight immediately after an animation. It also cannot spotlight targets which are a part of a
+ * recycler view which are laid out after a data provider call. If TalkBack is turned on, no spotlight shall
+ * be shown.
+ *
+ * @param spotlightTarget The [SpotlightTarget] for which the spotlight is requested
+ */
+ fun requestSpotlight(spotlightTarget: SpotlightTarget)
+
+ companion object {
+ const val SPOTLIGHT_FRAGMENT_TAG = "SpotlightFragment"
+ }
+}
+
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/SpotlightNavigationListener.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightNavigationListener.kt
similarity index 68%
rename from app/src/main/java/org/oppia/android/app/onboarding/SpotlightNavigationListener.kt
rename to app/src/main/java/org/oppia/android/app/spotlight/SpotlightNavigationListener.kt
index 814d78f0588..fa6c85153db 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/SpotlightNavigationListener.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightNavigationListener.kt
@@ -1,4 +1,4 @@
-package org.oppia.android.app.onboarding
+package org.oppia.android.app.spotlight
interface SpotlightNavigationListener {
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
index eaff01571e5..608f1c7c452 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
@@ -1,6 +1,7 @@
package org.oppia.android.app.spotlight
import android.view.View
+import org.oppia.android.app.model.Spotlight.FeatureCase
/**
* Data class to hold a [SpotlightTarget].
@@ -14,7 +15,7 @@ data class SpotlightTarget(
val anchor: View,
val hint: String = "",
val shape: SpotlightShape = SpotlightShape.RoundedRectangle,
- val feature: org.oppia.android.app.model.Spotlight.FeatureCase
+ val feature: FeatureCase
) {
val anchorLeft: Float = calculateAnchorLeft()
val anchorTop: Float = calculateAnchorTop()
diff --git a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt
index 62133a45954..17812524db2 100644
--- a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt
@@ -6,8 +6,8 @@ import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
-import org.oppia.android.app.topic.SPOTLIGHT_FRAGMENT_TAG
import org.oppia.android.databinding.SpotlightFragmentTestActivityBinding
@ActivityScope
@@ -28,14 +28,14 @@ class SpotlightFragmentTestActivityPresenter @Inject constructor(
spotlightFragment.arguments = args
activity.supportFragmentManager.beginTransaction().add(
R.id.test_spotlight_overlay_placeholder,
- spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
+ spotlightFragment, SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
).commitNow()
}
}
fun getSpotlightFragment(): SpotlightFragment? {
return activity.supportFragmentManager.findFragmentByTag(
- SPOTLIGHT_FRAGMENT_TAG
+ SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
) as SpotlightFragment?
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
index 45cbfae3d22..da216ea176f 100755
--- a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
@@ -7,9 +7,9 @@ import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.spotlight.SpotlightFragment
import javax.inject.Inject
+import org.oppia.android.app.spotlight.SpotlightManager
const val TOPIC_FRAGMENT_TAG = "TopicFragment"
-const val SPOTLIGHT_FRAGMENT_TAG = "SpotlightFragment"
const val PROFILE_ID_ARGUMENT_KEY = "profile_id"
const val TOPIC_ID_ARGUMENT_KEY = "topic_id"
const val STORY_ID_ARGUMENT_KEY = "story_id"
@@ -47,7 +47,7 @@ class TopicActivityPresenter @Inject constructor(private val activity: AppCompat
spotlightFragment.arguments = args
activity.supportFragmentManager.beginTransaction().add(
R.id.topic_spotlight_fragment_placeholder,
- spotlightFragment, SPOTLIGHT_FRAGMENT_TAG
+ spotlightFragment, SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
).commitNow()
}
}
@@ -62,7 +62,7 @@ class TopicActivityPresenter @Inject constructor(private val activity: AppCompat
private fun getSpotlightFragment(): SpotlightFragment? {
return activity.supportFragmentManager.findFragmentByTag(
- SPOTLIGHT_FRAGMENT_TAG
+ SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
) as SpotlightFragment?
}
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 6f4454feeb5..a8f4c67b059 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -21,6 +21,7 @@ import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.util.platformparameter.EnableExtraTopicTabsUi
import org.oppia.android.util.platformparameter.PlatformParameterValue
import javax.inject.Inject
+import org.oppia.android.app.spotlight.SpotlightManager
/** The presenter for [TopicFragment]. */
@FragmentScope
@@ -104,7 +105,7 @@ class TopicFragmentPresenter @Inject constructor(
private fun getSpotlightFragment(): SpotlightFragment? {
return activity.supportFragmentManager.findFragmentByTag(
- SPOTLIGHT_FRAGMENT_TAG
+ SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
) as SpotlightFragment?
}
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index cde8bba118d..7c5ecdaf2c8 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -7,8 +7,8 @@
+ name="listener"
+ type="org.oppia.android.app.spotlight.SpotlightNavigationListener" />
+ name="listener"
+ type="org.oppia.android.app.spotlight.SpotlightNavigationListener" />
+ name="listener"
+ type="org.oppia.android.app.spotlight.SpotlightNavigationListener" />
+ name="listener"
+ type="org.oppia.android.app.spotlight.SpotlightNavigationListener" />
Date: Fri, 18 Nov 2022 18:22:31 +0530
Subject: [PATCH 088/138] adjust affected tests
---
.../app/onboarding/OnboardingFragmentTest.kt | 20 ++++++++++++-------
.../app/spotlight/SpotlightFragmentTest.kt | 3 +--
.../android/app/topic/TopicActivityTest.kt | 6 ++----
.../android/app/topic/TopicFragmentTest.kt | 2 --
.../topic/lessons/TopicLessonsFragmentTest.kt | 13 +++++++++---
.../revision/TopicRevisionFragmentTest.kt | 17 ++++++++++++++++
6 files changed, 43 insertions(+), 18 deletions(-)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
index c8c45d49f70..40fb854276c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
@@ -174,13 +174,6 @@ class OnboardingFragmentTest {
}
}
- @Test
- fun testNextButtonSpotlight_setToShowOnStartup_neverSeenBefore_checkSpotlightIsShown() {
- launch(OnboardingActivity::class.java).use {
- onView(withText(R.string.onboarding_next_button_spotlight_hint)).check(matches(isDisplayed()))
- }
- }
-
@Test
fun testOnboardingFragment_checkDefaultSlideDescription_isCorrect() {
launch(OnboardingActivity::class.java).use {
@@ -233,6 +226,7 @@ class OnboardingFragmentTest {
@Test
fun testNextButtonSpotlight_setToShowOnStartup_checkSpotlightIsShown() {
launch(OnboardingActivity::class.java).use {
+ testCoroutineDispatchers.runCurrent()
onView(withText(R.string.onboarding_next_button_spotlight_hint)).check(matches(isDisplayed()))
}
}
@@ -240,6 +234,8 @@ class OnboardingFragmentTest {
@Test
fun testOnboardingFragment_checkDefaultSlide_clickSkipButton_shiftsToLastSlide() {
launch(OnboardingActivity::class.java).use {
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.close_target)).perform(click())
onView(withId(R.id.skip_text_view)).perform(click())
testCoroutineDispatchers.runCurrent()
onView(
@@ -342,6 +338,8 @@ class OnboardingFragmentTest {
@Test
fun testOnboardingFragment_checkSlide1_clickSkipButton_shiftsToLastSlide() {
launch(OnboardingActivity::class.java).use {
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.close_target)).perform(click())
onView(withId(R.id.onboarding_slide_view_pager)).perform(scrollToPosition(position = 1))
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.skip_text_view)).perform(click())
@@ -449,6 +447,8 @@ class OnboardingFragmentTest {
@Test
fun testOnboardingFragment_checkSlide2_clickSkipButton_shiftsToLastSlide() {
launch(OnboardingActivity::class.java).use {
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.close_target)).perform(click())
onView(withId(R.id.onboarding_slide_view_pager)).perform(scrollToPosition(position = 2))
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.skip_text_view)).perform(click())
@@ -519,6 +519,8 @@ class OnboardingFragmentTest {
@Test
fun testOnboardingFragment_checkSlide3_clickGetStartedButton_opensProfileActivity() {
launch(OnboardingActivity::class.java).use {
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.close_target)).perform(click())
onView(withId(R.id.onboarding_slide_view_pager)).perform(scrollToPosition(position = 3))
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.get_started_button)).perform(scrollTo(), click())
@@ -573,6 +575,8 @@ class OnboardingFragmentTest {
@Test
fun testOnboardingFragment_clickOnSkip_changeOrientation_titleIsCorrect() {
launch(OnboardingActivity::class.java).use {
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.close_target)).perform(click())
onView(withId(R.id.skip_text_view)).perform(click())
testCoroutineDispatchers.runCurrent()
onView(isRoot()).perform(orientationLandscape())
@@ -677,6 +681,8 @@ class OnboardingFragmentTest {
@Test
fun testOnboardingFragment_checkSlide3_policiesLinkIsVisible() {
launch(OnboardingActivity::class.java).use {
+ testCoroutineDispatchers.runCurrent()
+ onView(withId(R.id.close_target)).perform(click())
onView(withId(R.id.skip_text_view)).perform(click())
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.slide_terms_of_service_and_privacy_policy_links_text_view)).perform(
diff --git a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
index 069f9297227..cc09ae9a4c0 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
@@ -194,8 +194,7 @@ class SpotlightFragmentTest {
activity.getSpotlightFragment()
).requestSpotlightViewWithDelayedLayout(spotlightTarget)
}
- testCoroutineDispatchers.advanceUntilIdle()
- onView(withText(sampleSpotlightText)).check(matches(isDisplayed()))
+ onView(withText(sampleSpotlightText)).check(matches(isDisplayed()))
}
}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
index 1d5fd7cacea..265bbf343c5 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
@@ -8,7 +8,6 @@ import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
-import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions.scrollToPosition
import androidx.test.espresso.intent.Intents
@@ -21,8 +20,6 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import dagger.Component
-import javax.inject.Inject
-import javax.inject.Singleton
import org.junit.After
import org.junit.Before
import org.junit.Rule
@@ -105,6 +102,8 @@ import org.oppia.android.util.parser.image.GlideImageLoaderModule
import org.oppia.android.util.parser.image.ImageParsingModule
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
/** Tests for [TopicActivity]. */
@RunWith(AndroidJUnit4::class)
@@ -204,7 +203,6 @@ class TopicActivityTest {
)
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.topic_name_text_view)).check(matches(isDisplayed()))
- testCoroutineDispatchers.runCurrent()
return scenario
}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
index c610c2062c6..5556ac2b27e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
@@ -270,8 +270,6 @@ class TopicFragmentTest {
storyProgressTestHelper.markCompletedRatiosStory1Exp0(profileId, false)
testCoroutineDispatchers.runCurrent()
launch(createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)).use {
- // mark lessons spotlight seen
- onView(withId(R.id.close_target)).perform(click())
testCoroutineDispatchers.runCurrent()
onView(withText(R.string.topic_revision_tab_spotlight_hint)).check(matches(isDisplayed()))
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
index e49b3fccf95..ed0ee7fbed1 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
@@ -105,11 +105,8 @@ import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
import org.oppia.android.domain.topic.RATIOS_STORY_ID_0
import org.oppia.android.domain.topic.RATIOS_TOPIC_ID
import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule
-import org.oppia.android.testing.DisableAccessibilityChecks
import org.oppia.android.testing.OppiaTestRule
-import org.oppia.android.testing.RunOn
import org.oppia.android.testing.TestLogReportingModule
-import org.oppia.android.testing.TestPlatform
import org.oppia.android.testing.junit.InitializeDefaultLocaleRule
import org.oppia.android.testing.lightweightcheckpointing.ExplorationCheckpointTestHelper
import org.oppia.android.testing.lightweightcheckpointing.FRACTIONS_STORY_0_EXPLORATION_0_CURRENT_VERSION
@@ -179,6 +176,7 @@ class TopicLessonsFragmentTest {
testCoroutineDispatchers.registerIdlingResource()
profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
fakeOppiaClock.setFakeTimeMode(FakeOppiaClock.FakeTimeMode.MODE_UPTIME_MILLIS)
+ markAllSpotlightsSeen()
}
@After
@@ -941,6 +939,15 @@ class TopicLessonsFragmentTest {
}
}
+ private fun markAllSpotlightsSeen() {
+ spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_LESSON_TAB)
+ testCoroutineDispatchers.runCurrent()
+ spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_REVISION_TAB)
+ testCoroutineDispatchers.runCurrent()
+ spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.FIRST_CHAPTER)
+ testCoroutineDispatchers.runCurrent()
+ }
+
private fun createTopicActivityIntent(internalProfileId: Int, topicId: String): Intent {
return TopicActivity.createTopicActivityIntent(
ApplicationProvider.getApplicationContext(),
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt
index ee20abaf075..4bf289ed0c9 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt
@@ -111,6 +111,9 @@ import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
import javax.inject.Inject
import javax.inject.Singleton
+import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.model.Spotlight
+import org.oppia.android.domain.spotlight.SpotlightStateController
/** Tests for [TopicRevisionFragment]. */
@RunWith(AndroidJUnit4::class)
@@ -132,6 +135,9 @@ class TopicRevisionFragmentTest {
@Inject
lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
+ @Inject
+ lateinit var spotlightStateController: SpotlightStateController
+
@field:[Inject EnableExtraTopicTabsUi]
lateinit var enableExtraTopicTabsUi: PlatformParameterValue
@@ -144,6 +150,7 @@ class TopicRevisionFragmentTest {
TestPlatformParameterModule.forceEnableExtraTopicTabsUi(true)
setUpTestApplicationComponent()
testCoroutineDispatchers.registerIdlingResource()
+ markAllSpotlightsSeen()
}
@After
@@ -269,6 +276,16 @@ class TopicRevisionFragmentTest {
}
}
+ private fun markAllSpotlightsSeen() {
+ val profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
+ spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_LESSON_TAB)
+ testCoroutineDispatchers.runCurrent()
+ spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_REVISION_TAB)
+ testCoroutineDispatchers.runCurrent()
+ spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.FIRST_CHAPTER)
+ testCoroutineDispatchers.runCurrent()
+ }
+
private fun createTopicActivityIntent(internalProfileId: Int, topicId: String): Intent {
return TopicActivity.createTopicActivityIntent(
context = ApplicationProvider.getApplicationContext(),
From 080080b33b52051b80f3a37be04bddc027223779 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 18 Nov 2022 20:02:03 +0530
Subject: [PATCH 089/138] adjust tests
---
.../topic/practice/TopicPracticeFragmentTest.kt | 17 +++++++++++++++++
scripts/assets/test_file_exemptions.textproto | 2 ++
2 files changed, 19 insertions(+)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
index 9ce30a3d64b..7c2095ae016 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
@@ -109,6 +109,9 @@ import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
import javax.inject.Inject
import javax.inject.Singleton
+import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.model.Spotlight
+import org.oppia.android.domain.spotlight.SpotlightStateController
/** Tests for [TopicPracticeFragment]. */
@RunWith(AndroidJUnit4::class)
@@ -130,6 +133,9 @@ class TopicPracticeFragmentTest {
@Inject
lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
+ @Inject
+ lateinit var spotlightStateController: SpotlightStateController
+
@field:[Inject EnableExtraTopicTabsUi]
lateinit var enableExtraTopicTabsUiValue: PlatformParameterValue
@@ -141,6 +147,7 @@ class TopicPracticeFragmentTest {
testCoroutineDispatchers.registerIdlingResource()
skillIdList.add("5RM9KPfQxobH")
skillIdList.add("B39yK4cbHZYI")
+ markAllSpotlightsSeen()
}
@After
@@ -414,6 +421,16 @@ class TopicPracticeFragmentTest {
testCoroutineDispatchers.runCurrent()
}
+ private fun markAllSpotlightsSeen() {
+ val profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
+ spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_LESSON_TAB)
+ testCoroutineDispatchers.runCurrent()
+ spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_REVISION_TAB)
+ testCoroutineDispatchers.runCurrent()
+ spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.FIRST_CHAPTER)
+ testCoroutineDispatchers.runCurrent()
+ }
+
// TODO(#59): Figure out a way to reuse modules instead of needing to re-declare them.
@Singleton
@Component(
diff --git a/scripts/assets/test_file_exemptions.textproto b/scripts/assets/test_file_exemptions.textproto
index 8d05890315e..f4272b50d43 100644
--- a/scripts/assets/test_file_exemptions.textproto
+++ b/scripts/assets/test_file_exemptions.textproto
@@ -64,6 +64,8 @@ exempted_file_path: "app/src/main/java/org/oppia/android/app/completedstorylist/
exempted_file_path: "app/src/main/java/org/oppia/android/app/completedstorylist/CompletedStoryListFragment.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/completedstorylist/CompletedStoryListFragmentPresenter.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/completedstorylist/CompletedStoryListViewModel.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/customview/SegmentedCircularProgressView.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/customview/VerticalDashedLineView.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/customview/interaction/FractionInputInteractionView.kt"
From b950bf7c767ddcb9b86f6ab71867a87a811b5637 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 18 Nov 2022 20:17:00 +0530
Subject: [PATCH 090/138] kdocs
---
.../java/org/oppia/android/app/spotlight/SpotlightShape.kt | 5 ++++-
.../android/app/testing/SpotlightFragmentTestActivity.kt | 5 ++++-
.../app/testing/SpotlightFragmentTestActivityPresenter.kt | 4 ++++
scripts/assets/test_file_exemptions.textproto | 6 ++++++
4 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt
index 37cf4c3d38c..0193e0684eb 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt
@@ -2,6 +2,9 @@ package org.oppia.android.app.spotlight
/** The shape of the overlay screen cutout surrounding the spotlit view. */
sealed class SpotlightShape {
- object RoundedRectangle : SpotlightShape()
+ /** Circle shape for the spotlight highlight. */
object Circle : SpotlightShape()
+
+ /** Rounded rectangle shape for the spotlight highlight. */
+ object RoundedRectangle : SpotlightShape()
}
diff --git a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
index ccacd8e927f..faa93618ef8 100644
--- a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
+++ b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
@@ -8,10 +8,11 @@ import org.oppia.android.app.activity.ActivityComponentImpl
import org.oppia.android.app.testing.activity.TestActivity
import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
+/** Test Activity used for testing [SpotlightFragment]. */
class SpotlightFragmentTestActivity : TestActivity() {
@Inject
- lateinit var spotlightFragmentTestActivityPresenter: SpotlightFragmentTestActivityPresenter
+ private lateinit var spotlightFragmentTestActivityPresenter: SpotlightFragmentTestActivityPresenter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -24,8 +25,10 @@ class SpotlightFragmentTestActivity : TestActivity() {
)
}
+ /** Returns the spotlight fragment. */
fun getSpotlightFragment() = spotlightFragmentTestActivityPresenter.getSpotlightFragment()
+ /** Returns a view to be used as a spotlight anchor. */
fun getSampleSpotlightTarget() = spotlightFragmentTestActivityPresenter.getSampleSpotlightTarget()
companion object {
diff --git a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt
index 17812524db2..611eccbf723 100644
--- a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt
@@ -10,6 +10,7 @@ import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
import org.oppia.android.databinding.SpotlightFragmentTestActivityBinding
+/** The presenter for [SpotlightFragmentTestActivity] */
@ActivityScope
class SpotlightFragmentTestActivityPresenter @Inject constructor(
private val activity: AppCompatActivity
@@ -17,6 +18,7 @@ class SpotlightFragmentTestActivityPresenter @Inject constructor(
private lateinit var binding: SpotlightFragmentTestActivityBinding
+ /** Handles onCreate() method of the [SpotlightFragmentTestActivity]. */
fun handleOnCreate(internalProfileId: Int) {
binding = SpotlightFragmentTestActivityBinding.inflate(activity.layoutInflater)
activity.setContentView(binding.root)
@@ -33,11 +35,13 @@ class SpotlightFragmentTestActivityPresenter @Inject constructor(
}
}
+ /** Returns the spotlight fragment. */
fun getSpotlightFragment(): SpotlightFragment? {
return activity.supportFragmentManager.findFragmentByTag(
SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
) as SpotlightFragment?
}
+ /** Returns a view to be used as a spotlight anchor. */
fun getSampleSpotlightTarget() = binding.sampleSpotlightTarget
}
\ No newline at end of file
diff --git a/scripts/assets/test_file_exemptions.textproto b/scripts/assets/test_file_exemptions.textproto
index f4272b50d43..d28bb6bd5b0 100644
--- a/scripts/assets/test_file_exemptions.textproto
+++ b/scripts/assets/test_file_exemptions.textproto
@@ -417,6 +417,10 @@ exempted_file_path: "app/src/main/java/org/oppia/android/app/shim/ViewBindingShi
exempted_file_path: "app/src/main/java/org/oppia/android/app/shim/ViewComponentFactory.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/splash/SplashActivityPresenter.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/story/ExplorationSelectionListener.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/spotlight/SpotlightNavigationListener.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/spotlight/SpotlightShape.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/story/StoryActivityPresenter.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/story/StoryFragmentScroller.kt"
@@ -461,6 +465,8 @@ exempted_file_path: "app/src/main/java/org/oppia/android/app/testing/ProfileEdit
exempted_file_path: "app/src/main/java/org/oppia/android/app/testing/ProfileChooserFragmentTestActivityPresenter.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/testing/SplashTestActivity.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/testing/SplashTestActivityPresenter.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/testing/StateAssemblerMarginBindingAdaptersTestActivity.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/testing/StateAssemblerPaddingBindingAdaptersTestActivity.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/testing/TestFontScaleConfigurationUtilActivityPresenter.kt"
From ab463bf5194ea04509e9a75567d74d11acbd7dc7 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 18 Nov 2022 20:31:32 +0530
Subject: [PATCH 091/138] fix bug
---
.../oppia/android/app/testing/SpotlightFragmentTestActivity.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
index faa93618ef8..cfd2da6c9cc 100644
--- a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
+++ b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
@@ -12,7 +12,7 @@ import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
class SpotlightFragmentTestActivity : TestActivity() {
@Inject
- private lateinit var spotlightFragmentTestActivityPresenter: SpotlightFragmentTestActivityPresenter
+ lateinit var spotlightFragmentTestActivityPresenter: SpotlightFragmentTestActivityPresenter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
From d8b20c56ea3809dbe317312d944c5b51752ca75a Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 18 Nov 2022 22:43:22 +0530
Subject: [PATCH 092/138] small corrections
---
.../java/org/oppia/android/app/spotlight/SpotlightFragment.kt | 2 +-
.../java/org/oppia/android/app/spotlight/SpotlightManager.kt | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index fc3dffbe3bd..0185aa7a1f4 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -223,7 +223,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
val locale = Locale.getDefault()
val directionality: Byte = Character.getDirectionality(locale.displayName[0].toInt())
isRTL = directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT ||
- directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
+ directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT
}
private fun getArrowWidth(): Float {
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt
index 1b7d78f68c9..9812e497881 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt
@@ -1,5 +1,6 @@
package org.oppia.android.app.spotlight
+/** Manager for the [SpotlightFragment]. */
interface SpotlightManager {
/**
* Requests a spotlight to be shown on the [SpotlightTarget]. The spotlight is enqueued if it
From dd3222192b0bdf9b7a6b51038d15ead6536c75dc Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 18 Nov 2022 23:34:11 +0530
Subject: [PATCH 093/138] adjust test
---
.../oppia/android/app/topic/TopicActivityTest.kt | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
index 265bbf343c5..279c42540dd 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
@@ -104,6 +104,8 @@ import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
import javax.inject.Inject
import javax.inject.Singleton
+import org.oppia.android.app.model.Spotlight
+import org.oppia.android.domain.spotlight.SpotlightStateController
/** Tests for [TopicActivity]. */
@RunWith(AndroidJUnit4::class)
@@ -125,12 +127,16 @@ class TopicActivityTest {
@Inject
lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
+ @Inject
+ lateinit var spotlightStateController: SpotlightStateController
+
private val internalProfileId = 1
@Before
fun setUp() {
Intents.init()
setUpTestApplicationComponent()
+ markAllSpotlightsSeen()
}
@After
@@ -206,6 +212,16 @@ class TopicActivityTest {
return scenario
}
+ private fun markAllSpotlightsSeen() {
+ val profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
+ spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_LESSON_TAB)
+ testCoroutineDispatchers.runCurrent()
+ spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_REVISION_TAB)
+ testCoroutineDispatchers.runCurrent()
+ spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.FIRST_CHAPTER)
+ testCoroutineDispatchers.runCurrent()
+ }
+
// TODO(#59): Figure out a way to reuse modules instead of needing to re-declare them.
@Singleton
@Component(
From ac3621c1fb11bcb285f5600faed5bcdee8a5ba0b Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sat, 19 Nov 2022 00:53:19 +0530
Subject: [PATCH 094/138] use resource handler instead
---
.../ChapterNotStartedContainerConstraintLayout.kt | 6 +++++-
.../android/app/customview/PromotedStoryCardView.kt | 9 ++++-----
.../app/onboarding/OnboardingFragmentPresenter.kt | 2 +-
.../app/player/audio/AudioFragmentPresenter.kt | 2 +-
.../exploration/ExplorationActivityPresenter.kt | 6 ++++--
.../app/player/exploration/ExplorationFragment.kt | 1 +
.../exploration/ExplorationFragmentPresenter.kt | 4 +++-
.../app/player/state/StateFragmentPresenter.kt | 13 +++++++++++--
.../android/app/spotlight/SpotlightFragment.kt | 13 +++++--------
app/src/main/res/layout/bottom_left_overlay.xml | 2 +-
app/src/main/res/layout/bottom_right_overlay.xml | 2 +-
app/src/main/res/layout/top_left_overlay.xml | 4 ++--
app/src/main/res/layout/top_right_overlay.xml | 2 +-
app/src/main/res/values/strings.xml | 3 ++-
scripts/assets/test_file_exemptions.textproto | 1 +
15 files changed, 43 insertions(+), 27 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index 6caa76b98d2..e5f7f6e6586 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -10,6 +10,7 @@ import org.oppia.android.R
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.spotlight.SpotlightTarget
+import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
@@ -25,6 +26,9 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
@Inject
lateinit var fragment: Fragment
+ @Inject
+ lateinit var resourceHandler: AppLanguageResourceHandler
+
fun setStoryIndex(index: Int) {
// Only spotlight the first chapter of the "first" story. We know for sure that for a new user,
// the first chapter shall be a type of not started chapter view. The index tells which story
@@ -50,7 +54,7 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
isSpotlit = true
val spotlightTarget = SpotlightTarget(
this,
- context.getString(R.string.first_chapter_spotlight_hint),
+ resourceHandler.getStringInLocale(R.string.first_chapter_spotlight_hint),
feature = Spotlight.FeatureCase.FIRST_CHAPTER
)
if (index == 0) {
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
index edd21a2c048..23455bfb03f 100644
--- a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -12,6 +12,7 @@ import org.oppia.android.R
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.spotlight.SpotlightTarget
+import org.oppia.android.app.translation.AppLanguageResourceHandler
class PromotedStoryCardView @JvmOverloads constructor(
context: Context,
@@ -22,8 +23,9 @@ class PromotedStoryCardView @JvmOverloads constructor(
@Inject
lateinit var fragment: Fragment
+ @Inject
+ lateinit var resourceHandler: AppLanguageResourceHandler
- private var index: Int = -1
private var isSpotlit = false
fun setIndex(index: Int) {
@@ -31,14 +33,13 @@ class PromotedStoryCardView @JvmOverloads constructor(
isSpotlit = true
val spotlightTarget = SpotlightTarget(
this,
- context.getString(R.string.promoted_story_spotlight_hint),
+ resourceHandler.getStringInLocale(R.string.promoted_story_spotlight_hint),
feature = Spotlight.FeatureCase.PROMOTED_STORIES
)
if (index == 0) {
checkNotNull(getSpotlightFragment()).requestSpotlightViewWithDelayedLayout(spotlightTarget)
}
}
-
}
private fun getSpotlightFragment(): SpotlightManager? {
@@ -49,11 +50,9 @@ class PromotedStoryCardView @JvmOverloads constructor(
override fun onAttachedToWindow() {
super.onAttachedToWindow()
-
val viewComponentFactory =
FragmentManager.findFragment(this) as ViewComponentFactory
val viewComponent = viewComponentFactory.createViewComponent(this) as ViewComponentImpl
viewComponent.inject(this)
-
}
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index e0a255124f2..ca19250a3e3 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -70,7 +70,7 @@ class OnboardingFragmentPresenter @Inject constructor(
fun startSpotlight() {
val nextSpotlightTarget = SpotlightTarget(
binding.onboardingFragmentNextImageView,
- fragment.requireContext().getString(R.string.onboarding_next_button_spotlight_hint),
+ resourceHandler.getStringInLocale(R.string.onboarding_next_button_spotlight_hint),
SpotlightShape.Circle,
Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON
)
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index d26189c60f1..838d5fc66ce 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -132,7 +132,7 @@ class AudioFragmentPresenter @Inject constructor(
private fun startSpotlights() {
val audioLanguageIconSpotlightTarget = SpotlightTarget(
binding.audioLanguageIcon,
- context.getString(R.string.voiceover_language_icon_spotlight_hint),
+ resourceHandler.getStringInLocale(R.string.voiceover_language_icon_spotlight_hint),
SpotlightShape.Circle,
Spotlight.FeatureCase.VOICEOVER_LANGUAGE_ICON
)
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
index a0dba2fa43e..a79d6a8f205 100644
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
@@ -37,6 +37,7 @@ import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
+import org.oppia.android.app.translation.AppLanguageResourceHandler
private const val TAG_UNSAVED_EXPLORATION_DIALOG = "UNSAVED_EXPLORATION_DIALOG"
private const val TAG_STOP_EXPLORATION_DIALOG = "STOP_EXPLORATION_DIALOG"
@@ -53,7 +54,8 @@ class ExplorationActivityPresenter @Inject constructor(
private val viewModelProvider: ViewModelProvider,
private val fontScaleConfigurationUtil: FontScaleConfigurationUtil,
private val translationController: TranslationController,
- private val oppiaLogger: OppiaLogger
+ private val oppiaLogger: OppiaLogger,
+ private val resouceHandler: AppLanguageResourceHandler
) {
private lateinit var explorationToolbar: Toolbar
private lateinit var explorationToolbarTitle: TextView
@@ -150,7 +152,7 @@ class ExplorationActivityPresenter @Inject constructor(
// spotlight voice-over icon after 3 logins
val audioPlayerSpotlightTarget = SpotlightTarget(
binding.actionAudioPlayer,
- activity.getString(R.string.voiceover_icon_spotlight_hint),
+ resouceHandler.getStringInLocale(R.string.voiceover_icon_spotlight_hint),
SpotlightShape.Circle,
Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
)
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragment.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragment.kt
index b72f2f0da61..a662d79dbb0 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragment.kt
@@ -12,6 +12,7 @@ import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.ReadingTextSize
import org.oppia.android.util.extensions.putProto
import javax.inject.Inject
+import org.oppia.android.app.translation.AppLanguageResourceHandler
/** Fragment that contains displays single exploration. */
class ExplorationFragment : InjectableFragment() {
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index f668bec91dd..688f580b6dc 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -19,6 +19,7 @@ import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
+import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.utility.FontScaleConfigurationUtil
import org.oppia.android.databinding.ExplorationFragmentBinding
import org.oppia.android.domain.oppialogger.OppiaLogger
@@ -35,6 +36,7 @@ class ExplorationFragmentPresenter @Inject constructor(
private val oppiaLogger: OppiaLogger,
private val fontScaleConfigurationUtil: FontScaleConfigurationUtil,
private val profileManagementController: ProfileManagementController,
+ private val resourceHandler: AppLanguageResourceHandler
) {
private var internalProfileId: Int = -1
@@ -93,7 +95,7 @@ class ExplorationFragmentPresenter @Inject constructor(
// this toolbar contains only one image button, which is the back navigation icon
val backButtonSpotlightTarget = SpotlightTarget(
it,
- fragment.requireContext().getString(R.string.exploration_exit_button_spotlight_hint),
+ resourceHandler.getStringInLocale(R.string.exploration_exit_button_spotlight_hint),
SpotlightShape.Circle,
Spotlight.FeatureCase.LESSONS_BACK_BUTTON
)
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 b831399a935..d36af53c1ec 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
@@ -1,5 +1,6 @@
package org.oppia.android.app.player.state
+import org.oppia.android.util.accessibility.AccessibilityService
import android.content.Context
import android.view.LayoutInflater
import android.view.View
@@ -49,6 +50,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.translation.AppLanguageResourceHandler
const val STATE_FRAGMENT_PROFILE_ID_ARGUMENT_KEY =
"StateFragmentPresenter.state_fragment_profile_id"
@@ -73,7 +75,9 @@ class StateFragmentPresenter @Inject constructor(
@DefaultResourceBucketName private val resourceBucketName: String,
private val assemblerBuilderFactory: StatePlayerRecyclerViewAssembler.Builder.Factory,
private val splitScreenManager: SplitScreenManager,
- private val oppiaClock: OppiaClock
+ private val oppiaClock: OppiaClock,
+ private val accessibilityService: AccessibilityService,
+ private val resourceHandler: AppLanguageResourceHandler
) {
private val routeToHintsAndSolutionListener = activity as RouteToHintsAndSolutionListener
@@ -509,7 +513,12 @@ class StateFragmentPresenter @Inject constructor(
activity.runPeriodically(delayMillis = 5_000, periodMillis = 30_000) {
return@runPeriodically viewModel.isHintOpenedAndUnRevealed.get()!!.also { playAnim ->
if (playAnim) binding.hintBulb.startAnimation(hintBulbAnimation)
- binding.hintsAndSolutionFragmentContainer.announceForAccessibility("Go to the bottom of the screen for hint")
+ accessibilityService.announceForAccessibilityForView(
+ binding.hintsAndSolutionFragmentContainer,
+ resourceHandler.getStringInLocale(
+ R.string.state_fragment_hint_bar_forced_announcement_text
+ )
+ )
}
}
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 0185aa7a1f4..f76b324d551 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -327,14 +327,14 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
if (isRTL) {
arrowParams.setMargins(
screenWidth - spotlightTarget.anchorLeft.toInt(),
- (spotlightTarget.anchorTop.toInt() - getArrowHeight() - 5.dp).toInt(),
+ (spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
} else {
arrowParams.setMargins(
spotlightTarget.anchorLeft.toInt(),
- (spotlightTarget.anchorTop.toInt() - getArrowHeight() - 5.dp).toInt(),
+ (spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
@@ -393,7 +393,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
if (isRTL) {
arrowParams.setMargins(
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
- (spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
+ (spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
screenWidth - (spotlightTarget.anchorLeft + getArrowWidth()).toInt(),
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
@@ -426,14 +426,14 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
if (isRTL) {
arrowParams.setMargins(
screenWidth - spotlightTarget.anchorLeft.toInt(),
- (spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
+ (spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
} else {
arrowParams.setMargins(
spotlightTarget.anchorLeft.toInt(),
- (spotlightTarget.anchorTop + spotlightTarget.anchorHeight + 5.dp).toInt(),
+ (spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
@@ -442,7 +442,4 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
return (overlayBinding as TopLeftOverlayBinding).root
}
-
- private val Int.dp: Int
- get() = (this * Resources.getSystem().displayMetrics.density + 0.5f).toInt()
}
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 7c5ecdaf2c8..33924f3cd3e 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -24,7 +24,7 @@
android:layout_width="@dimen/arrow_width"
android:layout_height="@dimen/arrow_height"
android:rotationX="180"
- android:src="@drawable/ic_rounded_arrow_up_right"
+ app:srcCompat="@drawable/ic_rounded_arrow_up_right"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index e0c68664fda..0b39c5d055c 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -25,7 +25,7 @@
android:layout_height="@dimen/arrow_height"
android:rotationX="180"
android:rotationY="180"
- android:src="@drawable/ic_rounded_arrow_up_right"
+ app:srcCompat="@drawable/ic_rounded_arrow_up_right"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index 8ab7171f342..96aef3e9f12 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -23,8 +23,8 @@
android:id="@+id/arrow"
android:layout_width="@dimen/arrow_width"
android:layout_height="@dimen/arrow_height"
- android:src="@drawable/ic_rounded_arrow_up_right"
- app:layout_constraintStart_toStartOf="parent"
+ app:srcCompat="@drawable/ic_rounded_arrow_up_right"
+ app:layout_constraintStart_toStartOfC="parent"
app:layout_constraintTop_toTopOf="parent" />
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 506133563e6..9e008213275 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -580,8 +580,9 @@
Revise your lessons here
Tap to start a chapter
Exit anytime using this button. We will save your progress.
- Would you like Oppia to read for you? Tap on this button to try!
+ Would you like %s to read for you? Tap on this button to try!
Tap to change voiceover language
Next
From now, you can see stories recommended for you here
+ Go to the bottom of the screen for hint
diff --git a/scripts/assets/test_file_exemptions.textproto b/scripts/assets/test_file_exemptions.textproto
index d28bb6bd5b0..e8294c5eb11 100644
--- a/scripts/assets/test_file_exemptions.textproto
+++ b/scripts/assets/test_file_exemptions.textproto
@@ -292,6 +292,7 @@ exempted_file_path: "app/src/main/java/org/oppia/android/app/player/exploration/
exempted_file_path: "app/src/main/java/org/oppia/android/app/player/exploration/HintsAndSolutionExplorationManagerFragment.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/player/exploration/HintsAndSolutionExplorationManagerFragmentPresenter.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/player/exploration/HintsAndSolutionExplorationManagerListener.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/player/exploration/RequestVoiceOverIconSpotlightListener.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/player/exploration/testing/BottomSheetOptionsMenuTestActivity.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/player/state/ConfettiConfig.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/player/state/DragDropSortInteractionView.kt"
From e3450ce4b443bc8b2d6cba6b8fa99617f2cc6227 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sat, 19 Nov 2022 01:11:06 +0530
Subject: [PATCH 095/138] lint
---
...pterNotStartedContainerConstraintLayout.kt | 2 +-
.../app/customview/PromotedStoryCardView.kt | 6 ++--
.../android/app/home/HomeActivityPresenter.kt | 2 +-
.../onboarding/OnboardingActivityPresenter.kt | 2 +-
.../onboarding/OnboardingFragmentPresenter.kt | 11 +++---
.../player/audio/AudioFragmentPresenter.kt | 2 +-
.../ExplorationActivityPresenter.kt | 10 +++---
.../player/exploration/ExplorationFragment.kt | 1 -
.../ExplorationFragmentPresenter.kt | 5 +--
.../RequestVoiceOverIconSpotlightListener.kt | 2 +-
.../player/state/StateFragmentPresenter.kt | 5 ++-
.../app/spotlight/SpotlightFragment.kt | 35 +++++++++----------
.../android/app/spotlight/SpotlightManager.kt | 1 -
.../testing/SpotlightFragmentTestActivity.kt | 4 +--
.../SpotlightFragmentTestActivityPresenter.kt | 6 ++--
.../app/topic/TopicActivityPresenter.kt | 2 +-
.../app/topic/TopicFragmentPresenter.kt | 2 +-
.../android/app/home/HomeActivityTest.kt | 14 ++++----
.../exploration/ExplorationActivityTest.kt | 31 ++++++++--------
.../app/spotlight/SpotlightFragmentTest.kt | 16 +++------
.../android/app/topic/TopicActivityTest.kt | 12 ++++---
.../android/app/topic/TopicFragmentTest.kt | 30 ++++++++++------
.../topic/lessons/TopicLessonsFragmentTest.kt | 10 +++---
.../practice/TopicPracticeFragmentTest.kt | 11 +++---
.../revision/TopicRevisionFragmentTest.kt | 14 ++++----
.../player/state/StateFragmentLocalTest.kt | 2 +-
26 files changed, 121 insertions(+), 117 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index e5f7f6e6586..ad8cc1a4f53 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -5,7 +5,6 @@ import android.util.AttributeSet
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
-import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightManager
@@ -13,6 +12,7 @@ import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
+import javax.inject.Inject
class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
context: Context,
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
index 23455bfb03f..1dbd47e7407 100644
--- a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -5,14 +5,14 @@ import android.util.AttributeSet
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import com.google.android.material.card.MaterialCardView
-import org.oppia.android.app.view.ViewComponentFactory
-import org.oppia.android.app.view.ViewComponentImpl
-import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.translation.AppLanguageResourceHandler
+import org.oppia.android.app.view.ViewComponentFactory
+import org.oppia.android.app.view.ViewComponentImpl
+import javax.inject.Inject
class PromotedStoryCardView @JvmOverloads constructor(
context: Context,
diff --git a/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
index 9135b8f8d49..da1bc61cf51 100644
--- a/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
@@ -9,9 +9,9 @@ import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.drawer.NavigationDrawerFragment
import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
import javax.inject.Inject
-import org.oppia.android.app.spotlight.SpotlightManager
const val TAG_HOME_FRAGMENT = "HOME_FRAGMENT"
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
index db15ccf7675..1aed8f979e0 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
@@ -4,10 +4,10 @@ import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
-import javax.inject.Inject
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
+import javax.inject.Inject
/** The presenter for [OnboardingActivity]. */
@ActivityScope
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index ca19250a3e3..426877d528f 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -11,8 +11,13 @@ import androidx.viewpager2.widget.ViewPager2
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.PolicyPage
+import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.policies.RouteToPoliciesListener
import org.oppia.android.app.recyclerview.BindableAdapter
+import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightManager
+import org.oppia.android.app.spotlight.SpotlightShape
+import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.OnboardingFragmentBinding
@@ -22,11 +27,6 @@ import org.oppia.android.util.parser.html.HtmlParser
import org.oppia.android.util.parser.html.PolicyType
import org.oppia.android.util.statusbar.StatusBarColor
import javax.inject.Inject
-import org.oppia.android.app.model.Spotlight
-import org.oppia.android.app.spotlight.SpotlightFragment
-import org.oppia.android.app.spotlight.SpotlightManager
-import org.oppia.android.app.spotlight.SpotlightShape
-import org.oppia.android.app.spotlight.SpotlightTarget
/** The presenter for [OnboardingFragment]. */
@FragmentScope
@@ -66,7 +66,6 @@ class OnboardingFragmentPresenter @Inject constructor(
) as SpotlightFragment
}
-
fun startSpotlight() {
val nextSpotlightTarget = SpotlightTarget(
binding.onboardingFragmentNextImageView,
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index 838d5fc66ce..5415b655f04 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -13,7 +13,6 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.Transformations
-import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.AudioLanguage
@@ -36,6 +35,7 @@ import org.oppia.android.domain.profile.ProfileManagementController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.networking.NetworkConnectionUtil
+import javax.inject.Inject
const val TAG_LANGUAGE_DIALOG = "LANGUAGE_DIALOG"
private const val TAG_CELLULAR_DATA_DIALOG = "CELLULAR_DATA_DIALOG"
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
index a79d6a8f205..73e01018b72 100644
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
@@ -18,12 +18,17 @@ import org.oppia.android.app.model.EphemeralExploration
import org.oppia.android.app.model.ExplorationActivityParams
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.ReadingTextSize
+import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.options.OptionsActivity
import org.oppia.android.app.player.stopplaying.ProgressDatabaseFullDialogFragment
import org.oppia.android.app.player.stopplaying.UnsavedExplorationDialogFragment
import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightManager
+import org.oppia.android.app.spotlight.SpotlightShape
+import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
import org.oppia.android.app.topic.TopicActivity
+import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.utility.FontScaleConfigurationUtil
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.ExplorationActivityBinding
@@ -33,11 +38,6 @@ import org.oppia.android.domain.translation.TranslationController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import javax.inject.Inject
-import org.oppia.android.app.model.Spotlight
-import org.oppia.android.app.spotlight.SpotlightManager
-import org.oppia.android.app.spotlight.SpotlightShape
-import org.oppia.android.app.spotlight.SpotlightTarget
-import org.oppia.android.app.translation.AppLanguageResourceHandler
private const val TAG_UNSAVED_EXPLORATION_DIALOG = "UNSAVED_EXPLORATION_DIALOG"
private const val TAG_STOP_EXPLORATION_DIALOG = "STOP_EXPLORATION_DIALOG"
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragment.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragment.kt
index a662d79dbb0..b72f2f0da61 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragment.kt
@@ -12,7 +12,6 @@ import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.ReadingTextSize
import org.oppia.android.util.extensions.putProto
import javax.inject.Inject
-import org.oppia.android.app.translation.AppLanguageResourceHandler
/** Fragment that contains displays single exploration. */
class ExplorationFragment : InjectableFragment() {
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index 688f580b6dc..aa4536ce4db 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -8,7 +8,6 @@ import android.widget.ImageButton
import androidx.appcompat.widget.Toolbar
import androidx.core.view.forEach
import androidx.fragment.app.Fragment
-import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.ExplorationFragmentArguments
@@ -28,6 +27,7 @@ import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.extensions.getProto
import org.oppia.android.util.extensions.putProto
+import javax.inject.Inject
/** The presenter for [ExplorationFragment]. */
@FragmentScope
@@ -103,7 +103,8 @@ class ExplorationFragmentPresenter @Inject constructor(
}
}
- (fragment.requireActivity() as RequestVoiceOverIconSpotlightListener).requestVoiceOverIconSpotlight(numberOfLogins)
+ (fragment.requireActivity() as RequestVoiceOverIconSpotlightListener)
+ .requestVoiceOverIconSpotlight(numberOfLogins)
}
private fun getSpotlightFragment(): SpotlightFragment? {
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/RequestVoiceOverIconSpotlightListener.kt b/app/src/main/java/org/oppia/android/app/player/exploration/RequestVoiceOverIconSpotlightListener.kt
index c6ee800387d..e1094403d95 100644
--- a/app/src/main/java/org/oppia/android/app/player/exploration/RequestVoiceOverIconSpotlightListener.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/RequestVoiceOverIconSpotlightListener.kt
@@ -2,4 +2,4 @@ package org.oppia.android.app.player.exploration
interface RequestVoiceOverIconSpotlightListener {
fun requestVoiceOverIconSpotlight(numberOfLogins: Int)
-}
\ No newline at end of file
+}
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 d36af53c1ec..a781c6b5adc 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
@@ -1,6 +1,5 @@
package org.oppia.android.app.player.state
-import org.oppia.android.util.accessibility.AccessibilityService
import android.content.Context
import android.view.LayoutInflater
import android.view.View
@@ -36,6 +35,7 @@ import org.oppia.android.app.player.state.ConfettiConfig.MINI_CONFETTI_BURST
import org.oppia.android.app.player.state.listener.RouteToHintsAndSolutionListener
import org.oppia.android.app.player.stopplaying.StopStatePlayingSessionWithSavedProgressListener
import org.oppia.android.app.topic.conceptcard.ConceptCardFragment.Companion.CONCEPT_CARD_DIALOG_FRAGMENT_TAG
+import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.utility.LifecycleSafeTimerFactory
import org.oppia.android.app.utility.SplitScreenManager
import org.oppia.android.app.viewmodel.ViewModelProvider
@@ -43,6 +43,7 @@ import org.oppia.android.databinding.StateFragmentBinding
import org.oppia.android.domain.exploration.ExplorationProgressController
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.topic.StoryProgressController
+import org.oppia.android.util.accessibility.AccessibilityService
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProvider
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
@@ -50,7 +51,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.translation.AppLanguageResourceHandler
const val STATE_FRAGMENT_PROFILE_ID_ARGUMENT_KEY =
"StateFragmentPresenter.state_fragment_profile_id"
@@ -220,7 +220,6 @@ class StateFragmentPresenter @Inject constructor(
fun onHintAvailable(helpIndex: HelpIndex, isCurrentStatePendingState: Boolean) {
this.helpIndex = helpIndex
showHintsAndSolutions(helpIndex, isCurrentStatePendingState)
-
}
private fun createRecyclerViewAssembler(
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index f76b324d551..237f1b8f1b1 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -1,7 +1,6 @@
package org.oppia.android.app.spotlight
import android.content.Context
-import android.content.res.Resources
import android.util.DisplayMetrics
import android.util.Log
import android.view.View
@@ -18,8 +17,6 @@ import com.takusemba.spotlight.Target
import com.takusemba.spotlight.shape.Circle
import com.takusemba.spotlight.shape.RoundedRectangle
import com.takusemba.spotlight.shape.Shape
-import java.util.*
-import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentComponentImpl
import org.oppia.android.app.fragment.InjectableFragment
@@ -34,6 +31,8 @@ import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.util.accessibility.AccessibilityService
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
+import java.util.LinkedList
+import javax.inject.Inject
/**
* Fragment to hold the spotlights on elements. This fragments provides a single place for all the spotlight
@@ -159,7 +158,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
.setOverlay(requestOverlayResource(spotlightTarget))
.setOnTargetListener(object : OnTargetListener {
override fun onStarted() {
-
}
override fun onEnded() {
@@ -257,7 +255,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
} else {
AnchorPosition.TopLeft
}
-
}
private fun requestOverlayResource(spotlightTarget: SpotlightTarget): View {
@@ -328,15 +325,15 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
arrowParams.setMargins(
screenWidth - spotlightTarget.anchorLeft.toInt(),
(spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
} else {
arrowParams.setMargins(
spotlightTarget.anchorLeft.toInt(),
(spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
}
(overlayBinding as BottomLeftOverlayBinding).arrow.layoutParams = arrowParams
@@ -358,18 +355,18 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
as ViewGroup.MarginLayoutParams
if (isRTL) {
arrowParams.setMargins(
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
(spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
screenWidth -
(spotlightTarget.anchorLeft + getArrowWidth()).toInt(),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
} else {
arrowParams.setMargins(
(spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
(spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
}
(overlayBinding as BottomRightOverlayBinding).arrow.layoutParams = arrowParams
@@ -392,10 +389,10 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
as ViewGroup.MarginLayoutParams
if (isRTL) {
arrowParams.setMargins(
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
(spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
screenWidth - (spotlightTarget.anchorLeft + getArrowWidth()).toInt(),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
} else {
arrowParams.setMargins(
@@ -427,15 +424,15 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
arrowParams.setMargins(
screenWidth - spotlightTarget.anchorLeft.toInt(),
(spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
} else {
arrowParams.setMargins(
spotlightTarget.anchorLeft.toInt(),
(spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
}
(overlayBinding as TopLeftOverlayBinding).arrow.layoutParams = arrowParams
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt
index 9812e497881..091f1e98294 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt
@@ -30,4 +30,3 @@ interface SpotlightManager {
const val SPOTLIGHT_FRAGMENT_TAG = "SpotlightFragment"
}
}
-
diff --git a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
index cfd2da6c9cc..619a5d2fc21 100644
--- a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
+++ b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
@@ -3,10 +3,10 @@ package org.oppia.android.app.testing
import android.content.Context
import android.content.Intent
import android.os.Bundle
-import javax.inject.Inject
import org.oppia.android.app.activity.ActivityComponentImpl
import org.oppia.android.app.testing.activity.TestActivity
import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
+import javax.inject.Inject
/** Test Activity used for testing [SpotlightFragment]. */
class SpotlightFragmentTestActivity : TestActivity() {
@@ -39,4 +39,4 @@ class SpotlightFragmentTestActivity : TestActivity() {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt
index 611eccbf723..798d724e01c 100644
--- a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt
@@ -2,19 +2,19 @@ package org.oppia.android.app.testing
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
-import javax.inject.Inject
import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
import org.oppia.android.databinding.SpotlightFragmentTestActivityBinding
+import javax.inject.Inject
/** The presenter for [SpotlightFragmentTestActivity] */
@ActivityScope
class SpotlightFragmentTestActivityPresenter @Inject constructor(
private val activity: AppCompatActivity
- ) {
+) {
private lateinit var binding: SpotlightFragmentTestActivityBinding
@@ -44,4 +44,4 @@ class SpotlightFragmentTestActivityPresenter @Inject constructor(
/** Returns a view to be used as a spotlight anchor. */
fun getSampleSpotlightTarget() = binding.sampleSpotlightTarget
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
index da216ea176f..fb345ad8395 100755
--- a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
@@ -6,8 +6,8 @@ import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.spotlight.SpotlightFragment
-import javax.inject.Inject
import org.oppia.android.app.spotlight.SpotlightManager
+import javax.inject.Inject
const val TOPIC_FRAGMENT_TAG = "TopicFragment"
const val PROFILE_ID_ARGUMENT_KEY = "profile_id"
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 6de37a919da..e4e07819b24 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -13,6 +13,7 @@ import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.spotlight.SpotlightFragment
+import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.translation.AppLanguageResourceHandler
@@ -21,7 +22,6 @@ import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.util.platformparameter.EnableExtraTopicTabsUi
import org.oppia.android.util.platformparameter.PlatformParameterValue
import javax.inject.Inject
-import org.oppia.android.app.spotlight.SpotlightManager
/** The presenter for [TopicFragment]. */
@FragmentScope
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
index b52e0b680b2..308252f3fcd 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
@@ -66,6 +66,7 @@ import org.oppia.android.app.model.OppiaLanguage.ENGLISH_VALUE
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.ReadingTextSize
import org.oppia.android.app.model.ScreenName
+import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.profile.ProfileChooserActivity
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPosition
@@ -109,6 +110,7 @@ import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
+import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.domain.topic.FRACTIONS_STORY_ID_0
import org.oppia.android.domain.topic.FRACTIONS_TOPIC_ID
import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
@@ -149,9 +151,6 @@ import org.robolectric.annotation.LooperMode
import java.util.Locale
import javax.inject.Inject
import javax.inject.Singleton
-import org.oppia.android.app.model.Spotlight
-import org.oppia.android.domain.spotlight.SpotlightStateController
-import org.oppia.android.testing.DisableAccessibilityChecks
// Time: Tue Apr 23 2019 23:22:00
private const val EVENING_TIMESTAMP = 1556061720000
@@ -335,17 +334,18 @@ class HomeActivityTest {
}
@Test
- fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_spotlightNeverSeenBefore_checkSpotlightShown() {
+ fun testPromotedStorySpotlight_setToShowOnSecondLogin_notSeenBefore_checkSpotlightShown() {
logIntoUserTwice()
launch(createHomeActivityIntent(internalProfileId1)).use {
testCoroutineDispatchers.runCurrent()
- onView(withText(R.string.promoted_story_spotlight_hint)).check(matches(isDisplayed()))
+ onView(withText(R.string.promoted_story_spotlight_hint))
+ .check(matches(isDisplayed()))
}
}
@Test
- fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_pressDone_checkSpotlightIsNotShownAgain() {
- logIntoUserTwice()
+ fun testPromotedStoriesSpotlight_setToShowOnSecondLogin_pressDone_checkSpotlightNotShown() {
+ logIntoUserTwice()
launch(createHomeActivityIntent(internalProfileId1)).use {
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.close_target)).perform(click())
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
index 71c72263275..00c6ccf6f29 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
@@ -43,8 +43,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.rule.ActivityTestRule
import com.google.common.truth.Truth.assertThat
import dagger.Component
-import dagger.Module
-import dagger.Provides
import org.hamcrest.BaseMatcher
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.containsString
@@ -130,7 +128,6 @@ import org.oppia.android.domain.topic.TEST_TOPIC_ID_0
import org.oppia.android.domain.translation.TranslationController
import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule
import org.oppia.android.testing.BuildEnvironment
-import org.oppia.android.testing.DisableAccessibilityChecks
import org.oppia.android.testing.OppiaTestRule
import org.oppia.android.testing.RunOn
import org.oppia.android.testing.TestLogReportingModule
@@ -419,7 +416,7 @@ class ExplorationActivityTest {
}
@Test
- fun testVoiceoverLangIconSpotlight_setToShowOnIconClick_neverSeenBefore_checkSpotlightIsShown() {
+ fun testVoiceoverLangIconSpotlight_setToShowOnIconClick_notSeen_checkSpotlightIsShown() {
setUpAudioForFractionLesson()
markSpotlightSeen(Spotlight.FeatureCase.LESSONS_BACK_BUTTON)
markSpotlightSeen(Spotlight.FeatureCase.VOICEOVER_PLAY_ICON)
@@ -442,7 +439,8 @@ class ExplorationActivityTest {
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.action_audio_player)).perform(click())
testCoroutineDispatchers.runCurrent()
- onView(withText(R.string.voiceover_language_icon_spotlight_hint)).check(matches(isDisplayed()))
+ onView(withText(R.string.voiceover_language_icon_spotlight_hint))
+ .check(matches(isDisplayed()))
}
}
@@ -497,7 +495,7 @@ class ExplorationActivityTest {
}
@Test
- fun testBackButtonSpotlight_setToShowOnFirstLogin_neverSeenBefore_checkSpotlightIsShown() {
+ fun testBackButtonSpotlight_setToShowOnFirstLogin_notSeen_checkSpotlightIsShown() {
launch(
createExplorationActivityIntent(
internalProfileId,
@@ -514,7 +512,8 @@ class ExplorationActivityTest {
FRACTIONS_EXPLORATION_ID_0
)
- onView(withText(R.string.exploration_exit_button_spotlight_hint)).check(matches(isDisplayed()))
+ onView(withText(R.string.exploration_exit_button_spotlight_hint))
+ .check(matches(isDisplayed()))
}
}
@@ -554,12 +553,13 @@ class ExplorationActivityTest {
FRACTIONS_STORY_ID_0,
FRACTIONS_EXPLORATION_ID_0
)
- onView(withText(R.string.exploration_exit_button_spotlight_hint)).check(doesNotExist())
+ onView(withText(R.string.exploration_exit_button_spotlight_hint))
+ .check(doesNotExist())
}
}
@Test
- fun testVoiceoverIconSpotlight_setToShowOn3rdLoginChapterComplete_neverSeenBefore_checkSpotlightIsShown() {
+ fun testVoiceoverIconSpotlight_setToShowAfter3rdLogin_notSeen_checkSpotlightShown() {
logIntoUserThrice()
setUpAudioForFractionLesson()
markSpotlightSeen(Spotlight.FeatureCase.LESSONS_BACK_BUTTON)
@@ -580,12 +580,13 @@ class ExplorationActivityTest {
)
testCoroutineDispatchers.runCurrent()
- onView(withText(R.string.voiceover_icon_spotlight_hint)).check(matches(isDisplayed()))
+ onView(withText(R.string.voiceover_icon_spotlight_hint))
+ .check(matches(isDisplayed()))
}
}
@Test
- fun testVoiceoverIconSpotlight_setToShowOn3rdLoginChapterComplete_alreadySeen_checkSpotlightIsNotShown() {
+ fun testVoiceoverIconSpotlight_setToShowAfter3rdLogin_alreadySeen_checkSpotlightNotShown() {
logIntoUserThrice()
setUpAudioForFractionLesson()
markSpotlightSeen(Spotlight.FeatureCase.LESSONS_BACK_BUTTON)
@@ -625,12 +626,13 @@ class ExplorationActivityTest {
)
testCoroutineDispatchers.runCurrent()
- onView(withText(R.string.voiceover_icon_spotlight_hint)).check(doesNotExist())
+ onView(withText(R.string.voiceover_icon_spotlight_hint))
+ .check(doesNotExist())
}
}
@Test
- fun testVoiceoverIconSpotlight_setToShowOn3rdLoginChapterComplete_1stLogin_checkSpotlightIsNotShown() {
+ fun testVoiceoverIconSpotlight_setToShowAfter3rdLogin_1stLogin_checkNotShown() {
markSpotlightSeen(Spotlight.FeatureCase.LESSONS_BACK_BUTTON)
launch(
createExplorationActivityIntent(
@@ -649,7 +651,8 @@ class ExplorationActivityTest {
)
testCoroutineDispatchers.runCurrent()
- onView(withText(R.string.voiceover_icon_spotlight_hint)).check(doesNotExist())
+ onView(withText(R.string.voiceover_icon_spotlight_hint))
+ .check(doesNotExist())
}
}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
index cc09ae9a4c0..a4cab357641 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
@@ -2,7 +2,6 @@ package org.oppia.android.app.spotlight
import android.app.Application
import android.content.Context
-import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import androidx.test.core.app.ActivityScenario.launch
import androidx.test.core.app.ApplicationProvider
@@ -14,17 +13,12 @@ import androidx.test.espresso.intent.Intents
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
-import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import dagger.Component
-import javax.inject.Inject
-import javax.inject.Singleton
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
-import org.junit.rules.RuleChain
-import org.junit.rules.TestRule
import org.junit.runner.RunWith
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoRule
@@ -78,10 +72,8 @@ import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModu
import org.oppia.android.domain.question.QuestionModule
import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule
-import org.oppia.android.testing.OppiaTestRule
import org.oppia.android.testing.TestImageLoaderModule
import org.oppia.android.testing.TestLogReportingModule
-import org.oppia.android.testing.junit.InitializeDefaultLocaleRule
import org.oppia.android.testing.robolectric.RobolectricModule
import org.oppia.android.testing.threading.TestCoroutineDispatchers
import org.oppia.android.testing.threading.TestDispatcherModule
@@ -102,6 +94,8 @@ import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule
import org.oppia.android.util.parser.image.ImageParsingModule
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
/** Tests for [SpotlightFragment]. */
@RunWith(AndroidJUnit4::class)
@@ -194,7 +188,7 @@ class SpotlightFragmentTest {
activity.getSpotlightFragment()
).requestSpotlightViewWithDelayedLayout(spotlightTarget)
}
- onView(withText(sampleSpotlightText)).check(matches(isDisplayed()))
+ onView(withText(sampleSpotlightText)).check(matches(isDisplayed()))
}
}
@@ -203,7 +197,7 @@ class SpotlightFragmentTest {
launch(
createSpotlightFragmentTestActivity(context)
).use {
- it.onActivity { activity->
+ it.onActivity { activity ->
val spotlightTarget = SpotlightTarget(
activity.getSampleSpotlightTarget(),
sampleSpotlightText,
@@ -356,4 +350,4 @@ class SpotlightFragmentTest {
override fun getApplicationInjector(): ApplicationInjector = component
}
-}
\ No newline at end of file
+}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
index 279c42540dd..d4ba555dbb2 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
@@ -39,6 +39,9 @@ import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.ScreenName
+import org.oppia.android.app.model.Spotlight.FeatureCase.FIRST_CHAPTER
+import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_LESSON_TAB
+import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_REVISION_TAB
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.shim.ViewBindingShimModule
import org.oppia.android.app.topic.questionplayer.QuestionPlayerActivity
@@ -71,6 +74,7 @@ import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModul
import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
+import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.domain.topic.FRACTIONS_STORY_ID_0
import org.oppia.android.domain.topic.FRACTIONS_TOPIC_ID
import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
@@ -104,8 +108,6 @@ import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
import javax.inject.Inject
import javax.inject.Singleton
-import org.oppia.android.app.model.Spotlight
-import org.oppia.android.domain.spotlight.SpotlightStateController
/** Tests for [TopicActivity]. */
@RunWith(AndroidJUnit4::class)
@@ -214,11 +216,11 @@ class TopicActivityTest {
private fun markAllSpotlightsSeen() {
val profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
- spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_LESSON_TAB)
+ spotlightStateController.markSpotlightViewed(profileId, TOPIC_LESSON_TAB)
testCoroutineDispatchers.runCurrent()
- spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_REVISION_TAB)
+ spotlightStateController.markSpotlightViewed(profileId, TOPIC_REVISION_TAB)
testCoroutineDispatchers.runCurrent()
- spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.FIRST_CHAPTER)
+ spotlightStateController.markSpotlightViewed(profileId, FIRST_CHAPTER)
testCoroutineDispatchers.runCurrent()
}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
index d027194820f..8fc1cd81093 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
@@ -26,8 +26,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.rule.ActivityTestRule
import com.google.common.truth.Truth.assertThat
import dagger.Component
-import javax.inject.Inject
-import javax.inject.Singleton
import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.Matchers.allOf
import org.junit.After
@@ -48,7 +46,7 @@ import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.ProfileId
-import org.oppia.android.app.model.Spotlight
+import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_REVISION_TAB
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPositionOnView
import org.oppia.android.app.shim.ViewBindingShimModule
@@ -118,6 +116,8 @@ import org.oppia.android.util.platformparameter.EnableExtraTopicTabsUi
import org.oppia.android.util.platformparameter.PlatformParameterValue
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
private const val INFO_TAB_POSITION = 0
private const val LESSON_TAB_POSITION = 1
@@ -258,7 +258,7 @@ class TopicFragmentTest {
}
@Test
- fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_notSeenBefore_checkIsShown() {
+ fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_notSeenBefore_checkShown() {
initializeApplicationComponent(false)
markFirstChapterSpotlightSeen()
markLessonsTabSpotlightSeen()
@@ -267,7 +267,9 @@ class TopicFragmentTest {
storyProgressTestHelper.markCompletedRatiosStory0Exp0(profileId, false)
storyProgressTestHelper.markCompletedRatiosStory1Exp0(profileId, false)
testCoroutineDispatchers.runCurrent()
- launch(createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)).use {
+ launch(
+ createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)
+ ).use {
testCoroutineDispatchers.runCurrent()
onView(withText(R.string.topic_revision_tab_spotlight_hint)).check(matches(isDisplayed()))
@@ -275,18 +277,20 @@ class TopicFragmentTest {
}
@Test
- fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_chaptersNotComplete_checkIsNotShown() {
+ fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_notComplete_checkNotShown() {
initializeApplicationComponent(false)
markLessonsTabSpotlightSeen()
markFirstChapterSpotlightSeen()
- launch(createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)).use {
+ launch(
+ createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)
+ ).use {
testCoroutineDispatchers.runCurrent()
onView(withText(R.string.topic_revision_tab_spotlight_hint)).check(doesNotExist())
}
}
@Test
- fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_alreadySeen_checkIsNotShown() {
+ fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_alreadySeen_checkNotShown() {
initializeApplicationComponent(false)
markLessonsTabSpotlightSeen()
markFirstChapterSpotlightSeen()
@@ -295,13 +299,17 @@ class TopicFragmentTest {
storyProgressTestHelper.markCompletedFractionsStory0Exp0(profileId, false)
storyProgressTestHelper.markCompletedRatiosStory0Exp0(profileId, false)
storyProgressTestHelper.markCompletedRatiosStory1Exp0(profileId, false)
- launch(createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)).use {
+ launch(
+ createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)
+ ).use {
testCoroutineDispatchers.runCurrent()
// mark revision tab spotlight seen
onView(withId(R.id.close_target)).perform(click())
}
- launch(createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)).use {
+ launch(
+ createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)
+ ).use {
testCoroutineDispatchers.runCurrent()
onView(withText(R.string.topic_revision_tab_spotlight_hint)).check(doesNotExist())
}
@@ -807,7 +815,7 @@ class TopicFragmentTest {
val profileId = ProfileId.newBuilder()
.setInternalId(internalProfileId)
.build()
- spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_REVISION_TAB)
+ spotlightStateController.markSpotlightViewed(profileId, TOPIC_REVISION_TAB)
testCoroutineDispatchers.runCurrent()
}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
index ed0ee7fbed1..b575da5d462 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
@@ -55,7 +55,9 @@ import org.oppia.android.app.model.ExplorationActivityParams
import org.oppia.android.app.model.ExplorationCheckpoint
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.ResumeLessonActivityParams
-import org.oppia.android.app.model.Spotlight
+import org.oppia.android.app.model.Spotlight.FeatureCase.FIRST_CHAPTER
+import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_LESSON_TAB
+import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_REVISION_TAB
import org.oppia.android.app.player.exploration.ExplorationActivity
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPosition
@@ -940,11 +942,11 @@ class TopicLessonsFragmentTest {
}
private fun markAllSpotlightsSeen() {
- spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_LESSON_TAB)
+ spotlightStateController.markSpotlightViewed(profileId, TOPIC_LESSON_TAB)
testCoroutineDispatchers.runCurrent()
- spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_REVISION_TAB)
+ spotlightStateController.markSpotlightViewed(profileId, TOPIC_REVISION_TAB)
testCoroutineDispatchers.runCurrent()
- spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.FIRST_CHAPTER)
+ spotlightStateController.markSpotlightViewed(profileId, FIRST_CHAPTER)
testCoroutineDispatchers.runCurrent()
}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
index 7c2095ae016..707656365c0 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
@@ -41,6 +41,7 @@ import org.oppia.android.app.application.ApplicationStartupListenerModule
import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
+import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPositionOnView
import org.oppia.android.app.shim.ViewBindingShimModule
@@ -78,6 +79,7 @@ import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModul
import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
+import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.domain.topic.FRACTIONS_TOPIC_ID
import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule
@@ -109,9 +111,6 @@ import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
import javax.inject.Inject
import javax.inject.Singleton
-import org.oppia.android.app.model.ProfileId
-import org.oppia.android.app.model.Spotlight
-import org.oppia.android.domain.spotlight.SpotlightStateController
/** Tests for [TopicPracticeFragment]. */
@RunWith(AndroidJUnit4::class)
@@ -423,11 +422,11 @@ class TopicPracticeFragmentTest {
private fun markAllSpotlightsSeen() {
val profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
- spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_LESSON_TAB)
+ spotlightStateController.markSpotlightViewed(profileId, TOPIC_LESSON_TAB)
testCoroutineDispatchers.runCurrent()
- spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_REVISION_TAB)
+ spotlightStateController.markSpotlightViewed(profileId, TOPIC_REVISION_TAB)
testCoroutineDispatchers.runCurrent()
- spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.FIRST_CHAPTER)
+ spotlightStateController.markSpotlightViewed(profileId, FIRST_CHAPTER)
testCoroutineDispatchers.runCurrent()
}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt
index 4bf289ed0c9..39ce9928ea6 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt
@@ -41,6 +41,10 @@ import org.oppia.android.app.application.ApplicationStartupListenerModule
import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
+import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.model.Spotlight.FeatureCase.FIRST_CHAPTER
+import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_LESSON_TAB
+import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_REVISION_TAB
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPosition
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPositionOnView
@@ -79,6 +83,7 @@ import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModul
import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
+import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.domain.topic.FRACTIONS_TOPIC_ID
import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule
@@ -111,9 +116,6 @@ import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
import javax.inject.Inject
import javax.inject.Singleton
-import org.oppia.android.app.model.ProfileId
-import org.oppia.android.app.model.Spotlight
-import org.oppia.android.domain.spotlight.SpotlightStateController
/** Tests for [TopicRevisionFragment]. */
@RunWith(AndroidJUnit4::class)
@@ -278,11 +280,11 @@ class TopicRevisionFragmentTest {
private fun markAllSpotlightsSeen() {
val profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
- spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_LESSON_TAB)
+ spotlightStateController.markSpotlightViewed(profileId, TOPIC_LESSON_TAB)
testCoroutineDispatchers.runCurrent()
- spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_REVISION_TAB)
+ spotlightStateController.markSpotlightViewed(profileId, TOPIC_REVISION_TAB)
testCoroutineDispatchers.runCurrent()
- spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.FIRST_CHAPTER)
+ spotlightStateController.markSpotlightViewed(profileId, FIRST_CHAPTER)
testCoroutineDispatchers.runCurrent()
}
diff --git a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
index a4323114546..2e3ca154ae5 100644
--- a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
@@ -136,6 +136,7 @@ import org.oppia.android.testing.junit.DefineAppLanguageLocaleContext
import org.oppia.android.testing.junit.InitializeDefaultLocaleRule
import org.oppia.android.testing.profile.ProfileTestHelper
import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.story.StoryProgressTestHelper
import org.oppia.android.testing.threading.CoroutineExecutorService
import org.oppia.android.testing.threading.TestCoroutineDispatchers
import org.oppia.android.testing.threading.TestDispatcherModule
@@ -168,7 +169,6 @@ import java.util.Locale
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Singleton
-import org.oppia.android.testing.story.StoryProgressTestHelper
/**
* Tests for [StateFragment] that can only be run locally, e.g. using Robolectric, and not on an
From acff280895eee00dc99aa5f49a194d2bad0452ac Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sat, 19 Nov 2022 02:22:59 +0530
Subject: [PATCH 096/138] use spannable to highlight text
---
.../app/spotlight/SpotlightFragment.kt | 39 ++++++++++++++-----
.../main/res/layout/bottom_left_overlay.xml | 1 -
.../main/res/layout/bottom_right_overlay.xml | 1 -
app/src/main/res/layout/top_left_overlay.xml | 3 +-
app/src/main/res/layout/top_right_overlay.xml | 1 -
app/src/main/res/values/colors_migrating.xml | 2 +
6 files changed, 32 insertions(+), 15 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 237f1b8f1b1..0bb8cdc3764 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -1,6 +1,9 @@
package org.oppia.android.app.spotlight
import android.content.Context
+import android.text.Spannable
+import android.text.SpannableString
+import android.text.style.BackgroundColorSpan
import android.util.DisplayMetrics
import android.util.Log
import android.view.View
@@ -32,12 +35,13 @@ import org.oppia.android.util.accessibility.AccessibilityService
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import java.util.LinkedList
+import java.util.Locale
import javax.inject.Inject
/**
- * Fragment to hold the spotlights on elements. This fragments provides a single place for all the spotlight
- * interactions, and handles lifecycle related functionality for spotlights, such as surviving orientation changes
- * and marking spotlights as seen.
+ * Fragment to hold the spotlights on elements. This fragments provides a single place for all the
+ * spotlight interactions, and handles lifecycle related functionality for spotlights, such as
+ * surviving orientation changes and marking spotlights as seen.
*/
class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, SpotlightManager {
@Inject
@@ -83,9 +87,9 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
/**
* Requests a spotlight to be shown on the [SpotlightTarget]. The spotlight is enqueued if it
- * hasn't been shown before in a FIFO buffer. This API can ensure proper spotlighting of a [SpotlightTarget]
- * which is laid out after an animation. For the spotlights to work correctly, we must know the
- * [SpotlightTarget]'s anchor's size and position. For a view that is laid out after an animation, we must
+ * [SpotlightTarget] hasn't been shown before in a FIFO buffer. This API can ensure proper
+ * spotlighting of a which is laid out after an animation. For the spotlights to work correctly,
+ * we must know the [SpotlightTarget]'s anchor's size and position. For a view that is laid out after an animation, we must
* wait until the final size and positions of the anchor view are measured, which can be achieved by using
* doOnPreDraw (refer: https://betterprogramming.pub/stop-using-post-postdelayed-in-your-android-views-9d1c8eeaadf2).
*
@@ -317,7 +321,8 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
it.listener = this
}
- (overlayBinding as BottomLeftOverlayBinding).customText.text = spotlightTarget.hint
+ (overlayBinding as BottomLeftOverlayBinding).customText.text =
+ getSpannableHint(spotlightTarget.hint)
val arrowParams = (overlayBinding as BottomLeftOverlayBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
@@ -349,7 +354,8 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
it.listener = this
}
- (overlayBinding as BottomRightOverlayBinding).customText.text = spotlightTarget.hint
+ (overlayBinding as BottomRightOverlayBinding).customText.text =
+ getSpannableHint(spotlightTarget.hint)
val arrowParams = (overlayBinding as BottomRightOverlayBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
@@ -374,6 +380,17 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
return (overlayBinding as BottomRightOverlayBinding).root
}
+ private fun getSpannableHint(hint: String): SpannableString {
+ val spannable = SpannableString(hint)
+ spannable.setSpan(
+ BackgroundColorSpan(resources.getColor(R.color.spotlight_hint_background)),
+ 0, // start
+ spannable.length, // end
+ Spannable.SPAN_INCLUSIVE_INCLUSIVE
+ )
+ return spannable
+ }
+
private fun configureTopRightOverlay(spotlightTarget: SpotlightTarget): View {
Log.d("overlay", "top right overlay")
@@ -383,7 +400,8 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
it.listener = this
}
- (overlayBinding as TopRightOverlayBinding).customText.text = spotlightTarget.hint
+ (overlayBinding as TopRightOverlayBinding).customText.text =
+ getSpannableHint(spotlightTarget.hint)
val arrowParams = (overlayBinding as TopRightOverlayBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
@@ -416,7 +434,8 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
it.listener = this
}
- (overlayBinding as TopLeftOverlayBinding).customText.text = spotlightTarget.hint
+ (overlayBinding as TopLeftOverlayBinding).customText.text =
+ getSpannableHint(spotlightTarget.hint)
val arrowParams = (overlayBinding as TopLeftOverlayBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 33924f3cd3e..e85bfd1f4e5 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -35,7 +35,6 @@
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:text="this is a custom text"
- android:textColor="@android:color/white"
android:textSize="24dp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@id/arrow"
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index 0b39c5d055c..a8e3331c824 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -36,7 +36,6 @@
android:layout_height="wrap_content"
android:text="this is a custom text"
android:textAlignment="viewEnd"
- android:textColor="@android:color/white"
android:textSize="24dp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index 96aef3e9f12..b717c0d0d8c 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -24,7 +24,7 @@
android:layout_width="@dimen/arrow_width"
android:layout_height="@dimen/arrow_height"
app:srcCompat="@drawable/ic_rounded_arrow_up_right"
- app:layout_constraintStart_toStartOfC="parent"
+ app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
#674172
#7659B6
#BF000000
+
+ #FFFFF0
From ce463bf5f0252ddda73e0ae83b577abb2901df1a Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sat, 19 Nov 2022 06:03:37 +0530
Subject: [PATCH 097/138] suggestions
---
app/BUILD.bazel | 2 +-
...pterNotStartedContainerConstraintLayout.kt | 2 +
.../app/customview/PromotedStoryCardView.kt | 2 +
.../RequestVoiceOverIconSpotlightListener.kt | 2 +
.../app/spotlight/SpotlightFragment.kt | 41 +++++++++++--------
.../spotlight/SpotlightNavigationListener.kt | 7 ++--
.../android/app/spotlight/SpotlightTarget.kt | 7 ++++
.../practice/TopicPracticeFragmentTest.kt | 3 ++
.../file_content_validation_checks.textproto | 1 +
9 files changed, 45 insertions(+), 22 deletions(-)
diff --git a/app/BUILD.bazel b/app/BUILD.bazel
index 96c78b39d66..fb6e16220fe 100644
--- a/app/BUILD.bazel
+++ b/app/BUILD.bazel
@@ -772,6 +772,7 @@ kt_android_library(
"//domain/src/main/java/org/oppia/android/domain/onboarding:state_controller",
"//domain/src/main/java/org/oppia/android/domain/oppialogger:startup_listener",
"//domain/src/main/java/org/oppia/android/domain/profile:profile_management_controller",
+ "//domain/src/main/java/org/oppia/android/domain/spotlight:spotlight_state_controller",
"//model/src/main/proto:arguments_java_proto_lite",
"//third_party:androidx_databinding_databinding-adapters",
"//third_party:androidx_databinding_databinding-common",
@@ -784,7 +785,6 @@ kt_android_library(
"//third_party:androidx_viewpager_viewpager",
"//third_party:com_caverock_androidsvg",
"//third_party:com_github_takusemba_spotlight",
- "//domain/src/main/java/org/oppia/android/domain/spotlight:spotlight_state_controller",
"//third_party:com_google_android_flexbox_flexbox",
"//third_party:javax_annotation_javax_annotation-api_jar",
"//utility",
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index ad8cc1a4f53..5d92ec9b9a2 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -14,6 +14,7 @@ import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
import javax.inject.Inject
+/** Custom view to hold the chapter that has not yet been started. */
class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@@ -29,6 +30,7 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
@Inject
lateinit var resourceHandler: AppLanguageResourceHandler
+ /** Set the index of the story of which this custom view is a part of. */
fun setStoryIndex(index: Int) {
// Only spotlight the first chapter of the "first" story. We know for sure that for a new user,
// the first chapter shall be a type of not started chapter view. The index tells which story
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
index 1dbd47e7407..a77c80099cd 100644
--- a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -14,6 +14,7 @@ import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
import javax.inject.Inject
+/** Custom view to hold the promoted story cards. */
class PromotedStoryCardView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@@ -28,6 +29,7 @@ class PromotedStoryCardView @JvmOverloads constructor(
private var isSpotlit = false
+ /** Sets the index at which this custom view is located inside the recycler view. */
fun setIndex(index: Int) {
if (!isSpotlit) {
isSpotlit = true
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/RequestVoiceOverIconSpotlightListener.kt b/app/src/main/java/org/oppia/android/app/player/exploration/RequestVoiceOverIconSpotlightListener.kt
index e1094403d95..99057215de2 100644
--- a/app/src/main/java/org/oppia/android/app/player/exploration/RequestVoiceOverIconSpotlightListener.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/RequestVoiceOverIconSpotlightListener.kt
@@ -1,5 +1,7 @@
package org.oppia.android.app.player.exploration
+/** Interface to request voice-over icon spotlight. */
interface RequestVoiceOverIconSpotlightListener {
+ /** Requests the spotlight fragment to show voice-over icon spotlight. */
fun requestVoiceOverIconSpotlight(numberOfLogins: Int)
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 0bb8cdc3764..8815f70405c 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -10,6 +10,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.animation.DecelerateInterpolator
import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.ViewCompat
import androidx.core.view.doOnPreDraw
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
@@ -35,8 +36,8 @@ import org.oppia.android.util.accessibility.AccessibilityService
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import java.util.LinkedList
-import java.util.Locale
import javax.inject.Inject
+import org.oppia.android.app.translation.AppLanguageResourceHandler
/**
* Fragment to hold the spotlights on elements. This fragments provides a single place for all the
@@ -53,6 +54,9 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
@Inject
lateinit var accessibilityService: AccessibilityService
+ @Inject
+ lateinit var resourceHandler: AppLanguageResourceHandler
+
private var targetList = LinkedList()
private lateinit var spotlight: Spotlight
private var screenHeight: Int = 0
@@ -60,7 +64,11 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
private lateinit var overlayBinding: Any
private var internalProfileId: Int = -1
private val isSpotlightActive = MutableLiveData(false)
- private var isRTL = false
+
+
+ private val isRtl by lazy {
+ resourceHandler.getLayoutDirection() == ViewCompat.LAYOUT_DIRECTION_RTL
+ }
private fun calculateScreenSize() {
val displayMetrics = DisplayMetrics()
@@ -221,13 +229,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
}
- private fun checkIsRTL() {
- val locale = Locale.getDefault()
- val directionality: Byte = Character.getDirectionality(locale.displayName[0].toInt())
- isRTL = directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT ||
- directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT
- }
-
private fun getArrowWidth(): Float {
return this.resources.getDimension(R.dimen.arrow_width)
}
@@ -247,7 +248,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
private fun calculateAnchorPosition(spotlightTarget: SpotlightTarget): AnchorPosition {
- Log.d("overlay", "checking anchor position. RTL = $isRTL")
+ Log.d("overlay", "checking anchor position. RTL = $isRtl")
return if (spotlightTarget.anchorCentreX > getScreenCentreX()) {
if (spotlightTarget.anchorCentreY > getScreenCentreY()) {
AnchorPosition.BottomRight
@@ -267,28 +268,28 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
return when (anchorPosition) {
AnchorPosition.TopLeft -> {
- if (isRTL) {
+ if (isRtl) {
configureTopRightOverlay(spotlightTarget)
} else {
configureTopLeftOverlay(spotlightTarget)
}
}
AnchorPosition.TopRight -> {
- if (isRTL) {
+ if (isRtl) {
configureTopLeftOverlay(spotlightTarget)
} else {
configureTopRightOverlay(spotlightTarget)
}
}
AnchorPosition.BottomRight -> {
- if (isRTL) {
+ if (isRtl) {
configureBottomLeftOverlay(spotlightTarget)
} else {
configureBottomRightOverlay(spotlightTarget)
}
}
AnchorPosition.BottomLeft -> {
- if (isRTL) {
+ if (isRtl) {
configureBottomRightOverlay(spotlightTarget)
} else {
configureBottomLeftOverlay(spotlightTarget)
@@ -298,9 +299,13 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
private sealed class AnchorPosition {
+ /** The position corresponding to the anchor when it is on the top left of the screen. */
object TopLeft : AnchorPosition()
+ /** The position corresponding to the anchor when it is on the top right of the screen. */
object TopRight : AnchorPosition()
+ /** The position corresponding to the anchor when it is on the bottom left of the screen. */
object BottomLeft : AnchorPosition()
+ /** The position corresponding to the anchor when it is on the bottom right of the screen. */
object BottomRight : AnchorPosition()
}
@@ -326,7 +331,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
val arrowParams = (overlayBinding as BottomLeftOverlayBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
- if (isRTL) {
+ if (isRtl) {
arrowParams.setMargins(
screenWidth - spotlightTarget.anchorLeft.toInt(),
(spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
@@ -359,7 +364,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
val arrowParams = (overlayBinding as BottomRightOverlayBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
- if (isRTL) {
+ if (isRtl) {
arrowParams.setMargins(
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
(spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
@@ -405,7 +410,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
val arrowParams = (overlayBinding as TopRightOverlayBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
- if (isRTL) {
+ if (isRtl) {
arrowParams.setMargins(
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
(spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
@@ -439,7 +444,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
val arrowParams = (overlayBinding as TopLeftOverlayBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
- if (isRTL) {
+ if (isRtl) {
arrowParams.setMargins(
screenWidth - spotlightTarget.anchorLeft.toInt(),
(spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightNavigationListener.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightNavigationListener.kt
index fa6c85153db..a68907ef488 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightNavigationListener.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightNavigationListener.kt
@@ -1,8 +1,9 @@
package org.oppia.android.app.spotlight
+/** Listener for the spotlight navigation buttons. */
interface SpotlightNavigationListener {
-
- fun clickOnDismiss()
-
+ /** Called when the done button is clicked. */
fun clickOnNextTip()
+ /** Called when the dismiss button is clicked. */
+ fun clickOnDismiss()
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
index 608f1c7c452..97c935b4b3f 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
@@ -17,11 +17,18 @@ data class SpotlightTarget(
val shape: SpotlightShape = SpotlightShape.RoundedRectangle,
val feature: FeatureCase
) {
+
+ /** The left margin of the anchor. */
val anchorLeft: Float = calculateAnchorLeft()
+ /** The top margin of the anchor. */
val anchorTop: Float = calculateAnchorTop()
+ /** The height of the anchor. */
val anchorHeight: Int = calculateAnchorHeight()
+ /** The width of the anchor. */
val anchorWidth: Int = calculateAnchorWidth()
+ /** The position of the vertical centre of the anchor. */
val anchorCentreX = calculateAnchorCentreX()
+ /** The margin of the horizontal anchor. */
val anchorCentreY = calculateAnchorCentreY()
init {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
index 707656365c0..9aee35a956f 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
@@ -42,6 +42,9 @@ import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.model.Spotlight.FeatureCase.FIRST_CHAPTER
+import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_LESSON_TAB
+import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_REVISION_TAB
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPositionOnView
import org.oppia.android.app.shim.ViewBindingShimModule
diff --git a/scripts/assets/file_content_validation_checks.textproto b/scripts/assets/file_content_validation_checks.textproto
index 3b76a194cc7..da762d4dcff 100644
--- a/scripts/assets/file_content_validation_checks.textproto
+++ b/scripts/assets/file_content_validation_checks.textproto
@@ -16,6 +16,7 @@ file_content_checks {
failure_message: "When using announceForAccessibility, please add an exempt file in file_content_validation_checks.textproto."
exempted_file_name: "app/src/main/java/org/oppia/android/app/player/state/StatePlayerRecyclerViewAssembler.kt"
exempted_file_name: "app/src/test/java/org/oppia/android/app/accessibility/FakeAccessibilityServiceTest.kt"
+ exempted_file_name: "app/src/main/java/org/oppia/android/app/player/state/StateFragmentPresenter.kt"
exempted_file_name: "scripts/src/javatests/org/oppia/android/scripts/regex/RegexPatternValidationCheckTest.kt"
exempted_file_name: "utility/src/main/java/org/oppia/android/util/accessibility/AccessibilityService.kt"
exempted_file_name: "utility/src/main/java/org/oppia/android/util/accessibility/AccessibilityServiceImpl.kt"
From d0787a75092139252fafbf924f127744549cf30e Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sat, 19 Nov 2022 06:05:26 +0530
Subject: [PATCH 098/138] lint
---
.../java/org/oppia/android/app/spotlight/SpotlightFragment.kt | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 8815f70405c..a4d44671998 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -27,6 +27,7 @@ import org.oppia.android.app.fragment.InjectableFragment
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.SpotlightViewState
import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
+import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.databinding.BottomLeftOverlayBinding
import org.oppia.android.databinding.BottomRightOverlayBinding
import org.oppia.android.databinding.TopLeftOverlayBinding
@@ -37,7 +38,6 @@ import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import java.util.LinkedList
import javax.inject.Inject
-import org.oppia.android.app.translation.AppLanguageResourceHandler
/**
* Fragment to hold the spotlights on elements. This fragments provides a single place for all the
@@ -65,7 +65,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
private var internalProfileId: Int = -1
private val isSpotlightActive = MutableLiveData(false)
-
private val isRtl by lazy {
resourceHandler.getLayoutDirection() == ViewCompat.LAYOUT_DIRECTION_RTL
}
From 15eb671db779fb8ef8df198f425e6c964d8638bc Mon Sep 17 00:00:00 2001
From: Ben Henning
Date: Fri, 18 Nov 2022 17:37:39 -0800
Subject: [PATCH 099/138] Fix broken test.
To ensure doOnPreDraw actually runs, we need to request that the view
gets re-drawn.
---
.../org/oppia/android/app/spotlight/SpotlightFragment.kt | 2 ++
.../oppia/android/app/spotlight/SpotlightFragmentTest.kt | 9 +++------
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index a4d44671998..7bde5b7d86d 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -115,6 +115,8 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
)
requestSpotlight(targetAfterViewFullyDrawn)
}
+ spotlightTarget.anchor.invalidate()
+ spotlightTarget.anchor.requestLayout()
}
/**
diff --git a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
index a4cab357641..a9d86c3b326 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
@@ -172,9 +172,7 @@ class SpotlightFragmentTest {
@Test
fun testSpotlightFragment_requestDelayedSpotlight_shouldShowSpotlight() {
- launch(
- createSpotlightFragmentTestActivity(context)
- ).use {
+ launch(createSpotlightFragmentTestActivity(context)).use {
testCoroutineDispatchers.runCurrent()
it.onActivity { activity ->
val spotlightTarget = SpotlightTarget(
@@ -187,6 +185,7 @@ class SpotlightFragmentTest {
checkNotNull(
activity.getSpotlightFragment()
).requestSpotlightViewWithDelayedLayout(spotlightTarget)
+ testCoroutineDispatchers.runCurrent()
}
onView(withText(sampleSpotlightText)).check(matches(isDisplayed()))
}
@@ -194,9 +193,7 @@ class SpotlightFragmentTest {
@Test
fun testSpotlightFragment_markSpotlightSeen_checkSpotlightIsNotShowAgain() {
- launch(
- createSpotlightFragmentTestActivity(context)
- ).use {
+ launch(createSpotlightFragmentTestActivity(context)).use {
it.onActivity { activity ->
val spotlightTarget = SpotlightTarget(
activity.getSampleSpotlightTarget(),
From 2b92e629343fa1e5a82d6baa434d0e490a7f2a36 Mon Sep 17 00:00:00 2001
From: Ben Henning
Date: Sat, 19 Nov 2022 03:38:06 -0800
Subject: [PATCH 100/138] Fix variety of issues.
---
WORKSPACE | 4 ++--
app/build.gradle | 2 +-
.../ExplorationActivityPresenter.kt | 9 ++++++---
.../app/spotlight/SpotlightFragment.kt | 1 -
.../android/app/spotlight/SpotlightManager.kt | 4 ++++
.../exploration/ExplorationActivityTest.kt | 19 ++++++++++++++++---
.../android/app/topic/TopicFragmentTest.kt | 6 ++++--
instrumentation/src/java/AndroidManifest.xml | 2 +-
8 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/WORKSPACE b/WORKSPACE
index 9132e5d85c7..17ac191b294 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -132,9 +132,9 @@ git_repository(
git_repository(
name = "android-spotlight",
- commit = "1ba764bb9e3685947433f115120448910ef737ed",
+ commit = "ebde38335bfb56349eae57e705b611ead9addb15",
remote = "https://github.com/oppia/android-spotlight",
- shallow_since = "1667677977 -0500",
+ shallow_since = "1668824029 -0800",
)
# A custom fork of KotliTeX that removes resources artifacts that break the build, and updates the
diff --git a/app/build.gradle b/app/build.gradle
index 91b446fb173..7210225d4e2 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -178,7 +178,7 @@ dependencies {
'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1',
'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1',
'org.mockito:mockito-core:2.7.22',
- 'com.github.oppia:android-spotlight:1ba764bb9e'
+ 'com.github.oppia:android-spotlight:ebde38335bfb56349eae57e705b611ead9addb15'
)
compileOnly(
'jakarta.xml.bind:jakarta.xml.bind-api:2.3.2',
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
index 73e01018b72..0338c054884 100644
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
@@ -55,7 +55,7 @@ class ExplorationActivityPresenter @Inject constructor(
private val fontScaleConfigurationUtil: FontScaleConfigurationUtil,
private val translationController: TranslationController,
private val oppiaLogger: OppiaLogger,
- private val resouceHandler: AppLanguageResourceHandler
+ private val resourceHandler: AppLanguageResourceHandler
) {
private lateinit var explorationToolbar: Toolbar
private lateinit var explorationToolbarTitle: TextView
@@ -149,10 +149,13 @@ class ExplorationActivityPresenter @Inject constructor(
fun requestVoiceOverIconSpotlight(numberOfLogins: Int) {
if (numberOfLogins >= 3) {
- // spotlight voice-over icon after 3 logins
+ // Spotlight the voice-over icon after 3 or more logins.
val audioPlayerSpotlightTarget = SpotlightTarget(
binding.actionAudioPlayer,
- resouceHandler.getStringInLocale(R.string.voiceover_icon_spotlight_hint),
+ resourceHandler.getStringInLocaleWithWrapping(
+ R.string.voiceover_icon_spotlight_hint,
+ resourceHandler.getStringInLocale(R.string.app_name)
+ ),
SpotlightShape.Circle,
Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 7bde5b7d86d..818f41eb93c 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -89,7 +89,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
internalProfileId = arguments?.getInt(PROFILE_ID_ARGUMENT_KEY) ?: -1
calculateScreenSize()
- checkIsRTL()
}
/**
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt
index 091f1e98294..e8084388f82 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt
@@ -27,6 +27,10 @@ interface SpotlightManager {
fun requestSpotlight(spotlightTarget: SpotlightTarget)
companion object {
+ /**
+ * The tag that should be associated with fragment implementations of [SpotlightManager] so that
+ * it can be used for later retrieval.
+ */
const val SPOTLIGHT_FRAGMENT_TAG = "SpotlightFragment"
}
}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
index 00c6ccf6f29..8ad2f0ff05e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
@@ -496,6 +496,7 @@ class ExplorationActivityTest {
@Test
fun testBackButtonSpotlight_setToShowOnFirstLogin_notSeen_checkSpotlightIsShown() {
+ setUpAudioForFractionLesson()
launch(
createExplorationActivityIntent(
internalProfileId,
@@ -511,6 +512,7 @@ class ExplorationActivityTest {
FRACTIONS_STORY_ID_0,
FRACTIONS_EXPLORATION_ID_0
)
+ testCoroutineDispatchers.runCurrent()
onView(withText(R.string.exploration_exit_button_spotlight_hint))
.check(matches(isDisplayed()))
@@ -520,6 +522,7 @@ class ExplorationActivityTest {
@Test
fun testBackButtonSpotlight_setToShowOnFirstLogin_alreadySeen_checkSpotlightIsNotShown() {
markSpotlightSeen(Spotlight.FeatureCase.VOICEOVER_PLAY_ICON)
+ setUpAudioForFractionLesson()
launch(
createExplorationActivityIntent(
internalProfileId,
@@ -535,6 +538,7 @@ class ExplorationActivityTest {
FRACTIONS_STORY_ID_0,
FRACTIONS_EXPLORATION_ID_0
)
+ testCoroutineDispatchers.runCurrent()
onView(withId(R.id.close_target)).perform(click())
}
@@ -553,6 +557,8 @@ class ExplorationActivityTest {
FRACTIONS_STORY_ID_0,
FRACTIONS_EXPLORATION_ID_0
)
+ testCoroutineDispatchers.runCurrent()
+
onView(withText(R.string.exploration_exit_button_spotlight_hint))
.check(doesNotExist())
}
@@ -580,7 +586,7 @@ class ExplorationActivityTest {
)
testCoroutineDispatchers.runCurrent()
- onView(withText(R.string.voiceover_icon_spotlight_hint))
+ onView(withText("Would you like Oppia to read for you? Tap on this button to try!"))
.check(matches(isDisplayed()))
}
}
@@ -626,7 +632,7 @@ class ExplorationActivityTest {
)
testCoroutineDispatchers.runCurrent()
- onView(withText(R.string.voiceover_icon_spotlight_hint))
+ onView(withText("Would you like Oppia to read for you? Tap on this button to try!"))
.check(doesNotExist())
}
}
@@ -634,6 +640,7 @@ class ExplorationActivityTest {
@Test
fun testVoiceoverIconSpotlight_setToShowAfter3rdLogin_1stLogin_checkNotShown() {
markSpotlightSeen(Spotlight.FeatureCase.LESSONS_BACK_BUTTON)
+ setUpAudioForFractionLesson()
launch(
createExplorationActivityIntent(
internalProfileId,
@@ -651,7 +658,7 @@ class ExplorationActivityTest {
)
testCoroutineDispatchers.runCurrent()
- onView(withText(R.string.voiceover_icon_spotlight_hint))
+ onView(withText("Would you like Oppia to read for you? Tap on this button to try!"))
.check(doesNotExist())
}
}
@@ -843,6 +850,7 @@ class ExplorationActivityTest {
@Test
fun testAudioCellular_ratioExp_audioIcon_clickNegative_audioFragmentIsHidden() {
+ markAllSpotlightsSeen()
setUpAudio()
launch(
createExplorationActivityIntent(
@@ -1849,6 +1857,7 @@ class ExplorationActivityTest {
@Test
@RunOn(TestPlatform.ROBOLECTRIC) // TODO(#3858): Enable for Espresso.
fun testExpActivity_englishContentLang_showHint_explanationInEnglish() {
+ markAllSpotlightsSeen()
updateContentLanguage(
ProfileId.newBuilder().apply { internalId = internalProfileId }.build(),
OppiaLanguage.ENGLISH
@@ -1888,6 +1897,7 @@ class ExplorationActivityTest {
@Test
@RunOn(TestPlatform.ROBOLECTRIC) // TODO(#3858): Enable for Espresso.
fun testExpActivity_showHint_hasCorrectContentDescription() {
+ markAllSpotlightsSeen()
launch(
createExplorationActivityIntent(
internalProfileId,
@@ -1930,6 +1940,7 @@ class ExplorationActivityTest {
@Test
@RunOn(TestPlatform.ROBOLECTRIC) // TODO(#3858): Enable for Espresso.
fun testExpActivity_showHint_checkExpandListIconWithScreenReader_isClickable() {
+ markAllSpotlightsSeen()
launch(
createExplorationActivityIntent(
internalProfileId,
@@ -1965,6 +1976,7 @@ class ExplorationActivityTest {
@Test
@RunOn(TestPlatform.ROBOLECTRIC) // TODO(#3858): Enable for Espresso.
fun testExpActivity_showHint_checkExpandListIconWithoutScreenReader_isNotClickable() {
+ markAllSpotlightsSeen()
launch(
createExplorationActivityIntent(
internalProfileId,
@@ -2001,6 +2013,7 @@ class ExplorationActivityTest {
@Test
@RunOn(TestPlatform.ROBOLECTRIC, buildEnvironments = [BuildEnvironment.BAZEL])
fun testExpActivity_profileWithArabicContentLang_showHint_explanationInArabic() {
+ markAllSpotlightsSeen()
updateContentLanguage(
ProfileId.newBuilder().apply { internalId = internalProfileId }.build(),
OppiaLanguage.ARABIC
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
index 8fc1cd81093..4c2126e5515 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
@@ -46,6 +46,8 @@ import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.model.Spotlight.FeatureCase.FIRST_CHAPTER
+import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_LESSON_TAB
import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_REVISION_TAB
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPositionOnView
@@ -823,7 +825,7 @@ class TopicFragmentTest {
val profileId = ProfileId.newBuilder()
.setInternalId(internalProfileId)
.build()
- spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.TOPIC_LESSON_TAB)
+ spotlightStateController.markSpotlightViewed(profileId, TOPIC_LESSON_TAB)
testCoroutineDispatchers.runCurrent()
}
@@ -831,7 +833,7 @@ class TopicFragmentTest {
val profileId = ProfileId.newBuilder()
.setInternalId(internalProfileId)
.build()
- spotlightStateController.markSpotlightViewed(profileId, Spotlight.FeatureCase.FIRST_CHAPTER)
+ spotlightStateController.markSpotlightViewed(profileId, FIRST_CHAPTER)
testCoroutineDispatchers.runCurrent()
}
diff --git a/instrumentation/src/java/AndroidManifest.xml b/instrumentation/src/java/AndroidManifest.xml
index f93f46d8556..f28a8c6c04a 100644
--- a/instrumentation/src/java/AndroidManifest.xml
+++ b/instrumentation/src/java/AndroidManifest.xml
@@ -188,7 +188,7 @@
+ android:theme="@style/RevisionCardActivityTheme" />
Date: Sun, 20 Nov 2022 00:17:55 +0530
Subject: [PATCH 101/138] lint
---
.../org/oppia/android/app/spotlight/SpotlightFragment.kt | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index a4d44671998..3c0782ec7fd 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -89,16 +89,16 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
internalProfileId = arguments?.getInt(PROFILE_ID_ARGUMENT_KEY) ?: -1
calculateScreenSize()
- checkIsRTL()
}
/**
* Requests a spotlight to be shown on the [SpotlightTarget]. The spotlight is enqueued if it
* [SpotlightTarget] hasn't been shown before in a FIFO buffer. This API can ensure proper
* spotlighting of a which is laid out after an animation. For the spotlights to work correctly,
- * we must know the [SpotlightTarget]'s anchor's size and position. For a view that is laid out after an animation, we must
- * wait until the final size and positions of the anchor view are measured, which can be achieved by using
- * doOnPreDraw (refer: https://betterprogramming.pub/stop-using-post-postdelayed-in-your-android-views-9d1c8eeaadf2).
+ * we must know the [SpotlightTarget]'s anchor's size and position. For a view that is laid out
+ * after an animation, we must wait until the final size and positions of the anchor view are
+ * measured, which can be achieved by using doOnPreDraw. Refer:
+ * https://betterprogramming.pub/stop-using-post-postdelayed-in-your-android-views-9d1c8eeaadf2
*
* @param spotlightTarget The [SpotlightTarget] for which the spotlight is requested
*/
From e54728bf813658c6aae2c18bf1a54d160b67abf3 Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Sun, 20 Nov 2022 03:06:54 -0800
Subject: [PATCH 102/138] add hint background design
---
.../app/spotlight/SpotlightFragment.kt | 51 ++++---------------
.../spotlight_overlay_hint_background.xml | 5 ++
.../main/res/layout/bottom_left_overlay.xml | 33 +++++++-----
.../main/res/layout/bottom_right_overlay.xml | 32 +++++++-----
app/src/main/res/layout/top_left_overlay.xml | 18 ++++---
app/src/main/res/layout/top_right_overlay.xml | 29 ++++++-----
6 files changed, 78 insertions(+), 90 deletions(-)
create mode 100644 app/src/main/res/drawable/spotlight_overlay_hint_background.xml
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 818f41eb93c..8d08eda7c77 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -1,9 +1,6 @@
package org.oppia.android.app.spotlight
import android.content.Context
-import android.text.Spannable
-import android.text.SpannableString
-import android.text.style.BackgroundColorSpan
import android.util.DisplayMetrics
import android.util.Log
import android.view.View
@@ -12,7 +9,6 @@ import android.view.animation.DecelerateInterpolator
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.doOnPreDraw
-import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import com.takusemba.spotlight.OnSpotlightListener
import com.takusemba.spotlight.OnTargetListener
@@ -63,8 +59,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
private var screenWidth: Int = 0
private lateinit var overlayBinding: Any
private var internalProfileId: Int = -1
- private val isSpotlightActive = MutableLiveData(false)
-
+ private val isSpotlightActive = false
private val isRtl by lazy {
resourceHandler.getLayoutDirection() == ViewCompat.LAYOUT_DIRECTION_RTL
}
@@ -77,11 +72,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
screenWidth = displayMetrics.widthPixels
}
- /** LiveData to monitor spotlight activity status. */
- fun getSpotlightStatusLiveData(): MutableLiveData {
- return isSpotlightActive
- }
-
// since this fragment does not have any view to inflate yet, all the tasks should be done here.
override fun onAttach(context: Context) {
super.onAttach(context)
@@ -183,9 +173,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
.build(spotlightTarget.anchor)
targetList.add(target)
- if (!isSpotlightActive.value!!) {
- startSpotlight()
- }
+ if (!isSpotlightActive) startSpotlight()
}
private fun startSpotlight() {
@@ -197,11 +185,11 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
.setAnimation(DecelerateInterpolator(2f))
.setOnSpotlightListener(object : OnSpotlightListener {
override fun onStarted() {
- isSpotlightActive.value = true
+ isSpotlightActive = true
}
override fun onEnded() {
- isSpotlightActive.value = false
+ isSpotlightActive = false
startSpotlight()
}
})
@@ -318,16 +306,14 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
private fun configureBottomLeftOverlay(spotlightTarget: SpotlightTarget): View {
- Log.d("overlay", "bottom left overlay")
-
overlayBinding = BottomLeftOverlayBinding.inflate(this.layoutInflater)
(overlayBinding as BottomLeftOverlayBinding).let {
it.lifecycleOwner = this
it.listener = this
}
- (overlayBinding as BottomLeftOverlayBinding).customText.text =
- getSpannableHint(spotlightTarget.hint)
+ (overlayBinding as BottomLeftOverlayBinding).customText.text = spotlightTarget.hint
+
val arrowParams = (overlayBinding as BottomLeftOverlayBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
@@ -352,15 +338,13 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
private fun configureBottomRightOverlay(spotlightTarget: SpotlightTarget): View {
- Log.d("overlay", "bottom right overlay")
overlayBinding = BottomRightOverlayBinding.inflate(this.layoutInflater)
(overlayBinding as BottomRightOverlayBinding).let {
it.lifecycleOwner = this
it.listener = this
}
- (overlayBinding as BottomRightOverlayBinding).customText.text =
- getSpannableHint(spotlightTarget.hint)
+ (overlayBinding as BottomRightOverlayBinding).customText.text = spotlightTarget.hint
val arrowParams = (overlayBinding as BottomRightOverlayBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
@@ -385,28 +369,14 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
return (overlayBinding as BottomRightOverlayBinding).root
}
- private fun getSpannableHint(hint: String): SpannableString {
- val spannable = SpannableString(hint)
- spannable.setSpan(
- BackgroundColorSpan(resources.getColor(R.color.spotlight_hint_background)),
- 0, // start
- spannable.length, // end
- Spannable.SPAN_INCLUSIVE_INCLUSIVE
- )
- return spannable
- }
-
private fun configureTopRightOverlay(spotlightTarget: SpotlightTarget): View {
- Log.d("overlay", "top right overlay")
-
overlayBinding = TopRightOverlayBinding.inflate(layoutInflater)
(overlayBinding as TopRightOverlayBinding).let {
it.lifecycleOwner = this
it.listener = this
}
- (overlayBinding as TopRightOverlayBinding).customText.text =
- getSpannableHint(spotlightTarget.hint)
+ (overlayBinding as TopRightOverlayBinding).customText.text = spotlightTarget.hint
val arrowParams = (overlayBinding as TopRightOverlayBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
@@ -431,16 +401,13 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
private fun configureTopLeftOverlay(spotlightTarget: SpotlightTarget): View {
- Log.d("overlay", "top left overlay")
-
overlayBinding = TopLeftOverlayBinding.inflate(this.layoutInflater)
(overlayBinding as TopLeftOverlayBinding).let {
it.lifecycleOwner = this
it.listener = this
}
- (overlayBinding as TopLeftOverlayBinding).customText.text =
- getSpannableHint(spotlightTarget.hint)
+ (overlayBinding as TopLeftOverlayBinding).customText.text = spotlightTarget.hint
val arrowParams = (overlayBinding as TopLeftOverlayBinding).arrow.layoutParams
as ViewGroup.MarginLayoutParams
diff --git a/app/src/main/res/drawable/spotlight_overlay_hint_background.xml b/app/src/main/res/drawable/spotlight_overlay_hint_background.xml
new file mode 100644
index 00000000000..d1b02e8bc17
--- /dev/null
+++ b/app/src/main/res/drawable/spotlight_overlay_hint_background.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index e85bfd1f4e5..680d9ebec8a 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -15,28 +15,33 @@
android:id="@+id/overlayConstraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:focusable="true"
+ android:background="@drawable/transparent_background"
android:clickable="true"
- android:background="@drawable/transparent_background">
+ android:focusable="true">
+ app:layout_constraintTop_toTopOf="parent"
+ app:srcCompat="@drawable/ic_rounded_arrow_up_right" />
@@ -46,18 +51,18 @@
style="@style/StateButtonActive"
android:layout_width="160dp"
android:layout_height="48dp"
- android:paddingTop="8dp"
- android:paddingBottom="8dp"
- android:textSize="14dp"
- android:gravity="center"
- android:focusable="true"
- android:clickable="true"
- android:background="@color/color_def_dark_blue"
android:layout_marginTop="50dp"
android:layout_marginEnd="10dp"
+ android:background="@color/color_def_dark_blue"
+ android:clickable="true"
+ android:focusable="true"
+ android:gravity="center"
android:onClick="@{(v) -> listener.clickOnNextTip()}"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
android:text="Done"
android:textColor="#FFFFFF"
+ android:textSize="14dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -68,10 +73,10 @@
android:layout_marginStart="10dp"
android:layout_marginTop="50dp"
android:text="dismiss"
- android:visibility="invisible"
android:textColor="#FFFFFF"
android:textSize="20sp"
android:textStyle="bold"
+ android:visibility="invisible"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index a8e3331c824..ed08ab12419 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -25,40 +25,44 @@
android:layout_height="@dimen/arrow_height"
android:rotationX="180"
android:rotationY="180"
- app:srcCompat="@drawable/ic_rounded_arrow_up_right"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
+ app:layout_constraintTop_toTopOf="parent"
+ app:srcCompat="@drawable/ic_rounded_arrow_up_right" />
+ app:layout_constraintEnd_toEndOf="@+id/arrow"
+ app:layout_constraintStart_toStartOf="parent" />
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index b717c0d0d8c..5ffdab4d319 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -23,20 +23,24 @@
android:id="@+id/arrow"
android:layout_width="@dimen/arrow_width"
android:layout_height="@dimen/arrow_height"
- app:srcCompat="@drawable/ic_rounded_arrow_up_right"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
+ app:layout_constraintTop_toTopOf="parent"
+ app:srcCompat="@drawable/ic_rounded_arrow_up_right" />
@@ -44,8 +48,6 @@
+ app:layout_constraintTop_toTopOf="parent"
+ app:srcCompat="@drawable/ic_rounded_arrow_up_right" />
@@ -46,19 +49,19 @@
android:id="@+id/close_target"
style="@style/StateButtonActive"
android:layout_width="160dp"
- android:paddingTop="50dp"
- android:paddingBottom="8dp"
android:layout_height="48dp"
- android:textSize="14dp"
- android:gravity="center"
- android:layout_marginBottom="50dp"
android:layout_marginEnd="10dp"
+ android:layout_marginBottom="50dp"
android:background="@color/color_def_dark_blue"
+ android:gravity="center"
android:onClick="@{(v) -> listener.clickOnNextTip()}"
+ android:paddingTop="50dp"
+ android:paddingBottom="8dp"
android:text="Done"
android:textColor="#FFFFFF"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"/>
+ android:textSize="14dp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
Date: Sun, 20 Nov 2022 03:19:50 -0800
Subject: [PATCH 103/138] merge with develop
---
.../app/spotlight/SpotlightFragment.kt | 23 ++++++++-----------
.../spotlight/SpotlightNavigationListener.kt | 2 --
.../spotlight_overlay_hint_background.xml | 11 ++++++---
.../main/res/layout/bottom_left_overlay.xml | 14 -----------
.../main/res/layout/bottom_right_overlay.xml | 14 -----------
app/src/main/res/layout/top_left_overlay.xml | 14 -----------
app/src/main/res/layout/top_right_overlay.xml | 14 -----------
7 files changed, 18 insertions(+), 74 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 8d08eda7c77..0f0cb4cc88c 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -59,7 +59,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
private var screenWidth: Int = 0
private lateinit var overlayBinding: Any
private var internalProfileId: Int = -1
- private val isSpotlightActive = false
+ private var isSpotlightActive = false
private val isRtl by lazy {
resourceHandler.getLayoutDirection() == ViewCompat.LAYOUT_DIRECTION_RTL
}
@@ -85,9 +85,10 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
* Requests a spotlight to be shown on the [SpotlightTarget]. The spotlight is enqueued if it
* [SpotlightTarget] hasn't been shown before in a FIFO buffer. This API can ensure proper
* spotlighting of a which is laid out after an animation. For the spotlights to work correctly,
- * we must know the [SpotlightTarget]'s anchor's size and position. For a view that is laid out after an animation, we must
- * wait until the final size and positions of the anchor view are measured, which can be achieved by using
- * doOnPreDraw (refer: https://betterprogramming.pub/stop-using-post-postdelayed-in-your-android-views-9d1c8eeaadf2).
+ * we must know the [SpotlightTarget]'s anchor's size and position. For a view that is laid out
+ * after an animation, we must wait until the final size and positions of the anchor view are
+ * measured, which can be achieved by using doOnPreDraw. Refer:
+ * (https://betterprogramming.pub/stop-using-post-postdelayed-in-your-android-views-9d1c8eeaadf2)
*
* @param spotlightTarget The [SpotlightTarget] for which the spotlight is requested
*/
@@ -110,11 +111,11 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
/**
* Requests a spotlight to be shown on the [SpotlightTarget]. The spotlight is enqueued if it
- * hasn't been shown before in a FIFO buffer. This API can ensure proper spotlighting of a [SpotlightTarget]
- * when it is laid out late due to a data provider call. It cannot ensure the same if the view has to be
- * spotlight immediately after an animation. It also cannot spotlight targets which are a part of a
- * recycler view which are laid out after a data provider call. If TalkBack is turned on, no spotlight shall
- * be shown.
+ * hasn't been shown before in a FIFO buffer. This API can ensure proper spotlighting of a
+ * [SpotlightTarget] when it is laid out late due to a data provider call. It cannot ensure the
+ * same if the view has to be spotlight immediately after an animation. It also cannot spotlight
+ * targets which are a part of a recycler view which are laid out after a data provider call. If
+ * TalkBack is turned on, no spotlight shall be shown.
*
* @param spotlightTarget The [SpotlightTarget] for which the spotlight is requested
*/
@@ -297,10 +298,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
object BottomRight : AnchorPosition()
}
- override fun clickOnDismiss() {
- spotlight.finish()
- }
-
override fun clickOnNextTip() {
spotlight.next()
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightNavigationListener.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightNavigationListener.kt
index a68907ef488..17188d2f026 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightNavigationListener.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightNavigationListener.kt
@@ -4,6 +4,4 @@ package org.oppia.android.app.spotlight
interface SpotlightNavigationListener {
/** Called when the done button is clicked. */
fun clickOnNextTip()
- /** Called when the dismiss button is clicked. */
- fun clickOnDismiss()
}
diff --git a/app/src/main/res/drawable/spotlight_overlay_hint_background.xml b/app/src/main/res/drawable/spotlight_overlay_hint_background.xml
index d1b02e8bc17..4f220d50e7f 100644
--- a/app/src/main/res/drawable/spotlight_overlay_hint_background.xml
+++ b/app/src/main/res/drawable/spotlight_overlay_hint_background.xml
@@ -1,5 +1,10 @@
-
-
-
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 680d9ebec8a..74fa9d2d466 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -65,19 +65,5 @@
android:textSize="14dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index ed08ab12419..dbd5d15ebf3 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -65,19 +65,5 @@
android:textSize="14dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index 5ffdab4d319..ffe62be409e 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -64,19 +64,5 @@
android:textSize="14dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/top_right_overlay.xml b/app/src/main/res/layout/top_right_overlay.xml
index 10d89bb754d..0be418649dc 100644
--- a/app/src/main/res/layout/top_right_overlay.xml
+++ b/app/src/main/res/layout/top_right_overlay.xml
@@ -62,19 +62,5 @@
android:textSize="14dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
-
-
\ No newline at end of file
From 53d41a0bbf3a0d15a8264b3feb503d3f4ebca419 Mon Sep 17 00:00:00 2001
From: madhurgera2 <76070586+madhurgera2@users.noreply.github.com>
Date: Sun, 20 Nov 2022 09:45:52 +0530
Subject: [PATCH 104/138] fix build failure
---
.../app/player/audio/AudioFragmentPresenter.kt | 15 ++-------------
1 file changed, 2 insertions(+), 13 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index 5415b655f04..fe3cab9316d 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -119,16 +119,6 @@ class AudioFragmentPresenter @Inject constructor(
return binding.root
}
- private fun subscribeToSpotlightStatusLiveData() {
- getSpotlightFragment().getSpotlightStatusLiveData().observe(fragment) { isSpotlightActive ->
- if (isSpotlightActive) {
- handleOnStop()
- } else {
- handleOnPlay()
- }
- }
- }
-
private fun startSpotlights() {
val audioLanguageIconSpotlightTarget = SpotlightTarget(
binding.audioLanguageIcon,
@@ -297,13 +287,12 @@ class AudioFragmentPresenter @Inject constructor(
audioButtonListener.scrollToTop()
if (feedbackId == null) {
// This isn't reloading content since it's the first case of the content auto-playing.
- loadMainContentAudio(allowAutoPlay = true, reloadingContent = false)
+ loadMainContentAudio(allowAutoPlay = false, reloadingContent = false)
} else {
- loadFeedbackAudio(feedbackId!!, true)
+ loadFeedbackAudio(feedbackId!!, false)
}
fragment.view?.startAnimation(AnimationUtils.loadAnimation(context, R.anim.slide_down_audio))
startSpotlights()
- subscribeToSpotlightStatusLiveData()
}
private fun hideAudioFragment() {
From 1eb51e6c5741120c46780dfabcae36047a4c22af Mon Sep 17 00:00:00 2001
From: madhurgera2 <76070586+madhurgera2@users.noreply.github.com>
Date: Sun, 20 Nov 2022 09:49:52 +0530
Subject: [PATCH 105/138] fix build failure
---
.../org/oppia/android/app/player/state/StateFragmentPresenter.kt | 1 -
1 file changed, 1 deletion(-)
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 22ff5fb6e63..ae4b66d48c6 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
@@ -36,7 +36,6 @@ import org.oppia.android.app.player.state.listener.RouteToHintsAndSolutionListen
import org.oppia.android.app.player.stopplaying.StopStatePlayingSessionWithSavedProgressListener
import org.oppia.android.app.topic.conceptcard.ConceptCardFragment.Companion.CONCEPT_CARD_DIALOG_FRAGMENT_TAG
import org.oppia.android.app.translation.AppLanguageResourceHandler
-import org.oppia.android.app.utility.LifecycleSafeTimerFactory
import org.oppia.android.app.utility.SplitScreenManager
import org.oppia.android.app.utility.lifecycle.LifecycleSafeTimerFactory
import org.oppia.android.app.viewmodel.ViewModelProvider
From 912c357300f408f73a2aa4d6e94727c6605d9cdb Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Sun, 20 Nov 2022 14:24:39 +0530
Subject: [PATCH 106/138] Revert "Fix #4746: Update app to target SDK 31
(#4747)"
This reverts commit 7cb38ffa
---
.../action.yml | 4 ++--
BUILD.bazel | 4 ++--
WORKSPACE | 2 +-
app/build.gradle | 4 ++--
app/src/main/AppAndroidManifest.xml | 2 +-
app/src/main/DatabindingAdaptersManifest.xml | 2 +-
app/src/main/DatabindingResourcesManifest.xml | 2 +-
app/src/main/RecyclerviewAdaptersManifest.xml | 2 +-
app/src/main/ViewModelManifest.xml | 2 +-
app/src/main/ViewModelsManifest.xml | 2 +-
app/src/main/ViewsManifest.xml | 2 +-
build_flavors.bzl | 14 +++++++-------
.../org/oppia/android/config/AndroidManifest.xml | 2 +-
data/build.gradle | 4 ++--
data/src/test/AndroidManifest.xml | 2 +-
domain/build.gradle | 4 ++--
domain/src/main/AndroidManifest.xml | 2 +-
instrumentation/BUILD.bazel | 2 +-
testing/build.gradle | 4 ++--
testing/src/test/AndroidManifest.xml | 2 +-
utility/build.gradle | 4 ++--
utility/src/main/AndroidManifest.xml | 2 +-
22 files changed, 35 insertions(+), 35 deletions(-)
diff --git a/.github/actions/set-up-android-bazel-build-environment/action.yml b/.github/actions/set-up-android-bazel-build-environment/action.yml
index 6b3f5cf1155..836e327828b 100644
--- a/.github/actions/set-up-android-bazel-build-environment/action.yml
+++ b/.github/actions/set-up-android-bazel-build-environment/action.yml
@@ -72,9 +72,9 @@ runs:
$ANDROID_HOME/cmdline-tools/tools/bin/sdkmanager --install "platform-tools"
shell: bash
- - name: Install SDK 31
+ - name: Install SDK 30
run: |
- $ANDROID_HOME/cmdline-tools/tools/bin/sdkmanager --install "platforms;android-31"
+ $ANDROID_HOME/cmdline-tools/tools/bin/sdkmanager --install "platforms;android-30"
shell: bash
- name: Install build tools 29.0.2
diff --git a/BUILD.bazel b/BUILD.bazel
index 5177d895f27..81250077b03 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -117,14 +117,14 @@ package_group(
"flavor": "oppia",
"min_sdk_version": 21,
"multidex": "native",
- "target_sdk_version": 31,
+ "target_sdk_version": 30,
},
{
"flavor": "oppia_kitkat",
"main_dex_list": "//:config/kitkat_main_dex_class_list.txt",
"min_sdk_version": 19,
"multidex": "manual_main_dex",
- "target_sdk_version": 31,
+ "target_sdk_version": 30,
},
]
]
diff --git a/WORKSPACE b/WORKSPACE
index c6c1f09af5f..17ac191b294 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -11,7 +11,7 @@ load("//third_party:versions.bzl", "HTTP_DEPENDENCY_VERSIONS", "get_maven_depend
# TODO(#1542): Sync Android SDK version with the manifest.
android_sdk_repository(
name = "androidsdk",
- api_level = 31,
+ api_level = 30,
build_tools_version = "29.0.2",
)
diff --git a/app/build.gradle b/app/build.gradle
index 63ee7549c26..7210225d4e2 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -6,12 +6,12 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
- compileSdkVersion 31
+ compileSdkVersion 30
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "org.oppia.android"
minSdkVersion 19
- targetSdkVersion 31
+ targetSdkVersion 30
versionCode 1
versionName "1.0"
multiDexEnabled true
diff --git a/app/src/main/AppAndroidManifest.xml b/app/src/main/AppAndroidManifest.xml
index 9a5789e1872..1c8f666190e 100644
--- a/app/src/main/AppAndroidManifest.xml
+++ b/app/src/main/AppAndroidManifest.xml
@@ -1,5 +1,5 @@
+ android:targetSdkVersion="30" />
diff --git a/app/src/main/DatabindingAdaptersManifest.xml b/app/src/main/DatabindingAdaptersManifest.xml
index 0974b6b3aa6..1ce9e10c160 100644
--- a/app/src/main/DatabindingAdaptersManifest.xml
+++ b/app/src/main/DatabindingAdaptersManifest.xml
@@ -1,5 +1,5 @@
+ android:targetSdkVersion="30" />
diff --git a/app/src/main/DatabindingResourcesManifest.xml b/app/src/main/DatabindingResourcesManifest.xml
index 0c3dd8fa35a..9b1e93c2052 100644
--- a/app/src/main/DatabindingResourcesManifest.xml
+++ b/app/src/main/DatabindingResourcesManifest.xml
@@ -1,5 +1,5 @@
+ android:targetSdkVersion="30" />
diff --git a/app/src/main/RecyclerviewAdaptersManifest.xml b/app/src/main/RecyclerviewAdaptersManifest.xml
index f2a3273e765..f20e30062f0 100644
--- a/app/src/main/RecyclerviewAdaptersManifest.xml
+++ b/app/src/main/RecyclerviewAdaptersManifest.xml
@@ -1,5 +1,5 @@
+ android:targetSdkVersion="30" />
diff --git a/app/src/main/ViewModelManifest.xml b/app/src/main/ViewModelManifest.xml
index 07603e895d8..fa31c60ce75 100644
--- a/app/src/main/ViewModelManifest.xml
+++ b/app/src/main/ViewModelManifest.xml
@@ -3,5 +3,5 @@
+ android:targetSdkVersion="30" />
diff --git a/app/src/main/ViewModelsManifest.xml b/app/src/main/ViewModelsManifest.xml
index 84693784fd8..c44690d380c 100644
--- a/app/src/main/ViewModelsManifest.xml
+++ b/app/src/main/ViewModelsManifest.xml
@@ -3,5 +3,5 @@
+ android:targetSdkVersion="30" />
diff --git a/app/src/main/ViewsManifest.xml b/app/src/main/ViewsManifest.xml
index 340e35afe29..10b8d0ef41f 100644
--- a/app/src/main/ViewsManifest.xml
+++ b/app/src/main/ViewsManifest.xml
@@ -3,5 +3,5 @@
+ android:targetSdkVersion="30" />
diff --git a/build_flavors.bzl b/build_flavors.bzl
index e141ba1e702..55aec211b65 100644
--- a/build_flavors.bzl
+++ b/build_flavors.bzl
@@ -46,7 +46,7 @@ _FLAVOR_METADATA = {
"dev": {
"manifest": "//app:src/main/AndroidManifest.xml",
"min_sdk_version": 21,
- "target_sdk_version": 31,
+ "target_sdk_version": 30,
"multidex": "native",
"proguard_specs": [], # Developer builds are not optimized.
"production_release": False,
@@ -60,7 +60,7 @@ _FLAVOR_METADATA = {
"dev_kitkat": {
"manifest": "//app:src/main/AndroidManifest.xml",
"min_sdk_version": 19,
- "target_sdk_version": 31,
+ "target_sdk_version": 30,
"multidex": "manual_main_dex",
"main_dex_list": _MAIN_DEX_LIST_TARGET_KITKAT,
"proguard_specs": [], # Developer builds are not optimized.
@@ -75,7 +75,7 @@ _FLAVOR_METADATA = {
"alpha": {
"manifest": "//app:src/main/AndroidManifest.xml",
"min_sdk_version": 21,
- "target_sdk_version": 31,
+ "target_sdk_version": 30,
"multidex": "native",
"proguard_specs": _PRODUCTION_PROGUARD_SPECS,
"production_release": True,
@@ -89,7 +89,7 @@ _FLAVOR_METADATA = {
"alpha_kitkat": {
"manifest": "//app:src/main/AndroidManifest.xml",
"min_sdk_version": 19,
- "target_sdk_version": 31,
+ "target_sdk_version": 30,
"multidex": "manual_main_dex",
"main_dex_list": _MAIN_DEX_LIST_TARGET_KITKAT,
"proguard_specs": [], # TODO(#3886): Re-add Proguard support to alpha_kitkat.
@@ -104,7 +104,7 @@ _FLAVOR_METADATA = {
"alpha_kenya": {
"manifest": "//app:src/main/AndroidManifest.xml",
"min_sdk_version": 21,
- "target_sdk_version": 31,
+ "target_sdk_version": 30,
"multidex": "native",
"proguard_specs": _PRODUCTION_PROGUARD_SPECS,
"production_release": True,
@@ -118,7 +118,7 @@ _FLAVOR_METADATA = {
"beta": {
"manifest": "//app:src/main/AndroidManifest.xml",
"min_sdk_version": 21,
- "target_sdk_version": 31,
+ "target_sdk_version": 30,
"multidex": "native",
"proguard_specs": _PRODUCTION_PROGUARD_SPECS,
"production_release": True,
@@ -132,7 +132,7 @@ _FLAVOR_METADATA = {
"ga": {
"manifest": "//app:src/main/AndroidManifest.xml",
"min_sdk_version": 21,
- "target_sdk_version": 31,
+ "target_sdk_version": 30,
"multidex": "native",
"proguard_specs": _PRODUCTION_PROGUARD_SPECS,
"production_release": True,
diff --git a/config/src/java/org/oppia/android/config/AndroidManifest.xml b/config/src/java/org/oppia/android/config/AndroidManifest.xml
index 1d3f57544f1..e1c019cb70c 100644
--- a/config/src/java/org/oppia/android/config/AndroidManifest.xml
+++ b/config/src/java/org/oppia/android/config/AndroidManifest.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/data/build.gradle b/data/build.gradle
index d51015b8c24..b90bcc469fc 100644
--- a/data/build.gradle
+++ b/data/build.gradle
@@ -4,12 +4,12 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
- compileSdkVersion 31
+ compileSdkVersion 30
buildToolsVersion "29.0.2"
defaultConfig {
minSdkVersion 19
- targetSdkVersion 31
+ targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
diff --git a/data/src/test/AndroidManifest.xml b/data/src/test/AndroidManifest.xml
index 2078d324983..5fd4f17f291 100644
--- a/data/src/test/AndroidManifest.xml
+++ b/data/src/test/AndroidManifest.xml
@@ -1,5 +1,5 @@
+ android:maxSdkVersion="30" />
diff --git a/domain/build.gradle b/domain/build.gradle
index b0e246d6e27..861ea4ae207 100644
--- a/domain/build.gradle
+++ b/domain/build.gradle
@@ -4,12 +4,12 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
- compileSdkVersion 31
+ compileSdkVersion 30
buildToolsVersion "29.0.2"
defaultConfig {
minSdkVersion 19
- targetSdkVersion 31
+ targetSdkVersion 30
versionCode 1
versionName "1.0"
javaCompileOptions {
diff --git a/domain/src/main/AndroidManifest.xml b/domain/src/main/AndroidManifest.xml
index 483a96cc057..9cdbbca1e9e 100644
--- a/domain/src/main/AndroidManifest.xml
+++ b/domain/src/main/AndroidManifest.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/instrumentation/BUILD.bazel b/instrumentation/BUILD.bazel
index 22a68271e54..528eec6a433 100644
--- a/instrumentation/BUILD.bazel
+++ b/instrumentation/BUILD.bazel
@@ -18,7 +18,7 @@ android_binary(
manifest_values = {
"applicationId": "org.oppia.android",
"minSdkVersion": "19",
- "targetSdkVersion": "31",
+ "targetSdkVersion": "30",
"versionCode": "0",
"versionName": "0.1-test",
},
diff --git a/testing/build.gradle b/testing/build.gradle
index 9e502acee95..25123a4dd84 100644
--- a/testing/build.gradle
+++ b/testing/build.gradle
@@ -4,12 +4,12 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
- compileSdkVersion 31
+ compileSdkVersion 30
buildToolsVersion "29.0.2"
defaultConfig {
minSdkVersion 19
- targetSdkVersion 31
+ targetSdkVersion 30
versionCode 1
versionName "1.0"
}
diff --git a/testing/src/test/AndroidManifest.xml b/testing/src/test/AndroidManifest.xml
index 4682f548b88..be2a6519fab 100644
--- a/testing/src/test/AndroidManifest.xml
+++ b/testing/src/test/AndroidManifest.xml
@@ -1,5 +1,5 @@
+ android:maxSdkVersion="30" />
diff --git a/utility/build.gradle b/utility/build.gradle
index 4ffcde26c70..353ea924239 100644
--- a/utility/build.gradle
+++ b/utility/build.gradle
@@ -4,12 +4,12 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
- compileSdkVersion 31
+ compileSdkVersion 30
buildToolsVersion "29.0.2"
defaultConfig {
minSdkVersion 19
- targetSdkVersion 31
+ targetSdkVersion 30
versionCode 1
versionName "1.0"
javaCompileOptions {
diff --git a/utility/src/main/AndroidManifest.xml b/utility/src/main/AndroidManifest.xml
index 5a8bce58b67..f16271049d7 100644
--- a/utility/src/main/AndroidManifest.xml
+++ b/utility/src/main/AndroidManifest.xml
@@ -1,4 +1,4 @@
-
+
From 72a3c84754193dbb79d8cbde7c4f33e3ab984ea9 Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Sun, 20 Nov 2022 17:47:38 +0530
Subject: [PATCH 107/138] suggestive comments
---
app/src/main/AndroidManifest.xml | 2 +-
.../app/activity/ActivityComponentImpl.kt | 2 +-
.../app/fragment/FragmentComponentImpl.kt | 2 +-
.../RequestVoiceOverIconSpotlightListener.kt | 4 ++--
.../app/spotlight/SpotlightFragment.kt | 5 ++--
.../android/app/spotlight/SpotlightManager.kt | 23 ++++++++++---------
.../spotlight/SpotlightNavigationListener.kt | 2 +-
.../android/app/spotlight/SpotlightShape.kt | 4 ++--
.../testing/SpotlightFragmentTestActivity.kt | 2 +-
.../android/app/view/ViewComponentImpl.kt | 4 ++--
.../drawable/ic_rounded_arrow_up_right.xml | 13 +++++++----
.../exploration/ExplorationActivityTest.kt | 4 ++--
12 files changed, 36 insertions(+), 31 deletions(-)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index cad3ad03568..d4bd3fc53bb 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -39,7 +39,7 @@
+ android:theme="@style/OppiaThemeWithoutActionBar" />
-
+
+
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
index 7f496056030..c149f6d76a0 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
@@ -587,7 +587,7 @@ class ExplorationActivityTest {
)
testCoroutineDispatchers.runCurrent()
- onView(withText("Would you like Oppia to read for you? Tap on this button to try!"))
+ onView(withText(context.getString(R.string.voiceover_icon_spotlight_hint, R.string.app_name)))
.check(matches(isDisplayed()))
}
}
@@ -633,7 +633,7 @@ class ExplorationActivityTest {
)
testCoroutineDispatchers.runCurrent()
- onView(withText("Would you like Oppia to read for you? Tap on this button to try!"))
+ onView(withText(context.getString(R.string.voiceover_icon_spotlight_hint, R.string.app_name)))
.check(doesNotExist())
}
}
From 9fc2aef5f06dd4975aaf5fa83a3ffe0ed11d250a Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Sun, 20 Nov 2022 18:56:23 +0530
Subject: [PATCH 108/138] suggestive comments
---
...pterNotStartedContainerConstraintLayout.kt | 4 +-
.../app/customview/PromotedStoryCardView.kt | 2 +-
.../android/app/home/HomeActivityPresenter.kt | 2 +-
.../onboarding/OnboardingActivityPresenter.kt | 2 +-
.../onboarding/OnboardingFragmentPresenter.kt | 4 +-
.../player/audio/AudioFragmentPresenter.kt | 6 --
.../ExplorationActivityPresenter.kt | 2 +-
.../ExplorationFragmentPresenter.kt | 2 +-
.../oppia/android/app/spotlight/BUILD.bazel | 4 ++
.../app/spotlight/SpotlightFragment.kt | 64 ++++---------------
.../android/app/spotlight/SpotlightManager.kt | 16 ++---
.../android/app/spotlight/SpotlightTarget.kt | 12 ++--
.../testing/SpotlightFragmentTestActivity.kt | 4 +-
.../SpotlightFragmentTestActivityPresenter.kt | 2 +-
.../app/topic/TopicActivityPresenter.kt | 2 +-
.../app/topic/TopicFragmentPresenter.kt | 6 +-
.../org/oppia/android/app/topic/TopicTab.kt | 10 +--
.../main/res/layout/bottom_left_overlay.xml | 4 --
.../main/res/layout/bottom_right_overlay.xml | 4 --
app/src/main/res/layout/top_left_overlay.xml | 4 --
app/src/main/res/layout/top_right_overlay.xml | 4 --
.../app/spotlight/SpotlightFragmentTest.kt | 12 ----
.../player/state/StateFragmentLocalTest.kt | 4 --
23 files changed, 52 insertions(+), 124 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index 5d92ec9b9a2..5df58e5522f 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -14,7 +14,7 @@ import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
import javax.inject.Inject
-/** Custom view to hold the chapter that has not yet been started. */
+/** Custom view that represents an incomplete chapter. */
class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@@ -30,7 +30,7 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
@Inject
lateinit var resourceHandler: AppLanguageResourceHandler
- /** Set the index of the story of which this custom view is a part of. */
+ /** Sets the index of the story of which this custom view is a part of. */
fun setStoryIndex(index: Int) {
// Only spotlight the first chapter of the "first" story. We know for sure that for a new user,
// the first chapter shall be a type of not started chapter view. The index tells which story
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
index a77c80099cd..345da555d94 100644
--- a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -14,7 +14,7 @@ import org.oppia.android.app.view.ViewComponentFactory
import org.oppia.android.app.view.ViewComponentImpl
import javax.inject.Inject
-/** Custom view to hold the promoted story cards. */
+/** [MaterialCardView] that represents stories promoted to the learner. */
class PromotedStoryCardView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
diff --git a/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
index da1bc61cf51..22db68591ae 100644
--- a/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
@@ -69,6 +69,6 @@ class HomeActivityPresenter @Inject constructor(private val activity: AppCompatA
private fun getSpotlightFragment(): SpotlightFragment? {
return activity.supportFragmentManager.findFragmentById(
R.id.home_spotlight_fragment_placeholder
- ) as SpotlightFragment?
+ ) as? SpotlightFragment
}
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
index 1aed8f979e0..9bf39fda627 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
@@ -46,6 +46,6 @@ class OnboardingActivityPresenter @Inject constructor(private val activity: AppC
.supportFragmentManager
.findFragmentById(
R.id.onboarding_spotlight_fragment_placeholder
- ) as SpotlightFragment?
+ ) as? SpotlightFragment
}
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index 426877d528f..d850e83944e 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -60,10 +60,10 @@ class OnboardingFragmentPresenter @Inject constructor(
return binding.root
}
- private fun getSpotlightFragment(): SpotlightFragment {
+ private fun getSpotlightFragment(): SpotlightFragment? {
return activity.supportFragmentManager.findFragmentByTag(
SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
- ) as SpotlightFragment
+ ) as? SpotlightFragment
}
fun startSpotlight() {
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index fe3cab9316d..c953f7f92ce 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -204,12 +204,6 @@ class AudioFragmentPresenter @Inject constructor(
}
}
- private fun handleOnPlay() {
- if (!activity.isChangingConfigurations && prepared) {
- viewModel.togglePlayPause(UiAudioPlayStatus.PAUSED)
- }
- }
-
/** Releases audio player resources */
fun handleOnDestroy() {
if (!activity.isChangingConfigurations) {
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
index 0338c054884..0ef4379aab4 100644
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
@@ -168,7 +168,7 @@ class ExplorationActivityPresenter @Inject constructor(
private fun getSpotlightFragment(): SpotlightFragment? {
return activity.supportFragmentManager.findFragmentByTag(
SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
- ) as SpotlightFragment?
+ ) as? SpotlightFragment
}
fun loadExplorationFragment(readingTextSize: ReadingTextSize) {
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index aa4536ce4db..24e7c3d0ad4 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -110,7 +110,7 @@ class ExplorationFragmentPresenter @Inject constructor(
private fun getSpotlightFragment(): SpotlightFragment? {
return fragment.requireActivity().supportFragmentManager.findFragmentByTag(
SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
- ) as SpotlightFragment?
+ ) as? SpotlightFragment
}
fun handlePlayAudio() {
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/BUILD.bazel b/app/src/main/java/org/oppia/android/app/spotlight/BUILD.bazel
index fc04a936671..3114c4f118c 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/BUILD.bazel
+++ b/app/src/main/java/org/oppia/android/app/spotlight/BUILD.bazel
@@ -1,3 +1,7 @@
+"""
+Constructs for setting up spotlights.
+"""
+
load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library")
genrule(
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index cc9296e38f1..89c9674a901 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -36,7 +36,7 @@ import java.util.LinkedList
import javax.inject.Inject
/**
- * Fragment to hold the spotlights on elements. This fragments provides a single place for all the
+ * Fragment to hold spotlights on elements. This fragment provides a single place for all the
* spotlight interactions, and handles lifecycle related functionality for spotlights, such as
* surviving orientation changes and marking spotlights as seen.
*/
@@ -76,23 +76,15 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
override fun onAttach(context: Context) {
super.onAttach(context)
(fragmentComponent as FragmentComponentImpl).inject(this)
-
internalProfileId = arguments?.getInt(PROFILE_ID_ARGUMENT_KEY) ?: -1
calculateScreenSize()
}
- /**
- * Requests a spotlight to be shown on the [SpotlightTarget]. The spotlight is enqueued if it
- * [SpotlightTarget] hasn't been shown before in a FIFO buffer. This API can ensure proper
- * spotlighting of a which is laid out after an animation. For the spotlights to work correctly,
- * we must know the [SpotlightTarget]'s anchor's size and position. For a view that is laid out
- * after an animation, we must wait until the final size and positions of the anchor view are
- * measured, which can be achieved by using doOnPreDraw. Refer:
- * https://betterprogramming.pub/stop-using-post-postdelayed-in-your-android-views-9d1c8eeaadf2
- *
- * @param spotlightTarget The [SpotlightTarget] for which the spotlight is requested
- */
override fun requestSpotlightViewWithDelayedLayout(spotlightTarget: SpotlightTarget) {
+ // For the spotlights to work correctly, we must know the [SpotlightTarget]'s anchor's size and
+ // position. For a view that is laid out after an animation, we must wait until the final size
+ // and positions of the anchor view are measured, which can be achieved by using doOnPreDraw:
+ // https://betterprogramming.pub/stop-using-post-postdelayed-in-your-android-views-9d1c8eeaadf2
spotlightTarget.anchor.doOnPreDraw {
if (it.visibility != View.VISIBLE) {
return@doOnPreDraw
@@ -109,20 +101,10 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
spotlightTarget.anchor.requestLayout()
}
- /**
- * Requests a spotlight to be shown on the [SpotlightTarget]. The spotlight is enqueued if it
- * hasn't been shown before in a FIFO buffer. This API can ensure proper spotlighting of a
- * [SpotlightTarget] when it is laid out late due to a data provider call. It cannot ensure the
- * same if the view has to be spotlit immediately after an animation. It also cannot spotlight
- * targets which are a part of a recycler view which are laid out after a data provider call. If
- * TalkBack is turned on, no spotlight shall be shown.
- *
- * @param spotlightTarget The [SpotlightTarget] for which the spotlight is requested
- */
override fun requestSpotlight(spotlightTarget: SpotlightTarget) {
-
+ // When Talkback is turned on, do not show spotlights since they are visual tools and can
+ // potentially make the app experience difficult for a non-sighted user.
if (accessibilityService.isScreenReaderEnabled()) return
-
val profileId = ProfileId.newBuilder()
.setInternalId(internalProfileId)
.build()
@@ -133,29 +115,22 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
spotlightTarget.feature
).toLiveData()
- // use activity as observer because this fragment's view hasn't been created yet.
+ // Use activity as observer because this fragment's view hasn't been created yet.
featureViewStateLiveData.observe(
activity,
object : Observer> {
override fun onChanged(it: AsyncResult?) {
if (it is AsyncResult.Success) {
- val viewState = (it.value)
- if (viewState == SpotlightViewState.SPOTLIGHT_SEEN) {
- return
- } else if (viewState == SpotlightViewState.SPOTLIGHT_NOT_SEEN) {
- createTarget(spotlightTarget)
- featureViewStateLiveData.removeObserver(this)
- }
+ if (it.value == SpotlightViewState.SPOTLIGHT_SEEN) return
+ createTarget(spotlightTarget)
+ featureViewStateLiveData.removeObserver(this)
}
}
}
)
}
- private fun createTarget(
- spotlightTarget: SpotlightTarget
- ) {
-
+ private fun createTarget(spotlightTarget: SpotlightTarget) {
val target = Target.Builder()
.setShape(getShape(spotlightTarget))
.setOverlay(requestOverlayResource(spotlightTarget))
@@ -210,9 +185,9 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
SpotlightShape.Circle -> {
return if (spotlightTarget.anchorHeight > spotlightTarget.anchorWidth) {
- Circle((spotlightTarget.anchorHeight / 2).toFloat())
+ Circle((spotlightTarget.anchorHeight / 2.0f))
} else {
- Circle((spotlightTarget.anchorWidth / 2).toFloat())
+ Circle((spotlightTarget.anchorWidth / 2.0f))
}
}
}
@@ -227,17 +202,14 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
private fun getScreenCentreY(): Int {
- Log.d("overlay screenCentre Y", (screenHeight / 2).toString())
return screenHeight / 2
}
private fun getScreenCentreX(): Int {
- Log.d("overlay screenCentre X", (screenWidth / 2).toString())
return screenWidth / 2
}
private fun calculateAnchorPosition(spotlightTarget: SpotlightTarget): AnchorPosition {
- Log.d("overlay", "checking anchor position. RTL = $isRtl")
return if (spotlightTarget.anchorCentreX > getScreenCentreX()) {
if (spotlightTarget.anchorCentreY > getScreenCentreY()) {
AnchorPosition.BottomRight
@@ -308,7 +280,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
it.lifecycleOwner = this
it.listener = this
}
-
(overlayBinding as BottomLeftOverlayBinding).customText.text = spotlightTarget.hint
val arrowParams = (overlayBinding as BottomLeftOverlayBinding).arrow.layoutParams
@@ -329,7 +300,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
)
}
(overlayBinding as BottomLeftOverlayBinding).arrow.layoutParams = arrowParams
-
return (overlayBinding as BottomLeftOverlayBinding).root
}
@@ -339,7 +309,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
it.lifecycleOwner = this
it.listener = this
}
-
(overlayBinding as BottomRightOverlayBinding).customText.text = spotlightTarget.hint
val arrowParams = (overlayBinding as BottomRightOverlayBinding).arrow.layoutParams
@@ -361,7 +330,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
)
}
(overlayBinding as BottomRightOverlayBinding).arrow.layoutParams = arrowParams
-
return (overlayBinding as BottomRightOverlayBinding).root
}
@@ -371,7 +339,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
it.lifecycleOwner = this
it.listener = this
}
-
(overlayBinding as TopRightOverlayBinding).customText.text = spotlightTarget.hint
val arrowParams = (overlayBinding as TopRightOverlayBinding).arrow.layoutParams
@@ -392,7 +359,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
)
}
(overlayBinding as TopRightOverlayBinding).arrow.layoutParams = arrowParams
-
return (overlayBinding as TopRightOverlayBinding).root
}
@@ -402,7 +368,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
it.lifecycleOwner = this
it.listener = this
}
-
(overlayBinding as TopLeftOverlayBinding).customText.text = spotlightTarget.hint
val arrowParams = (overlayBinding as TopLeftOverlayBinding).arrow.layoutParams
@@ -423,7 +388,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
)
}
(overlayBinding as TopLeftOverlayBinding).arrow.layoutParams = arrowParams
-
return (overlayBinding as TopLeftOverlayBinding).root
}
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt
index 7273b487769..5b9de0d8423 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightManager.kt
@@ -5,11 +5,8 @@ interface SpotlightManager {
/**
* Requests a spotlight to be shown on the [SpotlightTarget]. The spotlight is enqueued if it
* hasn't been shown before in a FIFO buffer. This API can ensure proper spotlighting of a
- * [SpotlightTarget] which is laid out after an animation. For the spotlights to work correctly,
- * we must know the [SpotlightTarget]'s anchor's size and position. For a view that is laid out
- * after an animation, we must wait until the final size and positions of the anchor view are
- * measured, which can be achieved by using doOnPreDraw. Refer:
- * https://betterprogramming.pub/stop-using-post-postdelayed-in-your-android-views-9d1c8eeaadf2
+ * [SpotlightTarget] which is laid out after an animation, or is a part of a recycler view which
+ * gets laid out after a data provider call.
*
* @param spotlightTarget The [SpotlightTarget] for which the spotlight is requested
*/
@@ -18,10 +15,11 @@ interface SpotlightManager {
/**
* Requests a spotlight to be shown on the [SpotlightTarget]. The spotlight is enqueued if it
* hasn't been shown before in a FIFO buffer. This API can ensure proper spotlighting of a
- * [SpotlightTarget] when it is laid out late due to a data provider call. It cannot ensure the
- * same if the view has to be spotlit immediately after an animation. It also cannot spotlight
- * targets which are a part of a recycler view which are laid out after a data provider call.
- * If TalkBack is turned on, no spotlight shall be shown.
+ * [SpotlightTarget] when it is laid out late due to a data provider call. In these cases, use
+ * [requestSpotlightViewWithDelayedLayout], instead. It cannot ensure the same if the view has
+ * to be spotlit immediately after an animation. It also cannot spotlight targets which are a part
+ * of a recycler view which are laid out after a data provider call. If TalkBack is turned on, no
+ * spotlight shall be shown.
*
* @param spotlightTarget The [SpotlightTarget] for which the spotlight is requested
*/
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
index 97c935b4b3f..0642cb7b721 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
@@ -4,16 +4,16 @@ import android.view.View
import org.oppia.android.app.model.Spotlight.FeatureCase
/**
- * Data class to hold a [SpotlightTarget].
+ * Represents a screen target that can be spotlit using [SpotlightManager].
*
- * @param anchor the view that should be spotlit
- * @param hint the hint text that should be shown on the spotlight overlay
- * @param shape [SpotlightShape] of the spotlight
- * @param feature The [Spotlight] feature-case corresponding to the spotlight target
+ * @property anchor the view that should be spotlit
+ * @property hint the hint text that should be shown on the spotlight overlay
+ * @property shape [SpotlightShape] of the spotlight
+ * @property feature the [Spotlight] feature being spotlit by this target
*/
data class SpotlightTarget(
val anchor: View,
- val hint: String = "",
+ val hint: String,
val shape: SpotlightShape = SpotlightShape.RoundedRectangle,
val feature: FeatureCase
) {
diff --git a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
index a4a4b56f23d..b8548ad0a1b 100644
--- a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
+++ b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
@@ -20,7 +20,7 @@ class SpotlightFragmentTestActivity : TestActivity() {
spotlightFragmentTestActivityPresenter.handleOnCreate(
intent.getIntExtra(
- PROFILE_ID_ARGUMENT_KEY, -1
+ PROFILE_ID_ARGUMENT_KEY, /* profileIdKEyDefaultValue */ -1
)
)
}
@@ -35,7 +35,7 @@ class SpotlightFragmentTestActivity : TestActivity() {
/** Returns the [Intent] for opening [SpotlightFragmentTestActivity]. */
fun createSpotlightFragmentTestActivity(context: Context): Intent {
return Intent(context, SpotlightFragmentTestActivity::class.java).also {
- it.putExtra(PROFILE_ID_ARGUMENT_KEY, 0)
+ it.putExtra(PROFILE_ID_ARGUMENT_KEY, /* profileIdKEyDefaultValue */ 0)
}
}
}
diff --git a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt
index 798d724e01c..7ea63eab8f6 100644
--- a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivityPresenter.kt
@@ -39,7 +39,7 @@ class SpotlightFragmentTestActivityPresenter @Inject constructor(
fun getSpotlightFragment(): SpotlightFragment? {
return activity.supportFragmentManager.findFragmentByTag(
SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
- ) as SpotlightFragment?
+ ) as? SpotlightFragment
}
/** Returns a view to be used as a spotlight anchor. */
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
index fb345ad8395..daf782d3c31 100755
--- a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
@@ -63,6 +63,6 @@ class TopicActivityPresenter @Inject constructor(private val activity: AppCompat
private fun getSpotlightFragment(): SpotlightFragment? {
return activity.supportFragmentManager.findFragmentByTag(
SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
- ) as SpotlightFragment?
+ ) as? SpotlightFragment
}
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index e4e07819b24..616cd8ebf37 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -31,7 +31,7 @@ class TopicFragmentPresenter @Inject constructor(
private val viewModel: TopicViewModel,
private val oppiaLogger: OppiaLogger,
@EnableExtraTopicTabsUi private val enableExtraTopicTabsUi: PlatformParameterValue,
- private val resourceHandler: AppLanguageResourceHandler,
+ private val resourceHandler: AppLanguageResourceHandler
) {
private lateinit var tabLayout: TabLayout
private var internalProfileId: Int = -1
@@ -106,7 +106,7 @@ class TopicFragmentPresenter @Inject constructor(
private fun getSpotlightFragment(): SpotlightFragment? {
return activity.supportFragmentManager.findFragmentByTag(
SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
- ) as SpotlightFragment?
+ ) as? SpotlightFragment
}
private fun setCurrentTab(tab: TopicTab) {
@@ -126,7 +126,7 @@ class TopicFragmentPresenter @Inject constructor(
val topicTab = TopicTab.getTabForPosition(position, enableExtraTopicTabsUi.value)
tab.text = resourceHandler.getStringInLocale(topicTab.tabLabelResId)
tab.icon = ContextCompat.getDrawable(activity, topicTab.tabIconResId)
- tab.contentDescription = resourceHandler.getStringInLocale(topicTab.contentDescription)
+ tab.contentDescription = resourceHandler.getStringInLocale(topicTab.contentDescriptionResId)
}.attach()
if (!isConfigChanged && topicId.isNotEmpty()) {
if (enableExtraTopicTabsUi.value) {
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicTab.kt b/app/src/main/java/org/oppia/android/app/topic/TopicTab.kt
index 3a8b66d4830..fd10d629a13 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicTab.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicTab.kt
@@ -10,35 +10,35 @@ enum class TopicTab(
val positionWithFourTabs: Int,
@StringRes val tabLabelResId: Int,
@DrawableRes val tabIconResId: Int,
- @StringRes val contentDescription: Int
+ @StringRes val contentDescriptionResId: Int
) {
INFO(
positionWithTwoTabs = -1,
positionWithFourTabs = 0,
tabLabelResId = R.string.info,
tabIconResId = R.drawable.ic_info_icon_24dp,
- contentDescription = R.string.info_tab_content_description
+ contentDescriptionResId = R.string.info_tab_content_description
),
LESSONS(
positionWithTwoTabs = 0,
positionWithFourTabs = 1,
tabLabelResId = R.string.lessons,
tabIconResId = R.drawable.ic_lessons_icon_24dp,
- contentDescription = R.string.lessons_tab_content_description
+ contentDescriptionResId = R.string.lessons_tab_content_description
),
PRACTICE(
positionWithTwoTabs = -1,
positionWithFourTabs = 2,
tabLabelResId = R.string.practice,
tabIconResId = R.drawable.ic_practice_icon_24dp,
- contentDescription = R.string.practice_tab_content_description
+ contentDescriptionResId = R.string.practice_tab_content_description
),
REVISION(
positionWithTwoTabs = 1,
positionWithFourTabs = 3,
tabLabelResId = R.string.revision,
tabIconResId = R.drawable.ic_revision_icon_24dp,
- contentDescription = R.string.revision_tab_content_description
+ contentDescriptionResId = R.string.revision_tab_content_description
);
companion object {
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 74fa9d2d466..219a68f435c 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -3,9 +3,6 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
-
-
-
@@ -40,7 +37,6 @@
android:paddingTop="4dp"
android:paddingEnd="4dp"
android:paddingBottom="4dp"
- android:text="this is a custom text"
android:textSize="20dp"
app:layout_constraintBottom_toTopOf="@id/arrow"
app:layout_constraintEnd_toEndOf="parent"
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index dbd5d15ebf3..954a92c4536 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -3,9 +3,6 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
-
-
-
@@ -40,7 +37,6 @@
android:paddingTop="4dp"
android:paddingEnd="4dp"
android:paddingBottom="4dp"
- android:text="this is a custom text"
android:textSize="20dp"
app:layout_constraintBottom_toTopOf="@id/arrow"
app:layout_constraintEnd_toEndOf="@+id/arrow"
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index ffe62be409e..2cf493604bf 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -3,9 +3,6 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
-
-
-
@@ -39,7 +36,6 @@
android:paddingTop="4dp"
android:paddingEnd="4dp"
android:paddingBottom="4dp"
- android:text="this is a custom text"
android:textSize="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/arrow"
diff --git a/app/src/main/res/layout/top_right_overlay.xml b/app/src/main/res/layout/top_right_overlay.xml
index 0be418649dc..57dd51cd7e1 100644
--- a/app/src/main/res/layout/top_right_overlay.xml
+++ b/app/src/main/res/layout/top_right_overlay.xml
@@ -3,9 +3,6 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
-
-
-
@@ -39,7 +36,6 @@
android:paddingTop="4dp"
android:paddingEnd="4dp"
android:paddingBottom="4dp"
- android:text="this is a custom text"
android:textSize="20dp"
app:layout_constraintEnd_toEndOf="@+id/arrow"
app:layout_constraintStart_toStartOf="parent"
diff --git a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
index a9d86c3b326..36f6f7b0e93 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
@@ -108,9 +108,6 @@ class SpotlightFragmentTest {
@Inject
lateinit var context: Context
-// @get:Rule
-// val oppiaTestRule = OppiaTestRule()
-
@field:[Rule JvmField]
val mockitoRule: MockitoRule = MockitoJUnit.rule()
@@ -124,15 +121,6 @@ class SpotlightFragmentTest {
@field:DefaultResourceBucketName
lateinit var resourceBucketName: String
-// @get:Rule
-// var activityScenarioRule: ActivityScenarioRule =
-// ActivityScenarioRule(
-// Intent(
-// ApplicationProvider.getApplicationContext(),
-// SpotlightFragmentTestActivity::class.java
-// )
-// )
-
private val sampleSpotlightText = "Sample spotlight hint text"
private val sampleSecondSpotlightText = "Sample hint text for second spotlight"
diff --git a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
index 89ee50b2ff6..6009b6bad86 100644
--- a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
@@ -139,7 +139,6 @@ import org.oppia.android.testing.junit.InitializeDefaultLocaleRule
import org.oppia.android.testing.platformparameter.TestPlatformParameterModule
import org.oppia.android.testing.profile.ProfileTestHelper
import org.oppia.android.testing.robolectric.RobolectricModule
-import org.oppia.android.testing.story.StoryProgressTestHelper
import org.oppia.android.testing.threading.CoroutineExecutorService
import org.oppia.android.testing.threading.TestCoroutineDispatchers
import org.oppia.android.testing.threading.TestDispatcherModule
@@ -219,9 +218,6 @@ class StateFragmentLocalTest {
@Inject
lateinit var fakeAccessibilityService: FakeAccessibilityService
- @Inject
- lateinit var storyProgressTestHelper: StoryProgressTestHelper
-
private val profileId = ProfileId.newBuilder().apply { internalId = 1 }.build()
private val solutionIndex: Int = 4
From 855e32454acac84ee5676f205ef282ae54840471 Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Sun, 20 Nov 2022 19:35:03 +0530
Subject: [PATCH 109/138] general nits
---
...pterNotStartedContainerConstraintLayout.kt | 2 +-
.../app/spotlight/SpotlightFragment.kt | 47 +++++++++----------
.../spotlight/SpotlightNavigationListener.kt | 2 +-
.../android/app/spotlight/SpotlightTarget.kt | 2 +-
.../spotlight_overlay_hint_background.xml | 2 +-
.../main/res/layout/bottom_left_overlay.xml | 4 +-
.../main/res/layout/bottom_right_overlay.xml | 4 +-
app/src/main/res/layout/top_left_overlay.xml | 4 +-
app/src/main/res/layout/top_right_overlay.xml | 4 +-
app/src/main/res/values/strings.xml | 12 ++---
10 files changed, 41 insertions(+), 42 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index 5df58e5522f..c5c5c7929e9 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -31,7 +31,7 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
lateinit var resourceHandler: AppLanguageResourceHandler
/** Sets the index of the story of which this custom view is a part of. */
- fun setStoryIndex(index: Int) {
+ spotligfun setStoryIndex(index: Int) {
// Only spotlight the first chapter of the "first" story. We know for sure that for a new user,
// the first chapter shall be a type of not started chapter view. The index tells which story
// are we on.
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 89c9674a901..4da196411c7 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -64,14 +64,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
resourceHandler.getLayoutDirection() == ViewCompat.LAYOUT_DIRECTION_RTL
}
- private fun calculateScreenSize() {
- val displayMetrics = DisplayMetrics()
- activity.windowManager.defaultDisplay.getMetrics(displayMetrics)
-
- screenHeight = displayMetrics.heightPixels
- screenWidth = displayMetrics.widthPixels
- }
-
// since this fragment does not have any view to inflate yet, all the tasks should be done here.
override fun onAttach(context: Context) {
super.onAttach(context)
@@ -130,6 +122,10 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
)
}
+ override fun clickOnDone() {
+ spotlight.next()
+ }
+
private fun createTarget(spotlightTarget: SpotlightTarget) {
val target = Target.Builder()
.setShape(getShape(spotlightTarget))
@@ -225,7 +221,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
private fun requestOverlayResource(spotlightTarget: SpotlightTarget): View {
val anchorPosition = calculateAnchorPosition(spotlightTarget)
- Log.d("overlay", anchorPosition.toString())
return when (anchorPosition) {
AnchorPosition.TopLeft -> {
@@ -259,21 +254,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
}
- private sealed class AnchorPosition {
- /** The position corresponding to the anchor when it is on the top left of the screen. */
- object TopLeft : AnchorPosition()
- /** The position corresponding to the anchor when it is on the top right of the screen. */
- object TopRight : AnchorPosition()
- /** The position corresponding to the anchor when it is on the bottom left of the screen. */
- object BottomLeft : AnchorPosition()
- /** The position corresponding to the anchor when it is on the bottom right of the screen. */
- object BottomRight : AnchorPosition()
- }
-
- override fun clickOnNextTip() {
- spotlight.next()
- }
-
private fun configureBottomLeftOverlay(spotlightTarget: SpotlightTarget): View {
overlayBinding = BottomLeftOverlayBinding.inflate(this.layoutInflater)
(overlayBinding as BottomLeftOverlayBinding).let {
@@ -390,4 +370,23 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
(overlayBinding as TopLeftOverlayBinding).arrow.layoutParams = arrowParams
return (overlayBinding as TopLeftOverlayBinding).root
}
+
+ private fun calculateScreenSize() {
+ val displayMetrics = DisplayMetrics()
+ activity.windowManager.defaultDisplay.getMetrics(displayMetrics)
+
+ screenHeight = displayMetrics.heightPixels
+ screenWidth = displayMetrics.widthPixels
+ }
+
+ private sealed class AnchorPosition {
+ /** The position corresponding to the anchor when it is on the top left of the screen. */
+ object TopLeft : AnchorPosition()
+ /** The position corresponding to the anchor when it is on the top right of the screen. */
+ object TopRight : AnchorPosition()
+ /** The position corresponding to the anchor when it is on the bottom left of the screen. */
+ object BottomLeft : AnchorPosition()
+ /** The position corresponding to the anchor when it is on the bottom right of the screen. */
+ object BottomRight : AnchorPosition()
+ }s
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightNavigationListener.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightNavigationListener.kt
index 5ca40b6436b..c6966b1ebb3 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightNavigationListener.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightNavigationListener.kt
@@ -3,5 +3,5 @@ package org.oppia.android.app.spotlight
/** Listener for the spotlight navigation buttons. */
interface SpotlightNavigationListener {
/** Called when a spotlight's "done" button is clicked. */
- fun clickOnNextTip()
+ fun clickOnDone()
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
index 0642cb7b721..2355fc010d2 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightTarget.kt
@@ -28,7 +28,7 @@ data class SpotlightTarget(
val anchorWidth: Int = calculateAnchorWidth()
/** The position of the vertical centre of the anchor. */
val anchorCentreX = calculateAnchorCentreX()
- /** The margin of the horizontal anchor. */
+ /** The position of the horizontal centre of the anchor. */
val anchorCentreY = calculateAnchorCentreY()
init {
diff --git a/app/src/main/res/drawable/spotlight_overlay_hint_background.xml b/app/src/main/res/drawable/spotlight_overlay_hint_background.xml
index 4f220d50e7f..cfa84f27751 100644
--- a/app/src/main/res/drawable/spotlight_overlay_hint_background.xml
+++ b/app/src/main/res/drawable/spotlight_overlay_hint_background.xml
@@ -7,4 +7,4 @@
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
-
\ No newline at end of file
+
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 219a68f435c..08f29a44263 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -53,7 +53,7 @@
android:clickable="true"
android:focusable="true"
android:gravity="center"
- android:onClick="@{(v) -> listener.clickOnNextTip()}"
+ android:onClick="@{(v) -> listener.clickOnDone()}"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:text="Done"
@@ -62,4 +62,4 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
-
\ No newline at end of file
+
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index 954a92c4536..bc122e4b186 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -53,7 +53,7 @@
android:clickable="true"
android:focusable="true"
android:gravity="center"
- android:onClick="@{(v) -> listener.clickOnNextTip()}"
+ android:onClick="@{(v) -> listener.clickOnDone()}"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:text="Done"
@@ -62,4 +62,4 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
-
\ No newline at end of file
+
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index 2cf493604bf..a5ca5722019 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -52,7 +52,7 @@
android:clickable="true"
android:focusable="true"
android:gravity="center"
- android:onClick="@{(v) -> listener.clickOnNextTip()}"
+ android:onClick="@{(v) -> listener.clickOnDone()}"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:text="Done"
@@ -61,4 +61,4 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
-
\ No newline at end of file
+
diff --git a/app/src/main/res/layout/top_right_overlay.xml b/app/src/main/res/layout/top_right_overlay.xml
index 57dd51cd7e1..f2194f89c67 100644
--- a/app/src/main/res/layout/top_right_overlay.xml
+++ b/app/src/main/res/layout/top_right_overlay.xml
@@ -50,7 +50,7 @@
android:layout_marginBottom="50dp"
android:background="@color/color_def_dark_blue"
android:gravity="center"
- android:onClick="@{(v) -> listener.clickOnNextTip()}"
+ android:onClick="@{(v) -> listener.clickOnDone()}"
android:paddingTop="50dp"
android:paddingBottom="8dp"
android:text="Done"
@@ -59,4 +59,4 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
-
\ No newline at end of file
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9e008213275..9440d640026 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -572,10 +572,10 @@
Administrator Controls Fragment Test Activity
Select a Topic to Start
Continue Studying
- Info tab
- After completing a lesson, revise your concepts in the revision tab.
- Practice tab
- Start learning here in the lessons tab.
+ Details about the topic.
+ Revise concepts learned from completed lessons here.
+ Practice the concepts learned from completed lessons.
+ Tap here to start playing a lesson.
Find all your lessons here
Revise your lessons here
Tap to start a chapter
@@ -583,6 +583,6 @@
Would you like %s to read for you? Tap on this button to try!
Tap to change voiceover language
Next
- From now, you can see stories recommended for you here
- Go to the bottom of the screen for hint
+ From now, you can see lessons recommended for you here.
+ Go to the bottom of the screen for a hint.
From a69c4c1692e98da1ad187753cf97492bcfd45755 Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Sun, 20 Nov 2022 21:48:23 +0530
Subject: [PATCH 110/138] general nits
---
.../app/customview/PromotedStoryCardView.kt | 8 +--
.../onboarding/OnboardingFragmentPresenter.kt | 2 +-
.../ExplorationFragmentPresenter.kt | 21 ++++----
.../app/spotlight/SpotlightFragment.kt | 2 +-
.../main/res/layout/bottom_left_overlay.xml | 8 +--
.../main/res/layout/bottom_right_overlay.xml | 8 +--
app/src/main/res/layout/top_left_overlay.xml | 8 +--
app/src/main/res/layout/top_right_overlay.xml | 8 +--
app/src/main/res/values/strings.xml | 8 +--
.../android/app/home/HomeActivityTest.kt | 2 +-
.../exploration/ExplorationActivityTest.kt | 6 +--
.../android/app/topic/TopicFragmentTest.kt | 49 +++++++------------
12 files changed, 57 insertions(+), 73 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
index 345da555d94..ec281c4b20a 100644
--- a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -31,16 +31,16 @@ class PromotedStoryCardView @JvmOverloads constructor(
/** Sets the index at which this custom view is located inside the recycler view. */
fun setIndex(index: Int) {
- if (!isSpotlit) {
+ // This view can get attached multiple times and we must make sure that the spotlight is
+ // requested only once. Only spotlight the item at the first index of the recycler view.
+ if (!isSpotlit && index == 0) {
isSpotlit = true
val spotlightTarget = SpotlightTarget(
this,
resourceHandler.getStringInLocale(R.string.promoted_story_spotlight_hint),
feature = Spotlight.FeatureCase.PROMOTED_STORIES
)
- if (index == 0) {
- checkNotNull(getSpotlightFragment()).requestSpotlightViewWithDelayedLayout(spotlightTarget)
- }
+ checkNotNull(getSpotlightFragment()).requestSpotlightViewWithDelayedLayout(spotlightTarget)
}
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index d850e83944e..532de574b6c 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -73,7 +73,7 @@ class OnboardingFragmentPresenter @Inject constructor(
SpotlightShape.Circle,
Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON
)
- getSpotlightFragment().requestSpotlightViewWithDelayedLayout(nextSpotlightTarget)
+ checkNotNull(getSpotlightFragment()).requestSpotlightViewWithDelayedLayout(nextSpotlightTarget)
}
private fun setUpViewPager() {
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index 24e7c3d0ad4..c1769976312 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -73,17 +73,16 @@ class ExplorationFragmentPresenter @Inject constructor(
fragment
) { result ->
val readingTextSize = retrieveArguments().readingTextSize
- if (result is AsyncResult.Success && result.value.readingTextSize != readingTextSize) {
- selectNewReadingTextSize(result.value.readingTextSize)
-
- // Since text views are based on sp for sizing, the activity needs to be recreated so that
- // sp can be correctly recomputed.
- fragment.requireActivity().recreate()
- } else {
- if (result is AsyncResult.Success) {
- showSpotlights(result.value.numberOfLogins)
- }
+ if (result is AsyncResult.Success) {
+ if (result.value.readingTextSize != readingTextSize) {
+
+ // Since text views are based on sp for sizing, the activity needs to be recreated so that
+ // sp can be correctly recomputed.
+ selectNewReadingTextSize(result.value.readingTextSize)
+ fragment.requireActivity().recreate()
+ } else showSpotlights(result.value.numberOfLogins)
}
+ }
}
}
@@ -92,7 +91,7 @@ class ExplorationFragmentPresenter @Inject constructor(
fragment.requireActivity().findViewById(R.id.exploration_toolbar) as Toolbar
explorationToolbar.forEach {
if (it is ImageButton) {
- // this toolbar contains only one image button, which is the back navigation icon
+ // This toolbar contains only one image button, which is the back navigation icon.
val backButtonSpotlightTarget = SpotlightTarget(
it,
resourceHandler.getStringInLocale(R.string.exploration_exit_button_spotlight_hint),
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 4da196411c7..f1ab89f7f59 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -64,7 +64,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
resourceHandler.getLayoutDirection() == ViewCompat.LAYOUT_DIRECTION_RTL
}
- // since this fragment does not have any view to inflate yet, all the tasks should be done here.
+ // Since this fragment does not have any view to inflate yet, all the tasks should be done here.
override fun onAttach(context: Context) {
super.onAttach(context)
(fragmentComponent as FragmentComponentImpl).inject(this)
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 08f29a44263..1748341f702 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -9,7 +9,7 @@
+ app:layout_constraintStart_toStartOf="@+id/spotlight_overlay_arrow" />
+ app:layout_constraintStart_toStartOf="@id/spotlight_overlay_arrow"
+ app:layout_constraintTop_toBottomOf="@id/spotlight_overlay_arrow" />
+ app:layout_constraintTop_toBottomOf="@id/spotlight_overlay_arrow" />
Revise concepts learned from completed lessons here.
Practice the concepts learned from completed lessons.
Tap here to start playing a lesson.
- Find all your lessons here
- Revise your lessons here
- Tap to start a chapter
+ Find all your lessons here.
+ Revise your lessons here.
+ Tap to start a chapter.
Exit anytime using this button. We will save your progress.
Would you like %s to read for you? Tap on this button to try!
- Tap to change voiceover language
+ Tap to change voiceover language.
Next
From now, you can see lessons recommended for you here.
Go to the bottom of the screen for a hint.
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
index 308252f3fcd..721fe171346 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
@@ -352,7 +352,7 @@ class HomeActivityTest {
testCoroutineDispatchers.runCurrent()
}
- // re-launch the activity
+ // Re-launch the activity.
launch(createHomeActivityIntent(internalProfileId1)).use {
testCoroutineDispatchers.runCurrent()
onView(withText(R.string.promoted_story_spotlight_hint)).check(doesNotExist())
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
index c149f6d76a0..d49e9bdfe04 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
@@ -567,7 +567,7 @@ class ExplorationActivityTest {
@Test
fun testVoiceoverIconSpotlight_setToShowAfter3rdLogin_notSeen_checkSpotlightShown() {
- logIntoUserThrice()
+ logIntoAdminThrice()
setUpAudioForFractionLesson()
markSpotlightSeen(Spotlight.FeatureCase.LESSONS_BACK_BUTTON)
launch(
@@ -594,7 +594,7 @@ class ExplorationActivityTest {
@Test
fun testVoiceoverIconSpotlight_setToShowAfter3rdLogin_alreadySeen_checkSpotlightNotShown() {
- logIntoUserThrice()
+ logIntoAdminThrice()
setUpAudioForFractionLesson()
markSpotlightSeen(Spotlight.FeatureCase.LESSONS_BACK_BUTTON)
launch(
@@ -2187,7 +2187,7 @@ class ExplorationActivityTest {
markSpotlightSeen(Spotlight.FeatureCase.VOICEOVER_LANGUAGE_ICON)
}
- private fun logIntoUserThrice() {
+ private fun logIntoAdminThrice() {
monitorFactory.waitForNextSuccessfulResult(profileTestHelper.logIntoAdmin())
monitorFactory.waitForNextSuccessfulResult(profileTestHelper.logIntoAdmin())
monitorFactory.waitForNextSuccessfulResult(profileTestHelper.logIntoAdmin())
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
index 4c2126e5515..61cb0e3d19c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
@@ -120,6 +120,7 @@ import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
import javax.inject.Inject
import javax.inject.Singleton
+import org.oppia.android.app.model.Spotlight
private const val INFO_TAB_POSITION = 0
private const val LESSON_TAB_POSITION = 1
@@ -189,9 +190,9 @@ class TopicFragmentTest {
@Test
fun testLessonsTabSpotlight_spotlightAlreadySeen_checkSpotlightNotShown() {
initializeApplicationComponent(false)
- markFirstChapterSpotlightSeen()
+ markSpotlightSeen(FIRST_CHAPTER)
launch(createTopicActivityIntent(internalProfileId, FRACTIONS_TOPIC_ID)).use {
- // mark lessons spotlight seen
+ // Mark lessons spotlight seen.
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.close_target)).perform(click())
}
@@ -218,7 +219,7 @@ class TopicFragmentTest {
@Test
fun testFirstChapterSpotlight_setToShowOnFirstLogin_checkSpotlightShown() {
initializeApplicationComponent(false)
- markLessonsTabSpotlightSeen()
+ markSpotlightSeen(TOPIC_LESSON_TAB)
activityTestRule.launchActivity(
createTopicPlayStoryActivityIntent(
internalProfileId,
@@ -240,7 +241,7 @@ class TopicFragmentTest {
FRACTIONS_STORY_ID_0
)
).use {
- // mark first chapter spotlight seen
+ // Mark first chapter spotlight seen.
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.close_target)).perform(click())
testCoroutineDispatchers.runCurrent()
@@ -262,8 +263,8 @@ class TopicFragmentTest {
@Test
fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_notSeenBefore_checkShown() {
initializeApplicationComponent(false)
- markFirstChapterSpotlightSeen()
- markLessonsTabSpotlightSeen()
+ markSpotlightSeen(FIRST_CHAPTER)
+ markSpotlightSeen(TOPIC_LESSON_TAB)
val profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
storyProgressTestHelper.markCompletedFractionsStory0Exp0(profileId, false)
storyProgressTestHelper.markCompletedRatiosStory0Exp0(profileId, false)
@@ -281,8 +282,8 @@ class TopicFragmentTest {
@Test
fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_notComplete_checkNotShown() {
initializeApplicationComponent(false)
- markLessonsTabSpotlightSeen()
- markFirstChapterSpotlightSeen()
+ markSpotlightSeen(TOPIC_LESSON_TAB)
+ markSpotlightSeen(FIRST_CHAPTER)
launch(
createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)
).use {
@@ -294,8 +295,8 @@ class TopicFragmentTest {
@Test
fun testRevisionTabSpotlight_setToShowAfterAtleast3ChaptersCompleted_alreadySeen_checkNotShown() {
initializeApplicationComponent(false)
- markLessonsTabSpotlightSeen()
- markFirstChapterSpotlightSeen()
+ markSpotlightSeen(TOPIC_LESSON_TAB)
+ markSpotlightSeen(FIRST_CHAPTER)
val profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
fakeOppiaClock.setFakeTimeMode(FakeOppiaClock.FakeTimeMode.MODE_UPTIME_MILLIS)
storyProgressTestHelper.markCompletedFractionsStory0Exp0(profileId, false)
@@ -305,7 +306,7 @@ class TopicFragmentTest {
createTopicPlayStoryActivityIntent(internalProfileId, RATIOS_TOPIC_ID, RATIOS_STORY_ID_0)
).use {
testCoroutineDispatchers.runCurrent()
- // mark revision tab spotlight seen
+ // Mark revision tab spotlight seen.
onView(withId(R.id.close_target)).perform(click())
}
@@ -808,32 +809,16 @@ class TopicFragmentTest {
}
private fun markAllSpotlightsSeen() {
- markLessonsTabSpotlightSeen()
- markFirstChapterSpotlightSeen()
- markRevisionTabSpotlightSeen()
+ markSpotlightSeen(TOPIC_LESSON_TAB)
+ markSpotlightSeen(FIRST_CHAPTER)
+ markSpotlightSeen(TOPIC_REVISION_TAB)
}
- private fun markRevisionTabSpotlightSeen() {
+ private fun markSpotlightSeen(feature: Spotlight.FeatureCase) {
val profileId = ProfileId.newBuilder()
.setInternalId(internalProfileId)
.build()
- spotlightStateController.markSpotlightViewed(profileId, TOPIC_REVISION_TAB)
- testCoroutineDispatchers.runCurrent()
- }
-
- private fun markLessonsTabSpotlightSeen() {
- val profileId = ProfileId.newBuilder()
- .setInternalId(internalProfileId)
- .build()
- spotlightStateController.markSpotlightViewed(profileId, TOPIC_LESSON_TAB)
- testCoroutineDispatchers.runCurrent()
- }
-
- private fun markFirstChapterSpotlightSeen() {
- val profileId = ProfileId.newBuilder()
- .setInternalId(internalProfileId)
- .build()
- spotlightStateController.markSpotlightViewed(profileId, FIRST_CHAPTER)
+ spotlightStateController.markSpotlightViewed(profileId, feature)
testCoroutineDispatchers.runCurrent()
}
From 1af47a2336e4c0cddaa51936ec9d41f21980e0c3 Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Sun, 20 Nov 2022 22:12:12 +0530
Subject: [PATCH 111/138] general nits
---
.../customview/ChapterNotStartedContainerConstraintLayout.kt | 2 +-
.../oppia/android/app/player/state/StateFragmentPresenter.kt | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index c5c5c7929e9..6121e618766 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -31,7 +31,7 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
lateinit var resourceHandler: AppLanguageResourceHandler
/** Sets the index of the story of which this custom view is a part of. */
- spotligfun setStoryIndex(index: Int) {
+ sffun setStoryIndex(index: Int) {
// Only spotlight the first chapter of the "first" story. We know for sure that for a new user,
// the first chapter shall be a type of not started chapter view. The index tells which story
// are we on.
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 ae4b66d48c6..364ef65d225 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
@@ -512,6 +512,7 @@ class StateFragmentPresenter @Inject constructor(
activity.runPeriodically(delayMillis = 5_000, periodMillis = 30_000) {
return@runPeriodically viewModel.isHintOpenedAndUnRevealed.get()!!.also { playAnim ->
if (playAnim) binding.hintBulb.startAnimation(hintBulbAnimation)
+ // The forced announcement should be called
accessibilityService.announceForAccessibilityForView(
binding.hintsAndSolutionFragmentContainer,
resourceHandler.getStringInLocale(
From 5ac674226bbcf57b8e2f3ad3a56a6173148e2952 Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Sun, 20 Nov 2022 22:36:54 +0530
Subject: [PATCH 112/138] general nits
---
...apterNotStartedContainerConstraintLayout.kt | 2 +-
.../ExplorationFragmentPresenter.kt | 1 -
.../app/player/state/StateFragmentPresenter.kt | 18 ++++++++++++------
.../android/app/spotlight/SpotlightFragment.kt | 18 +++++++++---------
4 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index 6121e618766..97266d0c6b2 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -31,7 +31,7 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
lateinit var resourceHandler: AppLanguageResourceHandler
/** Sets the index of the story of which this custom view is a part of. */
- sffun setStoryIndex(index: Int) {
+ fun setStoryIndex(index: Int) {
// Only spotlight the first chapter of the "first" story. We know for sure that for a new user,
// the first chapter shall be a type of not started chapter view. The index tells which story
// are we on.
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index c1769976312..4b4652c5f63 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -82,7 +82,6 @@ class ExplorationFragmentPresenter @Inject constructor(
fragment.requireActivity().recreate()
} else showSpotlights(result.value.numberOfLogins)
}
- }
}
}
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 364ef65d225..7f234f97a0f 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
@@ -92,6 +92,7 @@ class StateFragmentPresenter @Inject constructor(
private lateinit var binding: StateFragmentBinding
private lateinit var recyclerViewAdapter: RecyclerView.Adapter<*>
private lateinit var helpIndex: HelpIndex
+ private var forceAnnouncedForHintsBar = false
private val viewModel: StateViewModel by lazy {
getStateViewModel()
@@ -512,13 +513,18 @@ class StateFragmentPresenter @Inject constructor(
activity.runPeriodically(delayMillis = 5_000, periodMillis = 30_000) {
return@runPeriodically viewModel.isHintOpenedAndUnRevealed.get()!!.also { playAnim ->
if (playAnim) binding.hintBulb.startAnimation(hintBulbAnimation)
- // The forced announcement should be called
- accessibilityService.announceForAccessibilityForView(
- binding.hintsAndSolutionFragmentContainer,
- resourceHandler.getStringInLocale(
- R.string.state_fragment_hint_bar_forced_announcement_text
+ // The forced announcement should be called after 5 seconds after the hints bar appears
+ // otherwise it might interrupt with the submit button's content description during
+ // Talkback.
+ if (!forceAnnouncedForHintsBar) {
+ forceAnnouncedForHintsBar = true
+ accessibilityService.announceForAccessibilityForView(
+ binding.hintsAndSolutionFragmentContainer,
+ resourceHandler.getStringInLocale(
+ R.string.state_fragment_hint_bar_forced_announcement_text
+ )
)
- )
+ }
}
}
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index f1ab89f7f59..5716e399436 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -262,7 +262,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
(overlayBinding as BottomLeftOverlayBinding).customText.text = spotlightTarget.hint
- val arrowParams = (overlayBinding as BottomLeftOverlayBinding).arrow.layoutParams
+ val arrowParams = (overlayBinding as BottomLeftOverlayBinding).spotlightOverlayArrow.layoutParams
as ViewGroup.MarginLayoutParams
if (isRtl) {
arrowParams.setMargins(
@@ -279,7 +279,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
}
- (overlayBinding as BottomLeftOverlayBinding).arrow.layoutParams = arrowParams
+ (overlayBinding as BottomLeftOverlayBinding).spotlightOverlayArrow.layoutParams = arrowParams
return (overlayBinding as BottomLeftOverlayBinding).root
}
@@ -291,7 +291,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
(overlayBinding as BottomRightOverlayBinding).customText.text = spotlightTarget.hint
- val arrowParams = (overlayBinding as BottomRightOverlayBinding).arrow.layoutParams
+ val arrowParams = (overlayBinding as BottomRightOverlayBinding).spotlightOverlayArrow.layoutParams
as ViewGroup.MarginLayoutParams
if (isRtl) {
arrowParams.setMargins(
@@ -309,7 +309,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
}
- (overlayBinding as BottomRightOverlayBinding).arrow.layoutParams = arrowParams
+ (overlayBinding as BottomRightOverlayBinding).spotlightOverlayArrow.layoutParams = arrowParams
return (overlayBinding as BottomRightOverlayBinding).root
}
@@ -321,7 +321,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
(overlayBinding as TopRightOverlayBinding).customText.text = spotlightTarget.hint
- val arrowParams = (overlayBinding as TopRightOverlayBinding).arrow.layoutParams
+ val arrowParams = (overlayBinding as TopRightOverlayBinding).spotlightOverlayArrow.layoutParams
as ViewGroup.MarginLayoutParams
if (isRtl) {
arrowParams.setMargins(
@@ -338,7 +338,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
}
- (overlayBinding as TopRightOverlayBinding).arrow.layoutParams = arrowParams
+ (overlayBinding as TopRightOverlayBinding).spotlightOverlayArrow.layoutParams = arrowParams
return (overlayBinding as TopRightOverlayBinding).root
}
@@ -350,7 +350,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
(overlayBinding as TopLeftOverlayBinding).customText.text = spotlightTarget.hint
- val arrowParams = (overlayBinding as TopLeftOverlayBinding).arrow.layoutParams
+ val arrowParams = (overlayBinding as TopLeftOverlayBinding).spotlightOverlayArrow.layoutParams
as ViewGroup.MarginLayoutParams
if (isRtl) {
arrowParams.setMargins(
@@ -367,7 +367,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
)
}
- (overlayBinding as TopLeftOverlayBinding).arrow.layoutParams = arrowParams
+ (overlayBinding as TopLeftOverlayBinding).spotlightOverlayArrow.layoutParams = arrowParams
return (overlayBinding as TopLeftOverlayBinding).root
}
@@ -388,5 +388,5 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
object BottomLeft : AnchorPosition()
/** The position corresponding to the anchor when it is on the bottom right of the screen. */
object BottomRight : AnchorPosition()
- }s
+ }
}
From 6cff9c912e9e2800dc17912a94a72001d5ce4749 Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Mon, 21 Nov 2022 11:31:17 +0530
Subject: [PATCH 113/138] add requested changes
---
.../player/state/StateFragmentPresenter.kt | 9 +-
.../main/res/layout/bottom_left_overlay.xml | 2 +-
.../main/res/layout/bottom_right_overlay.xml | 2 +-
.../main/res/layout/exploration_activity.xml | 121 +++++++++---------
.../main/res/layout/onboarding_activity.xml | 4 +-
app/src/main/res/layout/top_left_overlay.xml | 2 +-
app/src/main/res/layout/top_right_overlay.xml | 2 +-
app/src/main/res/values/strings.xml | 3 +-
.../app/spotlight/SpotlightFragmentTest.kt | 40 +++++-
.../topic/lessons/TopicLessonsFragmentTest.kt | 5 +-
10 files changed, 110 insertions(+), 80 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 7f234f97a0f..2dd09f26969 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
@@ -513,9 +513,12 @@ class StateFragmentPresenter @Inject constructor(
activity.runPeriodically(delayMillis = 5_000, periodMillis = 30_000) {
return@runPeriodically viewModel.isHintOpenedAndUnRevealed.get()!!.also { playAnim ->
if (playAnim) binding.hintBulb.startAnimation(hintBulbAnimation)
- // The forced announcement should be called after 5 seconds after the hints bar appears
- // otherwise it might interrupt with the submit button's content description during
- // Talkback.
+ // Make a forced announcement when the hint bar becomes visible so that the non sighted
+ // users know about the availability of hints. Instead of suddenly changing the focus of
+ // the app (which is a bad practice) to the hints bar upon availability, make a forced
+ // announcement. The forced announcement should be called after 5 seconds after the
+ // hints bar appears otherwise it might interrupt with the submit button's content
+ // description during Talkback.
if (!forceAnnouncedForHintsBar) {
forceAnnouncedForHintsBar = true
accessibilityService.announceForAccessibilityForView(
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 1748341f702..f5a821ae00a 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -56,7 +56,7 @@
android:onClick="@{(v) -> listener.clickOnDone()}"
android:paddingTop="8dp"
android:paddingBottom="8dp"
- android:text="Done"
+ android:text="@string/mark_spotlight_seen_button_text"
android:textColor="#FFFFFF"
android:textSize="14dp"
app:layout_constraintEnd_toEndOf="parent"
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index 0bbc67a5dd4..168738fa92f 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -56,7 +56,7 @@
android:onClick="@{(v) -> listener.clickOnDone()}"
android:paddingTop="8dp"
android:paddingBottom="8dp"
- android:text="Done"
+ android:text="@string/mark_spotlight_seen_button_text"
android:textColor="#FFFFFF"
android:textSize="14dp"
app:layout_constraintEnd_toEndOf="parent"
diff --git a/app/src/main/res/layout/exploration_activity.xml b/app/src/main/res/layout/exploration_activity.xml
index 83a0d4474df..d5a96beb488 100755
--- a/app/src/main/res/layout/exploration_activity.xml
+++ b/app/src/main/res/layout/exploration_activity.xml
@@ -12,87 +12,82 @@
type="org.oppia.android.app.player.exploration.ExplorationViewModel" />
-
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ tools:context=".player.exploration.ExplorationActivity">
-
-
-
+ android:layout_height="wrap_content"
+ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
-
+ android:background="@color/component_color_exploration_activity_toolbar_color"
+ android:minHeight="?attr/actionBarSize"
+ android:theme="@style/Widget.AppCompat.ActionBar"
+ app:navigationIcon="@drawable/ic_close_white_24dp">
-
+ android:orientation="horizontal">
-
-
-
-
+
-
-
-
-
+
+
+
+
+
+
+ android:layout_height="match_parent" />
-
+
-
-
-
-
+
+
+
diff --git a/app/src/main/res/layout/onboarding_activity.xml b/app/src/main/res/layout/onboarding_activity.xml
index 4171e157e2f..04ecacc8a1a 100644
--- a/app/src/main/res/layout/onboarding_activity.xml
+++ b/app/src/main/res/layout/onboarding_activity.xml
@@ -1,5 +1,5 @@
-
-
+
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index b732d65e937..db48af6f3c0 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -55,7 +55,7 @@
android:onClick="@{(v) -> listener.clickOnDone()}"
android:paddingTop="8dp"
android:paddingBottom="8dp"
- android:text="Done"
+ android:text="@string/mark_spotlight_seen_button_text"
android:textColor="#FFFFFF"
android:textSize="14dp"
app:layout_constraintBottom_toBottomOf="parent"
diff --git a/app/src/main/res/layout/top_right_overlay.xml b/app/src/main/res/layout/top_right_overlay.xml
index ba0ddbea2b8..7bc1d027f4b 100644
--- a/app/src/main/res/layout/top_right_overlay.xml
+++ b/app/src/main/res/layout/top_right_overlay.xml
@@ -53,7 +53,7 @@
android:onClick="@{(v) -> listener.clickOnDone()}"
android:paddingTop="50dp"
android:paddingBottom="8dp"
- android:text="Done"
+ android:text="@string/mark_spotlight_seen_button_text"
android:textColor="#FFFFFF"
android:textSize="14dp"
app:layout_constraintBottom_toBottomOf="parent"
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7f1d59da316..c58d83355a5 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -577,7 +577,7 @@
Practice the concepts learned from completed lessons.
Tap here to start playing a lesson.
Find all your lessons here.
- Revise your lessons here.
+ Revise concepts learned from completed lessons here.
Tap to start a chapter.
Exit anytime using this button. We will save your progress.
Would you like %s to read for you? Tap on this button to try!
@@ -585,4 +585,5 @@
Next
From now, you can see lessons recommended for you here.
Go to the bottom of the screen for a hint.
+ Done
diff --git a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
index 36f6f7b0e93..d7ff2f2152e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
@@ -105,12 +105,12 @@ import javax.inject.Singleton
qualifiers = "port-xxhdpi"
)
class SpotlightFragmentTest {
- @Inject
- lateinit var context: Context
-
@field:[Rule JvmField]
val mockitoRule: MockitoRule = MockitoJUnit.rule()
+ @Inject
+ lateinit var context: Context
+
@Inject
lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
@@ -214,6 +214,40 @@ class SpotlightFragmentTest {
}
}
+ @Test
+ fun testSpotlightFragment_exitSpotlightWithoutClickingDone_checkSpotlightIsShowAgain() {
+ launch(createSpotlightFragmentTestActivity(context)).use {
+ it.onActivity { activity ->
+ val spotlightTarget = SpotlightTarget(
+ activity.getSampleSpotlightTarget(),
+ sampleSpotlightText,
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.PROMOTED_STORIES
+ )
+
+ checkNotNull(activity.getSpotlightFragment()).requestSpotlight(spotlightTarget)
+ testCoroutineDispatchers.runCurrent()
+ }
+ }
+
+ launch(
+ createSpotlightFragmentTestActivity(context)
+ ).use {
+ it.onActivity { activity ->
+ val spotlightTarget = SpotlightTarget(
+ activity.getSampleSpotlightTarget(),
+ sampleSpotlightText,
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.PROMOTED_STORIES
+ )
+
+ checkNotNull(activity.getSpotlightFragment()).requestSpotlight(spotlightTarget)
+ testCoroutineDispatchers.runCurrent()
+ }
+ onView(withText(sampleSpotlightText)).check(matches(isDisplayed()))
+ }
+ }
+
@Test
fun testSpotlightQueuing_requestTwoSpotlights_checkFirstSpotlightShown() {
launch(
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
index b575da5d462..6a4f2578d82 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
@@ -158,16 +158,13 @@ class TopicLessonsFragmentTest {
@Inject lateinit var fakeOppiaClock: FakeOppiaClock
@Inject lateinit var fakeAccessibilityService: FakeAccessibilityService
@Inject lateinit var spotlightStateController: SpotlightStateController
-
- @Inject
- lateinit var explorationCheckpointTestHelper: ExplorationCheckpointTestHelper
+ @Inject lateinit var explorationCheckpointTestHelper: ExplorationCheckpointTestHelper
@Inject lateinit var fakeExplorationRetriever: FakeExplorationRetriever
@field:[Inject EnableExtraTopicTabsUi]
lateinit var enableExtraTopicTabsUiValue: PlatformParameterValue
private val internalProfileId = 0
-
private lateinit var profileId: ProfileId
@Before
From 4fbe97ecac8b49a29d136ca401dc42f9027cee21 Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Mon, 21 Nov 2022 12:53:28 +0530
Subject: [PATCH 114/138] more fixes
---
.../org/oppia/android/app/spotlight/SpotlightFragment.kt | 5 ++---
...int_background.xml => spotlight_hint_text_background.xml} | 0
app/src/main/res/layout/bottom_left_overlay.xml | 2 +-
app/src/main/res/layout/bottom_right_overlay.xml | 2 +-
app/src/main/res/layout/spotlight_fragment_test_activity.xml | 2 +-
app/src/main/res/layout/top_left_overlay.xml | 2 +-
app/src/main/res/layout/top_right_overlay.xml | 2 +-
app/src/main/res/values/colors_migrating.xml | 2 +-
8 files changed, 8 insertions(+), 9 deletions(-)
rename app/src/main/res/drawable/{spotlight_overlay_hint_background.xml => spotlight_hint_text_background.xml} (100%)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 5716e399436..46cfc1f11be 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -2,7 +2,6 @@ package org.oppia.android.app.spotlight
import android.content.Context
import android.util.DisplayMetrics
-import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.view.animation.DecelerateInterpolator
@@ -13,10 +12,10 @@ import androidx.lifecycle.Observer
import com.takusemba.spotlight.OnSpotlightListener
import com.takusemba.spotlight.OnTargetListener
import com.takusemba.spotlight.Spotlight
-import com.takusemba.spotlight.Target
import com.takusemba.spotlight.shape.Circle
import com.takusemba.spotlight.shape.RoundedRectangle
import com.takusemba.spotlight.shape.Shape
+import com.takusemba.spotlight.Target
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentComponentImpl
import org.oppia.android.app.fragment.InjectableFragment
@@ -152,7 +151,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
if (targetList.isNullOrEmpty()) return
spotlight = Spotlight.Builder(activity)
.setTargets(targetList)
- .setBackgroundColorRes(R.color.spotlightBackground)
+ .setBackgroundColorRes(R.color.spotlight_overlay_background)
.setDuration(1000L)
.setAnimation(DecelerateInterpolator(2f))
.setOnSpotlightListener(object : OnSpotlightListener {
diff --git a/app/src/main/res/drawable/spotlight_overlay_hint_background.xml b/app/src/main/res/drawable/spotlight_hint_text_background.xml
similarity index 100%
rename from app/src/main/res/drawable/spotlight_overlay_hint_background.xml
rename to app/src/main/res/drawable/spotlight_hint_text_background.xml
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index f5a821ae00a..e5d90745858 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -32,7 +32,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="10dp"
- android:background="@drawable/spotlight_overlay_hint_background"
+ android:background="@drawable/spotlight_hint_text_background"
android:paddingStart="8dp"
android:paddingTop="4dp"
android:paddingEnd="4dp"
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index 168738fa92f..4075516325c 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -32,7 +32,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
- android:background="@drawable/spotlight_overlay_hint_background"
+ android:background="@drawable/spotlight_hint_text_background"
android:paddingStart="8dp"
android:paddingTop="4dp"
android:paddingEnd="4dp"
diff --git a/app/src/main/res/layout/spotlight_fragment_test_activity.xml b/app/src/main/res/layout/spotlight_fragment_test_activity.xml
index 4ef5945233a..37125d9d9ee 100644
--- a/app/src/main/res/layout/spotlight_fragment_test_activity.xml
+++ b/app/src/main/res/layout/spotlight_fragment_test_activity.xml
@@ -22,4 +22,4 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
-
\ No newline at end of file
+
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index db48af6f3c0..253d9639b80 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -31,7 +31,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
- android:background="@drawable/spotlight_overlay_hint_background"
+ android:background="@drawable/spotlight_hint_text_background"
android:paddingStart="8dp"
android:paddingTop="4dp"
android:paddingEnd="4dp"
diff --git a/app/src/main/res/layout/top_right_overlay.xml b/app/src/main/res/layout/top_right_overlay.xml
index 7bc1d027f4b..8add590cd1b 100644
--- a/app/src/main/res/layout/top_right_overlay.xml
+++ b/app/src/main/res/layout/top_right_overlay.xml
@@ -31,7 +31,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
- android:background="@drawable/spotlight_overlay_hint_background"
+ android:background="@drawable/spotlight_hint_text_background"
android:paddingStart="8dp"
android:paddingTop="4dp"
android:paddingEnd="4dp"
diff --git a/app/src/main/res/values/colors_migrating.xml b/app/src/main/res/values/colors_migrating.xml
index b7d18df5125..dbddbe08317 100644
--- a/app/src/main/res/values/colors_migrating.xml
+++ b/app/src/main/res/values/colors_migrating.xml
@@ -112,7 +112,7 @@
#A5D3EC
#674172
#7659B6
- #BF000000
+ #BF000000
#FFFFF0
From 2bfafc3f1dff61569966768b207edf5fa22227cd Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Mon, 21 Nov 2022 17:20:32 +0530
Subject: [PATCH 115/138] more fixes
---
.../android/app/home/HomeActivityPresenter.kt | 7 ++---
.../onboarding/OnboardingActivityPresenter.kt | 7 ++---
.../ExplorationActivityPresenter.kt | 7 ++---
.../app/spotlight/SpotlightFragment.kt | 19 +++++++++++++-
.../app/topic/TopicActivityPresenter.kt | 7 ++---
.../app/topic/TopicFragmentPresenter.kt | 1 +
.../main/res/layout/bottom_left_overlay.xml | 22 +++++++---------
.../main/res/layout/bottom_right_overlay.xml | 23 +++++++---------
app/src/main/res/layout/home_activity.xml | 2 +-
app/src/main/res/layout/top_left_overlay.xml | 19 ++++++--------
app/src/main/res/layout/top_right_overlay.xml | 17 ++++++------
app/src/main/res/layout/topic_activity.xml | 10 +++----
.../app/spotlight/SpotlightFragmentTest.kt | 26 +++++++++++++++++--
.../PlatformParameterAlphaKenyaModule.kt | 10 +++++++
.../TestPlatformParameterModule.kt | 17 ++++++++++++
15 files changed, 119 insertions(+), 75 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
index 22db68591ae..31d5e7c5e63 100644
--- a/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
@@ -32,13 +32,10 @@ class HomeActivityPresenter @Inject constructor(private val activity: AppCompatA
}
if (getSpotlightFragment() == null) {
- val spotlightFragment = SpotlightFragment()
- val args = Bundle()
- args.putInt(PROFILE_ID_ARGUMENT_KEY, internalProfileId)
- spotlightFragment.arguments = args
activity.supportFragmentManager.beginTransaction().add(
R.id.home_spotlight_fragment_placeholder,
- spotlightFragment, SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
+ SpotlightFragment.newInstance(internalProfileId),
+ SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
).commitNow()
}
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
index 9bf39fda627..07240a522de 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
@@ -22,13 +22,10 @@ class OnboardingActivityPresenter @Inject constructor(private val activity: AppC
}
if (getSpotlightFragment() == null) {
- val spotlightFragment = SpotlightFragment()
- val args = Bundle()
- args.putInt(PROFILE_ID_ARGUMENT_KEY, -1)
- spotlightFragment.arguments = args
activity.supportFragmentManager.beginTransaction().add(
R.id.onboarding_spotlight_fragment_placeholder,
- spotlightFragment, SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
+ SpotlightFragment.newInstance(internalProfileId = 0),
+ SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
).commitNow()
}
}
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
index 0ef4379aab4..da82fb71db8 100644
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
@@ -136,13 +136,10 @@ class ExplorationActivityPresenter @Inject constructor(
}
if (getSpotlightFragment() == null) {
- val spotlightFragment = SpotlightFragment()
- val args = Bundle()
- args.putInt(PROFILE_ID_ARGUMENT_KEY, profileId.internalId)
- spotlightFragment.arguments = args
activity.supportFragmentManager.beginTransaction().add(
R.id.exploration_spotlight_fragment_placeholder,
- spotlightFragment, SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
+ SpotlightFragment.newInstance(profileId.internalId),
+ SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
).commitNow()
}
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 46cfc1f11be..69b246f6b56 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -1,6 +1,7 @@
package org.oppia.android.app.spotlight
import android.content.Context
+import android.os.Bundle
import android.util.DisplayMetrics
import android.view.View
import android.view.ViewGroup
@@ -33,6 +34,8 @@ import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import java.util.LinkedList
import javax.inject.Inject
+import org.oppia.android.util.platformparameter.EnableSpotlightUi
+import org.oppia.android.util.platformparameter.PlatformParameterValue
/**
* Fragment to hold spotlights on elements. This fragment provides a single place for all the
@@ -52,6 +55,9 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
@Inject
lateinit var resourceHandler: AppLanguageResourceHandler
+ @field:[Inject EnableSpotlightUi]
+ lateinit var enableSpotlightUi: PlatformParameterValue
+
private var targetList = LinkedList()
private lateinit var spotlight: Spotlight
private var screenHeight: Int = 0
@@ -95,7 +101,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
override fun requestSpotlight(spotlightTarget: SpotlightTarget) {
// When Talkback is turned on, do not show spotlights since they are visual tools and can
// potentially make the app experience difficult for a non-sighted user.
- if (accessibilityService.isScreenReaderEnabled()) return
+ if (accessibilityService.isScreenReaderEnabled() || !enableSpotlightUi.value) return
val profileId = ProfileId.newBuilder()
.setInternalId(internalProfileId)
.build()
@@ -388,4 +394,15 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
/** The position corresponding to the anchor when it is on the bottom right of the screen. */
object BottomRight : AnchorPosition()
}
+
+ companion object {
+ /* Returns a new [SpotlightFragment]. */
+ fun newInstance(internalProfileId: Int): SpotlightFragment {
+ val spotlightFragment = SpotlightFragment()
+ val args = Bundle()
+ args.putInt(PROFILE_ID_ARGUMENT_KEY, internalProfileId)
+ spotlightFragment.arguments = args
+ return spotlightFragment
+ }
+ }
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
index daf782d3c31..6470a5cdbac 100755
--- a/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicActivityPresenter.kt
@@ -41,13 +41,10 @@ class TopicActivityPresenter @Inject constructor(private val activity: AppCompat
}
if (getSpotlightFragment() == null) {
- val spotlightFragment = SpotlightFragment()
- val args = Bundle()
- args.putInt(PROFILE_ID_ARGUMENT_KEY, internalProfileId)
- spotlightFragment.arguments = args
activity.supportFragmentManager.beginTransaction().add(
R.id.topic_spotlight_fragment_placeholder,
- spotlightFragment, SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
+ SpotlightFragment.newInstance(internalProfileId),
+ SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
).commitNow()
}
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 616cd8ebf37..fb81233a558 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -75,6 +75,7 @@ class TopicFragmentPresenter @Inject constructor(
return binding.root
}
+ /* Requests the spotlights required in this activity to be enqueued. */
fun startSpotlight() {
viewModel.numberOfChaptersCompletedLiveData.observe(fragment) { numberOfChaptersCompleted ->
if (numberOfChaptersCompleted != null) {
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index e5d90745858..6357018c05c 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -42,24 +42,20 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/spotlight_overlay_arrow" />
-
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index 4075516325c..b340a2625a3 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -3,6 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
+
@@ -42,24 +43,20 @@
app:layout_constraintEnd_toEndOf="@+id/spotlight_overlay_arrow"
app:layout_constraintStart_toStartOf="parent" />
-
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
diff --git a/app/src/main/res/layout/home_activity.xml b/app/src/main/res/layout/home_activity.xml
index bda4e73f395..70e9572b8ec 100644
--- a/app/src/main/res/layout/home_activity.xml
+++ b/app/src/main/res/layout/home_activity.xml
@@ -9,7 +9,7 @@
+ android:layout_height="match_parent" />
+
@@ -41,23 +42,19 @@
app:layout_constraintStart_toStartOf="@id/spotlight_overlay_arrow"
app:layout_constraintTop_toBottomOf="@id/spotlight_overlay_arrow" />
-
diff --git a/app/src/main/res/layout/top_right_overlay.xml b/app/src/main/res/layout/top_right_overlay.xml
index 8add590cd1b..2ede6e574c5 100644
--- a/app/src/main/res/layout/top_right_overlay.xml
+++ b/app/src/main/res/layout/top_right_overlay.xml
@@ -3,6 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
+
@@ -41,21 +42,19 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/spotlight_overlay_arrow" />
-
diff --git a/app/src/main/res/layout/topic_activity.xml b/app/src/main/res/layout/topic_activity.xml
index 1a1475ad4ff..a0d3f6eeff8 100644
--- a/app/src/main/res/layout/topic_activity.xml
+++ b/app/src/main/res/layout/topic_activity.xml
@@ -2,15 +2,15 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context=".app.topic.TopicActivity" >
+ tools:context=".app.topic.TopicActivity">
+ android:layout_height="match_parent" />
+ android:layout_height="match_parent" />
diff --git a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
index d7ff2f2152e..42bd551b504 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
@@ -67,7 +67,6 @@ import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
import org.oppia.android.domain.oppialogger.analytics.CpuPerformanceSnapshotterModule
import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
-import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
@@ -92,6 +91,7 @@ import org.oppia.android.util.networking.NetworkConnectionDebugUtilModule
import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule
import org.oppia.android.util.parser.image.ImageParsingModule
+import org.oppia.android.testing.platformparameter.TestPlatformParameterModule
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
import javax.inject.Inject
@@ -137,6 +137,28 @@ class SpotlightFragmentTest {
testCoroutineDispatchers.unregisterIdlingResource()
}
+ @Test
+ fun testSpotlightFragment_disableSpotlights_requestSpotlight_shouldNotShowSpotlight() {
+ TestPlatformParameterModule.forceEnableSpotlightUi(false)
+ launch(
+ createSpotlightFragmentTestActivity(context)
+ ).use {
+ testCoroutineDispatchers.runCurrent()
+ it.onActivity { activity ->
+ val spotlightTarget = SpotlightTarget(
+ activity.getSampleSpotlightTarget(),
+ sampleSpotlightText,
+ SpotlightShape.RoundedRectangle,
+ Spotlight.FeatureCase.PROMOTED_STORIES
+ )
+
+ checkNotNull(activity.getSpotlightFragment()).requestSpotlight(spotlightTarget)
+ testCoroutineDispatchers.runCurrent()
+ }
+ onView(withText(sampleSpotlightText)).check(doesNotExist()bot)
+ }
+ }
+
@Test
fun testSpotlightFragment_requestSpotlight_shouldShowSpotlight() {
launch(
@@ -319,7 +341,7 @@ class SpotlightFragmentTest {
@Component(
modules = [
RobolectricModule::class,
- PlatformParameterModule::class, PlatformParameterSingletonModule::class,
+ TestPlatformParameterModule::class, PlatformParameterSingletonModule::class,
TestDispatcherModule::class, ApplicationModule::class,
LoggerModule::class, ContinueModule::class, FractionInputModule::class,
ItemSelectionInputModule::class, MultipleChoiceInputModule::class,
diff --git a/domain/src/main/java/org/oppia/android/domain/platformparameter/PlatformParameterAlphaKenyaModule.kt b/domain/src/main/java/org/oppia/android/domain/platformparameter/PlatformParameterAlphaKenyaModule.kt
index 893057855a3..17ee639b3d7 100644
--- a/domain/src/main/java/org/oppia/android/domain/platformparameter/PlatformParameterAlphaKenyaModule.kt
+++ b/domain/src/main/java/org/oppia/android/domain/platformparameter/PlatformParameterAlphaKenyaModule.kt
@@ -13,6 +13,7 @@ import org.oppia.android.util.platformparameter.ENABLE_INTERACTION_CONFIG_CHANGE
import org.oppia.android.util.platformparameter.ENABLE_LANGUAGE_SELECTION_UI_DEFAULT_VALUE
import org.oppia.android.util.platformparameter.ENABLE_PERFORMANCE_METRICS_COLLECTION
import org.oppia.android.util.platformparameter.ENABLE_PERFORMANCE_METRICS_COLLECTION_DEFAULT_VALUE
+import org.oppia.android.util.platformparameter.ENABLE_SPOTLIGHT_UI_DEFAULT_VALUE
import org.oppia.android.util.platformparameter.EnableContinueButtonAnimation
import org.oppia.android.util.platformparameter.EnableDownloadsSupport
import org.oppia.android.util.platformparameter.EnableEditAccountsOptionsUi
@@ -20,6 +21,7 @@ import org.oppia.android.util.platformparameter.EnableExtraTopicTabsUi
import org.oppia.android.util.platformparameter.EnableInteractionConfigChangeStateRetention
import org.oppia.android.util.platformparameter.EnableLanguageSelectionUi
import org.oppia.android.util.platformparameter.EnablePerformanceMetricsCollection
+import org.oppia.android.util.platformparameter.EnableSpotlightUi
import org.oppia.android.util.platformparameter.LEARNER_STUDY_ANALYTICS
import org.oppia.android.util.platformparameter.LearnerStudyAnalytics
import org.oppia.android.util.platformparameter.PERFORMANCE_METRICS_COLLECTION_HIGH_FREQUENCY_TIME_INTERVAL_IN_MINUTES
@@ -179,4 +181,12 @@ class PlatformParameterAlphaKenyaModule {
ENABLE_CONTINUE_BUTTON_ANIMATION_DEFAULT_VALUE
)
}
+
+ @Provides
+ @EnableSpotlightUi
+ fun enableSpotlightUi(): PlatformParameterValue {
+ return PlatformParameterValue.createDefaultParameter(
+ ENABLE_SPOTLIGHT_UI_DEFAULT_VALUE
+ )
+ }
}
diff --git a/testing/src/main/java/org/oppia/android/testing/platformparameter/TestPlatformParameterModule.kt b/testing/src/main/java/org/oppia/android/testing/platformparameter/TestPlatformParameterModule.kt
index 0a75382474b..d6f52281821 100644
--- a/testing/src/main/java/org/oppia/android/testing/platformparameter/TestPlatformParameterModule.kt
+++ b/testing/src/main/java/org/oppia/android/testing/platformparameter/TestPlatformParameterModule.kt
@@ -40,6 +40,8 @@ import org.oppia.android.util.platformparameter.SYNC_UP_WORKER_TIME_PERIOD_IN_HO
import org.oppia.android.util.platformparameter.SplashScreenWelcomeMsg
import org.oppia.android.util.platformparameter.SyncUpWorkerTimePeriodHours
import javax.inject.Singleton
+import org.oppia.android.util.platformparameter.ENABLE_SPOTLIGHT_UI_DEFAULT_VALUE
+import org.oppia.android.util.platformparameter.EnableSpotlightUi
/* Fake Platform Parameter Module that provides individual Platform Parameters for testing. */
@Module
@@ -184,6 +186,14 @@ class TestPlatformParameterModule {
)
}
+ @Provides
+ @EnableSpotlightUi
+ fun provideEnableSpotlightUi(): PlatformParameterValue {
+ return PlatformParameterValue.createDefaultParameter(
+ enableSpotlightUi
+ )
+ }
+
companion object {
private var enableDownloadsSupport = ENABLE_DOWNLOADS_SUPPORT_DEFAULT_VALUE
private var enableLanguageSelectionUi = ENABLE_LANGUAGE_SELECTION_UI_DEFAULT_VALUE
@@ -194,6 +204,7 @@ class TestPlatformParameterModule {
ENABLE_INTERACTION_CONFIG_CHANGE_STATE_RETENTION_DEFAULT_VALUE
private var enablePerformanceMetricsCollection =
ENABLE_PERFORMANCE_METRICS_COLLECTION_DEFAULT_VALUE
+ private var enableSpotlightUi = ENABLE_SPOTLIGHT_UI_DEFAULT_VALUE
/** Enables forcing [EnableLanguageSelectionUi] platform parameter flag from tests. */
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
@@ -244,6 +255,12 @@ class TestPlatformParameterModule {
enableContinueButtonAnimation = value
}
+ /** Enables forcing [EnableSpotlightUi] platform parameter flag from tests. */
+ @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+ fun forceEnableSpotlightUi(value: Boolean) {
+ enableSpotlightUi = value
+ }
+
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
fun reset() {
enableDownloadsSupport = ENABLE_DOWNLOADS_SUPPORT_DEFAULT_VALUE
From 5826fa1dcb594113e25ee1d01f03cc1c9f55a8fe Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Mon, 21 Nov 2022 17:21:13 +0530
Subject: [PATCH 116/138] more fixes
---
.../org/oppia/android/app/spotlight/SpotlightFragmentTest.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
index 42bd551b504..f704391e827 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
@@ -155,7 +155,7 @@ class SpotlightFragmentTest {
checkNotNull(activity.getSpotlightFragment()).requestSpotlight(spotlightTarget)
testCoroutineDispatchers.runCurrent()
}
- onView(withText(sampleSpotlightText)).check(doesNotExist()bot)
+ onView(withText(sampleSpotlightText)).check(doesNotExist())
}
}
From 6ea3cb01c42fe841c8bb12bf066a8c5488f83008 Mon Sep 17 00:00:00 2001
From: Ben Henning
Date: Mon, 21 Nov 2022 03:53:20 -0800
Subject: [PATCH 117/138] Fix broken ExplorationActivityTest tests.
---
.../ExplorationActivityPresenter.kt | 32 +++++++++++--------
.../app/spotlight/SpotlightFragment.kt | 3 --
.../exploration/ExplorationActivityTest.kt | 4 +--
3 files changed, 21 insertions(+), 18 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
index 0ef4379aab4..698672b41ea 100644
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
@@ -2,10 +2,12 @@ package org.oppia.android.app.player.exploration
import android.content.Context
import android.os.Bundle
+import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
+import androidx.core.view.doOnPreDraw
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
@@ -149,19 +151,23 @@ class ExplorationActivityPresenter @Inject constructor(
fun requestVoiceOverIconSpotlight(numberOfLogins: Int) {
if (numberOfLogins >= 3) {
- // Spotlight the voice-over icon after 3 or more logins.
- val audioPlayerSpotlightTarget = SpotlightTarget(
- binding.actionAudioPlayer,
- resourceHandler.getStringInLocaleWithWrapping(
- R.string.voiceover_icon_spotlight_hint,
- resourceHandler.getStringInLocale(R.string.app_name)
- ),
- SpotlightShape.Circle,
- Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
- )
- checkNotNull(getSpotlightFragment()).requestSpotlightViewWithDelayedLayout(
- audioPlayerSpotlightTarget
- )
+ // Spotlight the voice-over icon after 3 or more logins, and only if it's visible. Note that
+ // the doOnPreDraw here ensures that the visibility check for the button is up-to-date before
+ // a decision is made on whether to show the button.
+ binding.actionAudioPlayer.doOnPreDraw {
+ if (it.visibility == View.VISIBLE) {
+ val audioPlayerSpotlightTarget = SpotlightTarget(
+ it,
+ resourceHandler.getStringInLocaleWithWrapping(
+ R.string.voiceover_icon_spotlight_hint,
+ resourceHandler.getStringInLocale(R.string.app_name)
+ ),
+ SpotlightShape.Circle,
+ Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
+ )
+ checkNotNull(getSpotlightFragment()).requestSpotlight(audioPlayerSpotlightTarget)
+ }
+ }
}
}
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 46cfc1f11be..aeb7e9a1c5c 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -77,9 +77,6 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
// and positions of the anchor view are measured, which can be achieved by using doOnPreDraw:
// https://betterprogramming.pub/stop-using-post-postdelayed-in-your-android-views-9d1c8eeaadf2
spotlightTarget.anchor.doOnPreDraw {
- if (it.visibility != View.VISIBLE) {
- return@doOnPreDraw
- }
val targetAfterViewFullyDrawn = SpotlightTarget(
it,
spotlightTarget.hint,
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
index d49e9bdfe04..923baa63d2a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
@@ -587,7 +587,7 @@ class ExplorationActivityTest {
)
testCoroutineDispatchers.runCurrent()
- onView(withText(context.getString(R.string.voiceover_icon_spotlight_hint, R.string.app_name)))
+ onView(withText("Would you like Oppia to read for you? Tap on this button to try!"))
.check(matches(isDisplayed()))
}
}
@@ -633,7 +633,7 @@ class ExplorationActivityTest {
)
testCoroutineDispatchers.runCurrent()
- onView(withText(context.getString(R.string.voiceover_icon_spotlight_hint, R.string.app_name)))
+ onView(withText("Would you like Oppia to read for you? Tap on this button to try!"))
.check(doesNotExist())
}
}
From 344e34e1aa9131f077ce8d041f2ce7b17f345883 Mon Sep 17 00:00:00 2001
From: Ben Henning
Date: Mon, 21 Nov 2022 03:54:53 -0800
Subject: [PATCH 118/138] Revert "Revert "Fix #4746: Update app to target SDK
31 (#4747)""
This reverts commit 912c357300f408f73a2aa4d6e94727c6605d9cdb.
---
.../action.yml | 4 ++--
BUILD.bazel | 4 ++--
WORKSPACE | 2 +-
app/build.gradle | 4 ++--
app/src/main/AppAndroidManifest.xml | 2 +-
app/src/main/DatabindingAdaptersManifest.xml | 2 +-
app/src/main/DatabindingResourcesManifest.xml | 2 +-
app/src/main/RecyclerviewAdaptersManifest.xml | 2 +-
app/src/main/ViewModelManifest.xml | 2 +-
app/src/main/ViewModelsManifest.xml | 2 +-
app/src/main/ViewsManifest.xml | 2 +-
build_flavors.bzl | 14 +++++++-------
.../org/oppia/android/config/AndroidManifest.xml | 2 +-
data/build.gradle | 4 ++--
data/src/test/AndroidManifest.xml | 2 +-
domain/build.gradle | 4 ++--
domain/src/main/AndroidManifest.xml | 2 +-
instrumentation/BUILD.bazel | 2 +-
testing/build.gradle | 4 ++--
testing/src/test/AndroidManifest.xml | 2 +-
utility/build.gradle | 4 ++--
utility/src/main/AndroidManifest.xml | 2 +-
22 files changed, 35 insertions(+), 35 deletions(-)
diff --git a/.github/actions/set-up-android-bazel-build-environment/action.yml b/.github/actions/set-up-android-bazel-build-environment/action.yml
index 836e327828b..6b3f5cf1155 100644
--- a/.github/actions/set-up-android-bazel-build-environment/action.yml
+++ b/.github/actions/set-up-android-bazel-build-environment/action.yml
@@ -72,9 +72,9 @@ runs:
$ANDROID_HOME/cmdline-tools/tools/bin/sdkmanager --install "platform-tools"
shell: bash
- - name: Install SDK 30
+ - name: Install SDK 31
run: |
- $ANDROID_HOME/cmdline-tools/tools/bin/sdkmanager --install "platforms;android-30"
+ $ANDROID_HOME/cmdline-tools/tools/bin/sdkmanager --install "platforms;android-31"
shell: bash
- name: Install build tools 29.0.2
diff --git a/BUILD.bazel b/BUILD.bazel
index 81250077b03..5177d895f27 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -117,14 +117,14 @@ package_group(
"flavor": "oppia",
"min_sdk_version": 21,
"multidex": "native",
- "target_sdk_version": 30,
+ "target_sdk_version": 31,
},
{
"flavor": "oppia_kitkat",
"main_dex_list": "//:config/kitkat_main_dex_class_list.txt",
"min_sdk_version": 19,
"multidex": "manual_main_dex",
- "target_sdk_version": 30,
+ "target_sdk_version": 31,
},
]
]
diff --git a/WORKSPACE b/WORKSPACE
index 17ac191b294..c6c1f09af5f 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -11,7 +11,7 @@ load("//third_party:versions.bzl", "HTTP_DEPENDENCY_VERSIONS", "get_maven_depend
# TODO(#1542): Sync Android SDK version with the manifest.
android_sdk_repository(
name = "androidsdk",
- api_level = 30,
+ api_level = 31,
build_tools_version = "29.0.2",
)
diff --git a/app/build.gradle b/app/build.gradle
index 7210225d4e2..63ee7549c26 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -6,12 +6,12 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
- compileSdkVersion 30
+ compileSdkVersion 31
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "org.oppia.android"
minSdkVersion 19
- targetSdkVersion 30
+ targetSdkVersion 31
versionCode 1
versionName "1.0"
multiDexEnabled true
diff --git a/app/src/main/AppAndroidManifest.xml b/app/src/main/AppAndroidManifest.xml
index 1c8f666190e..9a5789e1872 100644
--- a/app/src/main/AppAndroidManifest.xml
+++ b/app/src/main/AppAndroidManifest.xml
@@ -1,5 +1,5 @@
+ android:targetSdkVersion="31" />
diff --git a/app/src/main/DatabindingAdaptersManifest.xml b/app/src/main/DatabindingAdaptersManifest.xml
index 1ce9e10c160..0974b6b3aa6 100644
--- a/app/src/main/DatabindingAdaptersManifest.xml
+++ b/app/src/main/DatabindingAdaptersManifest.xml
@@ -1,5 +1,5 @@
+ android:targetSdkVersion="31" />
diff --git a/app/src/main/DatabindingResourcesManifest.xml b/app/src/main/DatabindingResourcesManifest.xml
index 9b1e93c2052..0c3dd8fa35a 100644
--- a/app/src/main/DatabindingResourcesManifest.xml
+++ b/app/src/main/DatabindingResourcesManifest.xml
@@ -1,5 +1,5 @@
+ android:targetSdkVersion="31" />
diff --git a/app/src/main/RecyclerviewAdaptersManifest.xml b/app/src/main/RecyclerviewAdaptersManifest.xml
index f20e30062f0..f2a3273e765 100644
--- a/app/src/main/RecyclerviewAdaptersManifest.xml
+++ b/app/src/main/RecyclerviewAdaptersManifest.xml
@@ -1,5 +1,5 @@
+ android:targetSdkVersion="31" />
diff --git a/app/src/main/ViewModelManifest.xml b/app/src/main/ViewModelManifest.xml
index fa31c60ce75..07603e895d8 100644
--- a/app/src/main/ViewModelManifest.xml
+++ b/app/src/main/ViewModelManifest.xml
@@ -3,5 +3,5 @@
+ android:targetSdkVersion="31" />
diff --git a/app/src/main/ViewModelsManifest.xml b/app/src/main/ViewModelsManifest.xml
index c44690d380c..84693784fd8 100644
--- a/app/src/main/ViewModelsManifest.xml
+++ b/app/src/main/ViewModelsManifest.xml
@@ -3,5 +3,5 @@
+ android:targetSdkVersion="31" />
diff --git a/app/src/main/ViewsManifest.xml b/app/src/main/ViewsManifest.xml
index 10b8d0ef41f..340e35afe29 100644
--- a/app/src/main/ViewsManifest.xml
+++ b/app/src/main/ViewsManifest.xml
@@ -3,5 +3,5 @@
+ android:targetSdkVersion="31" />
diff --git a/build_flavors.bzl b/build_flavors.bzl
index 55aec211b65..e141ba1e702 100644
--- a/build_flavors.bzl
+++ b/build_flavors.bzl
@@ -46,7 +46,7 @@ _FLAVOR_METADATA = {
"dev": {
"manifest": "//app:src/main/AndroidManifest.xml",
"min_sdk_version": 21,
- "target_sdk_version": 30,
+ "target_sdk_version": 31,
"multidex": "native",
"proguard_specs": [], # Developer builds are not optimized.
"production_release": False,
@@ -60,7 +60,7 @@ _FLAVOR_METADATA = {
"dev_kitkat": {
"manifest": "//app:src/main/AndroidManifest.xml",
"min_sdk_version": 19,
- "target_sdk_version": 30,
+ "target_sdk_version": 31,
"multidex": "manual_main_dex",
"main_dex_list": _MAIN_DEX_LIST_TARGET_KITKAT,
"proguard_specs": [], # Developer builds are not optimized.
@@ -75,7 +75,7 @@ _FLAVOR_METADATA = {
"alpha": {
"manifest": "//app:src/main/AndroidManifest.xml",
"min_sdk_version": 21,
- "target_sdk_version": 30,
+ "target_sdk_version": 31,
"multidex": "native",
"proguard_specs": _PRODUCTION_PROGUARD_SPECS,
"production_release": True,
@@ -89,7 +89,7 @@ _FLAVOR_METADATA = {
"alpha_kitkat": {
"manifest": "//app:src/main/AndroidManifest.xml",
"min_sdk_version": 19,
- "target_sdk_version": 30,
+ "target_sdk_version": 31,
"multidex": "manual_main_dex",
"main_dex_list": _MAIN_DEX_LIST_TARGET_KITKAT,
"proguard_specs": [], # TODO(#3886): Re-add Proguard support to alpha_kitkat.
@@ -104,7 +104,7 @@ _FLAVOR_METADATA = {
"alpha_kenya": {
"manifest": "//app:src/main/AndroidManifest.xml",
"min_sdk_version": 21,
- "target_sdk_version": 30,
+ "target_sdk_version": 31,
"multidex": "native",
"proguard_specs": _PRODUCTION_PROGUARD_SPECS,
"production_release": True,
@@ -118,7 +118,7 @@ _FLAVOR_METADATA = {
"beta": {
"manifest": "//app:src/main/AndroidManifest.xml",
"min_sdk_version": 21,
- "target_sdk_version": 30,
+ "target_sdk_version": 31,
"multidex": "native",
"proguard_specs": _PRODUCTION_PROGUARD_SPECS,
"production_release": True,
@@ -132,7 +132,7 @@ _FLAVOR_METADATA = {
"ga": {
"manifest": "//app:src/main/AndroidManifest.xml",
"min_sdk_version": 21,
- "target_sdk_version": 30,
+ "target_sdk_version": 31,
"multidex": "native",
"proguard_specs": _PRODUCTION_PROGUARD_SPECS,
"production_release": True,
diff --git a/config/src/java/org/oppia/android/config/AndroidManifest.xml b/config/src/java/org/oppia/android/config/AndroidManifest.xml
index e1c019cb70c..1d3f57544f1 100644
--- a/config/src/java/org/oppia/android/config/AndroidManifest.xml
+++ b/config/src/java/org/oppia/android/config/AndroidManifest.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/data/build.gradle b/data/build.gradle
index b90bcc469fc..d51015b8c24 100644
--- a/data/build.gradle
+++ b/data/build.gradle
@@ -4,12 +4,12 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
- compileSdkVersion 30
+ compileSdkVersion 31
buildToolsVersion "29.0.2"
defaultConfig {
minSdkVersion 19
- targetSdkVersion 30
+ targetSdkVersion 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
diff --git a/data/src/test/AndroidManifest.xml b/data/src/test/AndroidManifest.xml
index 5fd4f17f291..2078d324983 100644
--- a/data/src/test/AndroidManifest.xml
+++ b/data/src/test/AndroidManifest.xml
@@ -1,5 +1,5 @@
+ android:targetSdkVersion="30" />
diff --git a/domain/build.gradle b/domain/build.gradle
index 861ea4ae207..b0e246d6e27 100644
--- a/domain/build.gradle
+++ b/domain/build.gradle
@@ -4,12 +4,12 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
- compileSdkVersion 30
+ compileSdkVersion 31
buildToolsVersion "29.0.2"
defaultConfig {
minSdkVersion 19
- targetSdkVersion 30
+ targetSdkVersion 31
versionCode 1
versionName "1.0"
javaCompileOptions {
diff --git a/domain/src/main/AndroidManifest.xml b/domain/src/main/AndroidManifest.xml
index 9cdbbca1e9e..483a96cc057 100644
--- a/domain/src/main/AndroidManifest.xml
+++ b/domain/src/main/AndroidManifest.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/instrumentation/BUILD.bazel b/instrumentation/BUILD.bazel
index 528eec6a433..22a68271e54 100644
--- a/instrumentation/BUILD.bazel
+++ b/instrumentation/BUILD.bazel
@@ -18,7 +18,7 @@ android_binary(
manifest_values = {
"applicationId": "org.oppia.android",
"minSdkVersion": "19",
- "targetSdkVersion": "30",
+ "targetSdkVersion": "31",
"versionCode": "0",
"versionName": "0.1-test",
},
diff --git a/testing/build.gradle b/testing/build.gradle
index 25123a4dd84..9e502acee95 100644
--- a/testing/build.gradle
+++ b/testing/build.gradle
@@ -4,12 +4,12 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
- compileSdkVersion 30
+ compileSdkVersion 31
buildToolsVersion "29.0.2"
defaultConfig {
minSdkVersion 19
- targetSdkVersion 30
+ targetSdkVersion 31
versionCode 1
versionName "1.0"
}
diff --git a/testing/src/test/AndroidManifest.xml b/testing/src/test/AndroidManifest.xml
index be2a6519fab..4682f548b88 100644
--- a/testing/src/test/AndroidManifest.xml
+++ b/testing/src/test/AndroidManifest.xml
@@ -1,5 +1,5 @@
+ android:targetSdkVersion="30" />
diff --git a/utility/build.gradle b/utility/build.gradle
index 353ea924239..4ffcde26c70 100644
--- a/utility/build.gradle
+++ b/utility/build.gradle
@@ -4,12 +4,12 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
- compileSdkVersion 30
+ compileSdkVersion 31
buildToolsVersion "29.0.2"
defaultConfig {
minSdkVersion 19
- targetSdkVersion 30
+ targetSdkVersion 31
versionCode 1
versionName "1.0"
javaCompileOptions {
diff --git a/utility/src/main/AndroidManifest.xml b/utility/src/main/AndroidManifest.xml
index f16271049d7..5a8bce58b67 100644
--- a/utility/src/main/AndroidManifest.xml
+++ b/utility/src/main/AndroidManifest.xml
@@ -1,4 +1,4 @@
-
+
From d27b461e3f7f60329d3c87a2f5c649983672f32d Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Mon, 21 Nov 2022 18:43:40 +0530
Subject: [PATCH 119/138] more fixes
---
.../app/customview/PromotedStoryCardView.kt | 2 +-
.../app/spotlight/SpotlightFragment.kt | 11 ++++-----
.../main/res/layout/bottom_left_overlay.xml | 12 +++++-----
.../main/res/layout/bottom_right_overlay.xml | 10 ++++----
.../main/res/layout/promoted_story_card.xml | 2 +-
app/src/main/res/layout/top_left_overlay.xml | 10 ++++----
app/src/main/res/layout/top_right_overlay.xml | 12 +++++-----
app/src/main/res/values/colors_migrating.xml | 2 +-
app/src/main/res/values/dimens.xml | 11 +++++----
app/src/main/res/values/strings.xml | 24 +++++++++----------
.../android/app/home/HomeActivityTest.kt | 2 +-
.../app/onboarding/OnboardingFragmentTest.kt | 16 ++++++++-----
.../exploration/ExplorationActivityTest.kt | 6 ++---
.../app/spotlight/SpotlightFragmentTest.kt | 4 ++--
.../android/app/topic/TopicFragmentTest.kt | 8 +++----
15 files changed, 68 insertions(+), 64 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
index ec281c4b20a..3b0eb0129f2 100644
--- a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -30,7 +30,7 @@ class PromotedStoryCardView @JvmOverloads constructor(
private var isSpotlit = false
/** Sets the index at which this custom view is located inside the recycler view. */
- fun setIndex(index: Int) {
+ fun setPromotedStoryIndex(index: Int) {
// This view can get attached multiple times and we must make sure that the spotlight is
// requested only once. Only spotlight the item at the first index of the recycler view.
if (!isSpotlit && index == 0) {
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 69b246f6b56..b4508ecf363 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -32,7 +32,6 @@ import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.util.accessibility.AccessibilityService
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
-import java.util.LinkedList
import javax.inject.Inject
import org.oppia.android.util.platformparameter.EnableSpotlightUi
import org.oppia.android.util.platformparameter.PlatformParameterValue
@@ -58,7 +57,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
@field:[Inject EnableSpotlightUi]
lateinit var enableSpotlightUi: PlatformParameterValue
- private var targetList = LinkedList()
+ private var targetList = mutableListOf()
private lateinit var spotlight: Spotlight
private var screenHeight: Int = 0
private var screenWidth: Int = 0
@@ -140,7 +139,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
override fun onEnded() {
- targetList.pop()
+ targetList.removeFirst()
val profileId = ProfileId.newBuilder()
.setInternalId(internalProfileId)
.build()
@@ -181,7 +180,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
RoundedRectangle(
spotlightTarget.anchorHeight.toFloat(),
spotlightTarget.anchorWidth.toFloat(),
- 24f
+ resources.getDimensionPixelSize(R.dimen.spotlight_highlight_rectangle_corner_radius).toFloat()
)
}
SpotlightShape.Circle -> {
@@ -195,11 +194,11 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
private fun getArrowWidth(): Float {
- return this.resources.getDimension(R.dimen.arrow_width)
+ return this.resources.getDimension(R.dimen.spotlight_arrow_width)
}
private fun getArrowHeight(): Float {
- return this.resources.getDimension(R.dimen.arrow_height)
+ return this.resources.getDimension(R.dimen.spotlight_arrow_height)
}
private fun getScreenCentreY(): Int {
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 6357018c05c..73fb60bdcc7 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -18,32 +18,32 @@
]]>
Profile Edit Fragment Test Activity
Administrator Controls Fragment Test Activity
- Select a Topic to Start
Continue Studying
- Details about the topic.
- Revise concepts learned from completed lessons here.
- Practice the concepts learned from completed lessons.
- Tap here to start playing a lesson.
- Find all your lessons here.
- Revise concepts learned from completed lessons here.
- Tap to start a chapter.
- Exit anytime using this button. We will save your progress.
- Would you like %s to read for you? Tap on this button to try!
- Tap to change voiceover language.
Next
- From now, you can see lessons recommended for you here.
Go to the bottom of the screen for a hint.
Done
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
index 721fe171346..eec31c95539 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
@@ -348,7 +348,7 @@ class HomeActivityTest {
logIntoUserTwice()
launch(createHomeActivityIntent(internalProfileId1)).use {
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.close_target)).perform(click())
+ onView(withId(R.id.close_spotlight_button)).perform(click())
testCoroutineDispatchers.runCurrent()
}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
index 40fb854276c..e2a65aaac41 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
@@ -235,7 +235,7 @@ class OnboardingFragmentTest {
fun testOnboardingFragment_checkDefaultSlide_clickSkipButton_shiftsToLastSlide() {
launch(OnboardingActivity::class.java).use {
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.close_target)).perform(click())
+ skipNextSlideButtonSpotlight()
onView(withId(R.id.skip_text_view)).perform(click())
testCoroutineDispatchers.runCurrent()
onView(
@@ -339,7 +339,7 @@ class OnboardingFragmentTest {
fun testOnboardingFragment_checkSlide1_clickSkipButton_shiftsToLastSlide() {
launch(OnboardingActivity::class.java).use {
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.close_target)).perform(click())
+ skipNextSlideButtonSpotlight()
onView(withId(R.id.onboarding_slide_view_pager)).perform(scrollToPosition(position = 1))
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.skip_text_view)).perform(click())
@@ -448,7 +448,7 @@ class OnboardingFragmentTest {
fun testOnboardingFragment_checkSlide2_clickSkipButton_shiftsToLastSlide() {
launch(OnboardingActivity::class.java).use {
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.close_target)).perform(click())
+ skipNextSlideButtonSpotlight()
onView(withId(R.id.onboarding_slide_view_pager)).perform(scrollToPosition(position = 2))
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.skip_text_view)).perform(click())
@@ -520,7 +520,7 @@ class OnboardingFragmentTest {
fun testOnboardingFragment_checkSlide3_clickGetStartedButton_opensProfileActivity() {
launch(OnboardingActivity::class.java).use {
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.close_target)).perform(click())
+ skipNextSlideButtonSpotlight()
onView(withId(R.id.onboarding_slide_view_pager)).perform(scrollToPosition(position = 3))
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.get_started_button)).perform(scrollTo(), click())
@@ -576,7 +576,7 @@ class OnboardingFragmentTest {
fun testOnboardingFragment_clickOnSkip_changeOrientation_titleIsCorrect() {
launch(OnboardingActivity::class.java).use {
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.close_target)).perform(click())
+ skipNextSlideButtonSpotlight()
onView(withId(R.id.skip_text_view)).perform(click())
testCoroutineDispatchers.runCurrent()
onView(isRoot()).perform(orientationLandscape())
@@ -682,7 +682,7 @@ class OnboardingFragmentTest {
fun testOnboardingFragment_checkSlide3_policiesLinkIsVisible() {
launch(OnboardingActivity::class.java).use {
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.close_target)).perform(click())
+ skipNextSlideButtonSpotlight()
onView(withId(R.id.skip_text_view)).perform(click())
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.slide_terms_of_service_and_privacy_policy_links_text_view)).perform(
@@ -720,6 +720,10 @@ class OnboardingFragmentTest {
}
}
+ private fun skipNextSlideButtonSpotlight() {
+ onView(withId(R.id.close_spotlight_button)).perform(click())
+ }
+
// TODO(#59): Figure out a way to reuse modules instead of needing to re-declare them.
@Singleton
@Component(
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
index d49e9bdfe04..e5e0b61cbde 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
@@ -469,7 +469,7 @@ class ExplorationActivityTest {
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.action_audio_player)).perform(click())
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.close_target)).perform(click())
+ onView(withId(R.id.close_spotlight_button)).perform(click())
}
launch(
@@ -540,7 +540,7 @@ class ExplorationActivityTest {
FRACTIONS_EXPLORATION_ID_0
)
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.close_target)).perform(click())
+ onView(withId(R.id.close_spotlight_button)).perform(click())
}
launch(
@@ -613,7 +613,7 @@ class ExplorationActivityTest {
FRACTIONS_EXPLORATION_ID_0
)
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.close_target)).perform(click())
+ onView(withId(R.id.close_spotlight_button)).perform(click())
}
launch(
diff --git a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
index f704391e827..712669f5afa 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
@@ -215,7 +215,7 @@ class SpotlightFragmentTest {
checkNotNull(activity.getSpotlightFragment()).requestSpotlight(spotlightTarget)
testCoroutineDispatchers.runCurrent()
}
- onView(withId(R.id.close_target)).perform(click())
+ onView(withId(R.id.close_spotlight_button)).perform(click())
}
launch(
@@ -326,7 +326,7 @@ class SpotlightFragmentTest {
checkNotNull(activity.getSpotlightFragment()).requestSpotlight(secondSpotlightTarget)
testCoroutineDispatchers.runCurrent()
}
- onView(withId(R.id.close_target)).perform(click())
+ onView(withId(R.id.close_spotlight_button)).perform(click())
testCoroutineDispatchers.runCurrent()
onView(withText(sampleSecondSpotlightText)).check(matches(isDisplayed()))
}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
index 61cb0e3d19c..f5699340d8e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
@@ -194,7 +194,7 @@ class TopicFragmentTest {
launch(createTopicActivityIntent(internalProfileId, FRACTIONS_TOPIC_ID)).use {
// Mark lessons spotlight seen.
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.close_target)).perform(click())
+ onView(withId(R.id.close_spotlight_button)).perform(click())
}
launch(createTopicActivityIntent(internalProfileId, FRACTIONS_TOPIC_ID)).use {
@@ -243,9 +243,9 @@ class TopicFragmentTest {
).use {
// Mark first chapter spotlight seen.
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.close_target)).perform(click())
+ onView(withId(R.id.close_spotlight_button)).perform(click())
testCoroutineDispatchers.runCurrent()
- onView(withId(R.id.close_target)).perform(click())
+ onView(withId(R.id.close_spotlight_button)).perform(click())
}
launch(
@@ -307,7 +307,7 @@ class TopicFragmentTest {
).use {
testCoroutineDispatchers.runCurrent()
// Mark revision tab spotlight seen.
- onView(withId(R.id.close_target)).perform(click())
+ onView(withId(R.id.close_spotlight_button)).perform(click())
}
launch(
From 9452cce98080d3a4a2d6ae7716bd7ceeb851b17a Mon Sep 17 00:00:00 2001
From: Ben Henning
Date: Mon, 21 Nov 2022 05:15:52 -0800
Subject: [PATCH 120/138] Simplify margin computations a bit for overlays.
---
.../app/spotlight/SpotlightFragment.kt | 187 ++++++++----------
1 file changed, 84 insertions(+), 103 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index aeb7e9a1c5c..3aa911a4b24 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -3,7 +3,7 @@ package org.oppia.android.app.spotlight
import android.content.Context
import android.util.DisplayMetrics
import android.view.View
-import android.view.ViewGroup
+import android.view.ViewGroup.MarginLayoutParams
import android.view.animation.DecelerateInterpolator
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
@@ -216,9 +216,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
private fun requestOverlayResource(spotlightTarget: SpotlightTarget): View {
- val anchorPosition = calculateAnchorPosition(spotlightTarget)
-
- return when (anchorPosition) {
+ return when (calculateAnchorPosition(spotlightTarget)) {
AnchorPosition.TopLeft -> {
if (isRtl) {
configureTopRightOverlay(spotlightTarget)
@@ -251,120 +249,103 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
private fun configureBottomLeftOverlay(spotlightTarget: SpotlightTarget): View {
- overlayBinding = BottomLeftOverlayBinding.inflate(this.layoutInflater)
- (overlayBinding as BottomLeftOverlayBinding).let {
- it.lifecycleOwner = this
- it.listener = this
- }
- (overlayBinding as BottomLeftOverlayBinding).customText.text = spotlightTarget.hint
-
- val arrowParams = (overlayBinding as BottomLeftOverlayBinding).spotlightOverlayArrow.layoutParams
- as ViewGroup.MarginLayoutParams
- if (isRtl) {
- arrowParams.setMargins(
- screenWidth - spotlightTarget.anchorLeft.toInt(),
- (spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
- )
- } else {
- arrowParams.setMargins(
- spotlightTarget.anchorLeft.toInt(),
- (spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
- )
+ val overlayBinding = BottomLeftOverlayBinding.inflate(this.layoutInflater).also {
+ this.overlayBinding = it
}
- (overlayBinding as BottomLeftOverlayBinding).spotlightOverlayArrow.layoutParams = arrowParams
- return (overlayBinding as BottomLeftOverlayBinding).root
+ overlayBinding.lifecycleOwner = this
+ overlayBinding.listener = this
+ overlayBinding.customText.text = spotlightTarget.hint
+
+ val arrowLayoutParams = overlayBinding.spotlightOverlayArrow.layoutParams as MarginLayoutParams
+ arrowLayoutParams.computeMargins(AnchorPosition.BottomLeft, spotlightTarget)
+ return overlayBinding.root
}
private fun configureBottomRightOverlay(spotlightTarget: SpotlightTarget): View {
- overlayBinding = BottomRightOverlayBinding.inflate(this.layoutInflater)
- (overlayBinding as BottomRightOverlayBinding).let {
- it.lifecycleOwner = this
- it.listener = this
- }
- (overlayBinding as BottomRightOverlayBinding).customText.text = spotlightTarget.hint
-
- val arrowParams = (overlayBinding as BottomRightOverlayBinding).spotlightOverlayArrow.layoutParams
- as ViewGroup.MarginLayoutParams
- if (isRtl) {
- arrowParams.setMargins(
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
- (spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
- screenWidth -
- (spotlightTarget.anchorLeft + getArrowWidth()).toInt(),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
- )
- } else {
- arrowParams.setMargins(
- (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
- (spotlightTarget.anchorTop.toInt() - getArrowHeight()).toInt(),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
- )
+ val overlayBinding = BottomRightOverlayBinding.inflate(this.layoutInflater).also {
+ this.overlayBinding = it
}
- (overlayBinding as BottomRightOverlayBinding).spotlightOverlayArrow.layoutParams = arrowParams
- return (overlayBinding as BottomRightOverlayBinding).root
+ overlayBinding.lifecycleOwner = this
+ overlayBinding.listener = this
+ overlayBinding.customText.text = spotlightTarget.hint
+
+ val arrowLayoutParams = overlayBinding.spotlightOverlayArrow.layoutParams as MarginLayoutParams
+ arrowLayoutParams.computeMargins(AnchorPosition.BottomRight, spotlightTarget)
+ return overlayBinding.root
}
private fun configureTopRightOverlay(spotlightTarget: SpotlightTarget): View {
- overlayBinding = TopRightOverlayBinding.inflate(layoutInflater)
- (overlayBinding as TopRightOverlayBinding).let {
- it.lifecycleOwner = this
- it.listener = this
- }
- (overlayBinding as TopRightOverlayBinding).customText.text = spotlightTarget.hint
-
- val arrowParams = (overlayBinding as TopRightOverlayBinding).spotlightOverlayArrow.layoutParams
- as ViewGroup.MarginLayoutParams
- if (isRtl) {
- arrowParams.setMargins(
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
- (spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
- screenWidth - (spotlightTarget.anchorLeft + getArrowWidth()).toInt(),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
- )
- } else {
- arrowParams.setMargins(
- (spotlightTarget.anchorLeft + spotlightTarget.anchorWidth - getArrowWidth()).toInt(),
- (spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
- )
+ val overlayBinding = TopRightOverlayBinding.inflate(this.layoutInflater).also {
+ this.overlayBinding = it
}
- (overlayBinding as TopRightOverlayBinding).spotlightOverlayArrow.layoutParams = arrowParams
- return (overlayBinding as TopRightOverlayBinding).root
+ overlayBinding.lifecycleOwner = this
+ overlayBinding.listener = this
+ overlayBinding.customText.text = spotlightTarget.hint
+
+ val arrowLayoutParams = overlayBinding.spotlightOverlayArrow.layoutParams as MarginLayoutParams
+ arrowLayoutParams.computeMargins(AnchorPosition.TopRight, spotlightTarget)
+ return overlayBinding.root
}
private fun configureTopLeftOverlay(spotlightTarget: SpotlightTarget): View {
- overlayBinding = TopLeftOverlayBinding.inflate(this.layoutInflater)
- (overlayBinding as TopLeftOverlayBinding).let {
- it.lifecycleOwner = this
- it.listener = this
+ val overlayBinding = TopLeftOverlayBinding.inflate(this.layoutInflater).also {
+ this.overlayBinding = it
}
- (overlayBinding as TopLeftOverlayBinding).customText.text = spotlightTarget.hint
-
- val arrowParams = (overlayBinding as TopLeftOverlayBinding).spotlightOverlayArrow.layoutParams
- as ViewGroup.MarginLayoutParams
- if (isRtl) {
- arrowParams.setMargins(
- screenWidth - spotlightTarget.anchorLeft.toInt(),
- (spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
- )
- } else {
- arrowParams.setMargins(
- spotlightTarget.anchorLeft.toInt(),
- (spotlightTarget.anchorTop + spotlightTarget.anchorHeight).toInt(),
- resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin),
+ overlayBinding.lifecycleOwner = this
+ overlayBinding.listener = this
+ overlayBinding.customText.text = spotlightTarget.hint
+
+ val arrowLayoutParams = overlayBinding.spotlightOverlayArrow.layoutParams as MarginLayoutParams
+ arrowLayoutParams.computeMargins(AnchorPosition.TopLeft, spotlightTarget)
+ return overlayBinding.root
+ }
+
+ private fun MarginLayoutParams.computeMargins(
+ anchorPosition: AnchorPosition, spotlightTarget: SpotlightTarget
+ ) {
+ setMargins(
+ computeLeftMargin(anchorPosition, spotlightTarget),
+ computeTopMargin(anchorPosition, spotlightTarget),
+ computeRightMargin(anchorPosition, spotlightTarget),
+ computeBottomMargin()
+ )
+ }
+
+ private fun computeLeftMargin(anchorPosition: AnchorPosition, target: SpotlightTarget): Int {
+ return when (anchorPosition) {
+ AnchorPosition.BottomLeft, AnchorPosition.TopLeft ->
+ if (isRtl) screenWidth - target.anchorLeft.toInt() else target.anchorLeft.toInt()
+ AnchorPosition.BottomRight, AnchorPosition.TopRight -> {
+ if (isRtl) {
+ resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
+ } else (target.anchorLeft + target.anchorWidth - getArrowWidth()).toInt()
+ }
+ }
+ }
+
+ private fun computeTopMargin(anchorPosition: AnchorPosition, target: SpotlightTarget): Int {
+ return when (anchorPosition) {
+ AnchorPosition.BottomLeft, AnchorPosition.BottomRight ->
+ (target.anchorTop - getArrowHeight()).toInt()
+ AnchorPosition.TopLeft, AnchorPosition.TopRight ->
+ (target.anchorTop + target.anchorHeight).toInt()
+ }
+ }
+
+ private fun computeRightMargin(anchorPosition: AnchorPosition, target: SpotlightTarget): Int {
+ return when (anchorPosition) {
+ AnchorPosition.BottomLeft, AnchorPosition.TopLeft ->
resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
- )
+ AnchorPosition.BottomRight, AnchorPosition.TopRight -> {
+ if (isRtl) {
+ screenWidth - (target.anchorLeft + getArrowWidth()).toInt()
+ } else resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
+ }
}
- (overlayBinding as TopLeftOverlayBinding).spotlightOverlayArrow.layoutParams = arrowParams
- return (overlayBinding as TopLeftOverlayBinding).root
+ }
+
+ private fun computeBottomMargin(): Int {
+ return resources.getDimensionPixelSize(R.dimen.spotlight_overlay_arrow_left_margin)
}
private fun calculateScreenSize() {
From 4db4a53745453a15b6c6e25146b7407f2dbf8d23 Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Mon, 21 Nov 2022 18:56:32 +0530
Subject: [PATCH 121/138] another fix
---
.../org/oppia/android/app/spotlight/SpotlightFragment.kt | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index b4508ecf363..0b3c63d75ac 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -264,7 +264,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
it.lifecycleOwner = this
it.listener = this
}
- (overlayBinding as BottomLeftOverlayBinding).customText.text = spotlightTarget.hint
+ (overlayBinding as BottomLeftOverlayBinding).spotlightHintText.text = spotlightTarget.hint
val arrowParams = (overlayBinding as BottomLeftOverlayBinding).spotlightOverlayArrow.layoutParams
as ViewGroup.MarginLayoutParams
@@ -293,7 +293,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
it.lifecycleOwner = this
it.listener = this
}
- (overlayBinding as BottomRightOverlayBinding).customText.text = spotlightTarget.hint
+ (overlayBinding as BottomRightOverlayBinding).spotlightHintText.text = spotlightTarget.hint
val arrowParams = (overlayBinding as BottomRightOverlayBinding).spotlightOverlayArrow.layoutParams
as ViewGroup.MarginLayoutParams
@@ -323,7 +323,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
it.lifecycleOwner = this
it.listener = this
}
- (overlayBinding as TopRightOverlayBinding).customText.text = spotlightTarget.hint
+ (overlayBinding as TopRightOverlayBinding).spotlightHintText.text = spotlightTarget.hint
val arrowParams = (overlayBinding as TopRightOverlayBinding).spotlightOverlayArrow.layoutParams
as ViewGroup.MarginLayoutParams
@@ -352,7 +352,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
it.lifecycleOwner = this
it.listener = this
}
- (overlayBinding as TopLeftOverlayBinding).customText.text = spotlightTarget.hint
+ (overlayBinding as TopLeftOverlayBinding).spotlightHintText.text = spotlightTarget.hint
val arrowParams = (overlayBinding as TopLeftOverlayBinding).spotlightOverlayArrow.layoutParams
as ViewGroup.MarginLayoutParams
From 8dee6c167bc4e496eaefa664fd658d2238aa72d9 Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Mon, 21 Nov 2022 19:07:42 +0530
Subject: [PATCH 122/138] another fix
---
.../android/app/player/audio/AudioFragmentPresenter.kt | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index c953f7f92ce..a1f86f14ee4 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -36,6 +36,8 @@ import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.networking.NetworkConnectionUtil
import javax.inject.Inject
+import org.oppia.android.util.platformparameter.EnableSpotlightUi
+import org.oppia.android.util.platformparameter.PlatformParameterValue
const val TAG_LANGUAGE_DIALOG = "LANGUAGE_DIALOG"
private const val TAG_CELLULAR_DATA_DIALOG = "CELLULAR_DATA_DIALOG"
@@ -52,7 +54,8 @@ class AudioFragmentPresenter @Inject constructor(
private val networkConnectionUtil: NetworkConnectionUtil,
private val viewModelProvider: ViewModelProvider,
private val oppiaLogger: OppiaLogger,
- private val resourceHandler: AppLanguageResourceHandler
+ private val resourceHandler: AppLanguageResourceHandler,
+ @EnableSpotlightUi private val enableSpotlightUi: PlatformParameterValue
) {
var userIsSeeking = false
var userProgress = 0
@@ -281,9 +284,9 @@ class AudioFragmentPresenter @Inject constructor(
audioButtonListener.scrollToTop()
if (feedbackId == null) {
// This isn't reloading content since it's the first case of the content auto-playing.
- loadMainContentAudio(allowAutoPlay = false, reloadingContent = false)
+ loadMainContentAudio(allowAutoPlay = !enableSpotlightUi.value, reloadingContent = false)
} else {
- loadFeedbackAudio(feedbackId!!, false)
+ loadFeedbackAudio(feedbackId!!, !enableSpotlightUi.value)
}
fragment.view?.startAnimation(AnimationUtils.loadAnimation(context, R.anim.slide_down_audio))
startSpotlights()
From fa2e69f0642cf42b68dd40a566c1668b441e0edd Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Mon, 21 Nov 2022 19:51:53 +0530
Subject: [PATCH 123/138] fix constraints, add tests
---
.../main/res/layout/bottom_left_overlay.xml | 4 +--
.../main/res/layout/bottom_right_overlay.xml | 2 +-
.../player/state/StateFragmentLocalTest.kt | 33 +++++++++++++++++++
3 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 73fb60bdcc7..c71fba37606 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -48,14 +48,14 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
- android:layout_marginBottom="52dp"
+ android:layout_marginTop="8dp"
android:background="@color/color_def_dark_blue"
android:gravity="center"
android:minWidth="160dp"
android:minHeight="48dp"
android:onClick="@{(v) -> listener.clickOnDone()}"
android:text="@string/mark_spotlight_seen_button_text"
- app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index 3804558973a..7762e0fdbfe 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -56,7 +56,7 @@
android:minHeight="48dp"
android:onClick="@{(v) -> listener.clickOnDone()}"
android:text="@string/mark_spotlight_seen_button_text"
- app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
diff --git a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
index 6009b6bad86..2a6cb16bddf 100644
--- a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
@@ -856,6 +856,39 @@ class StateFragmentLocalTest {
}
}
+ @Test
+ fun testHintBarForcedAnnouncement_submitTwoWrongAnswers_checkAnnouncesIn5SecsAfter() {
+ launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {
+ startPlayingExploration()
+ playThroughFractionsState1()
+
+ submitTwoWrongAnswersForFractionsState2()
+ openHintsAndSolutionsDialog()
+
+ testCoroutineDispatchers.advanceTimeBy(TimeUnit.SECONDS.toMillis(5))
+ assertThat(fakeAccessibilityService.getLatestAnnouncement()).isEqualTo(
+ "Go to the bottom of the screen for a hint."
+ )
+ }
+ }
+
+ @Test
+ fun testHintBarForcedAnnouncement_submitTwoWrongAnswers_checkDoesNotRepeatAnnouncementAfter30Sec() {
+ launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {
+ startPlayingExploration()
+ playThroughFractionsState1()
+
+ submitTwoWrongAnswersForFractionsState2()
+ openHintsAndSolutionsDialog()
+
+ // announcement played
+ testCoroutineDispatchers.advanceTimeBy(TimeUnit.SECONDS.toMillis(5))
+ fakeAccessibilityService.resetLatestAnnouncement()
+ testCoroutineDispatchers.advanceTimeBy(TimeUnit.SECONDS.toMillis(30))
+ assertThat(fakeAccessibilityService.getLatestAnnouncement()).isEqualTo(null)
+ }
+ }
+
@Test
fun testStateFragment_nextState_submitTwoWrongAnswersAndWait_canViewOneHint() {
launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {
From 40c32e7c38021d60cdcea9fb3514b32eafc67eec Mon Sep 17 00:00:00 2001
From: Ben Henning
Date: Mon, 21 Nov 2022 06:59:58 -0800
Subject: [PATCH 124/138] Miscellaneous follow-up static check & test fixes.
---
.../ChapterNotStartedContainerConstraintLayout.kt | 2 +-
.../oppia/android/app/home/HomeActivityPresenter.kt | 2 --
.../app/onboarding/OnboardingActivityPresenter.kt | 2 --
.../app/player/audio/AudioFragmentPresenter.kt | 2 +-
.../exploration/ExplorationActivityPresenter.kt | 2 --
.../android/app/spotlight/SpotlightFragment.kt | 13 ++++++++-----
.../org/oppia/android/app/home/HomeActivityTest.kt | 4 ++--
.../app/onboarding/OnboardingFragmentTest.kt | 4 ++--
.../android/app/spotlight/SpotlightFragmentTest.kt | 8 +++++++-
.../oppia/android/app/topic/TopicFragmentTest.kt | 2 +-
.../app/player/state/StateFragmentLocalTest.kt | 4 ++--
.../TestPlatformParameterModule.kt | 5 ++---
.../platformparameter/PlatformParameterConstants.kt | 2 +-
13 files changed, 27 insertions(+), 25 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index 97266d0c6b2..5df58e5522f 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -31,7 +31,7 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
lateinit var resourceHandler: AppLanguageResourceHandler
/** Sets the index of the story of which this custom view is a part of. */
- fun setStoryIndex(index: Int) {
+ fun setStoryIndex(index: Int) {
// Only spotlight the first chapter of the "first" story. We know for sure that for a new user,
// the first chapter shall be a type of not started chapter view. The index tells which story
// are we on.
diff --git a/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
index 31d5e7c5e63..83e65950b7f 100644
--- a/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/home/HomeActivityPresenter.kt
@@ -1,6 +1,5 @@
package org.oppia.android.app.home
-import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
@@ -10,7 +9,6 @@ import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.drawer.NavigationDrawerFragment
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightManager
-import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
import javax.inject.Inject
const val TAG_HOME_FRAGMENT = "HOME_FRAGMENT"
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
index 07240a522de..79108be1bd6 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
@@ -1,12 +1,10 @@
package org.oppia.android.app.onboarding
-import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightManager
-import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
import javax.inject.Inject
/** The presenter for [OnboardingActivity]. */
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index a1f86f14ee4..c18aa140d23 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -35,9 +35,9 @@ import org.oppia.android.domain.profile.ProfileManagementController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.networking.NetworkConnectionUtil
-import javax.inject.Inject
import org.oppia.android.util.platformparameter.EnableSpotlightUi
import org.oppia.android.util.platformparameter.PlatformParameterValue
+import javax.inject.Inject
const val TAG_LANGUAGE_DIALOG = "LANGUAGE_DIALOG"
private const val TAG_CELLULAR_DATA_DIALOG = "CELLULAR_DATA_DIALOG"
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
index b197a9706b0..3bc3a0ba0cd 100644
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
@@ -1,7 +1,6 @@
package org.oppia.android.app.player.exploration
import android.content.Context
-import android.os.Bundle
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.TextView
@@ -28,7 +27,6 @@ import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
-import org.oppia.android.app.topic.PROFILE_ID_ARGUMENT_KEY
import org.oppia.android.app.topic.TopicActivity
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.utility.FontScaleConfigurationUtil
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 71a7f61319f..d1d09d58fe1 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -13,10 +13,10 @@ import androidx.lifecycle.Observer
import com.takusemba.spotlight.OnSpotlightListener
import com.takusemba.spotlight.OnTargetListener
import com.takusemba.spotlight.Spotlight
+import com.takusemba.spotlight.Target
import com.takusemba.spotlight.shape.Circle
import com.takusemba.spotlight.shape.RoundedRectangle
import com.takusemba.spotlight.shape.Shape
-import com.takusemba.spotlight.Target
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentComponentImpl
import org.oppia.android.app.fragment.InjectableFragment
@@ -32,9 +32,9 @@ import org.oppia.android.domain.spotlight.SpotlightStateController
import org.oppia.android.util.accessibility.AccessibilityService
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
-import javax.inject.Inject
import org.oppia.android.util.platformparameter.EnableSpotlightUi
import org.oppia.android.util.platformparameter.PlatformParameterValue
+import javax.inject.Inject
/**
* Fragment to hold spotlights on elements. This fragment provides a single place for all the
@@ -177,7 +177,9 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
RoundedRectangle(
spotlightTarget.anchorHeight.toFloat(),
spotlightTarget.anchorWidth.toFloat(),
- resources.getDimensionPixelSize(R.dimen.spotlight_highlight_rectangle_corner_radius).toFloat()
+ resources.getDimensionPixelSize(
+ R.dimen.spotlight_highlight_rectangle_corner_radius
+ ).toFloat()
)
}
SpotlightShape.Circle -> {
@@ -306,7 +308,8 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
private fun MarginLayoutParams.computeMargins(
- anchorPosition: AnchorPosition, spotlightTarget: SpotlightTarget
+ anchorPosition: AnchorPosition,
+ spotlightTarget: SpotlightTarget
) {
setMargins(
computeLeftMargin(anchorPosition, spotlightTarget),
@@ -373,7 +376,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
companion object {
- /* Returns a new [SpotlightFragment]. */
+ /** Returns a new [SpotlightFragment]. */
fun newInstance(internalProfileId: Int): SpotlightFragment {
val spotlightFragment = SpotlightFragment()
val args = Bundle()
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
index eec31c95539..df0139a9bf8 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
@@ -107,7 +107,6 @@ import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
import org.oppia.android.domain.oppialogger.analytics.CpuPerformanceSnapshotterModule
import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
-import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
import org.oppia.android.domain.spotlight.SpotlightStateController
@@ -124,6 +123,7 @@ import org.oppia.android.testing.TestPlatform
import org.oppia.android.testing.data.DataProviderTestMonitor
import org.oppia.android.testing.junit.DefineAppLanguageLocaleContext
import org.oppia.android.testing.junit.InitializeDefaultLocaleRule
+import org.oppia.android.testing.platformparameter.TestPlatformParameterModule
import org.oppia.android.testing.profile.ProfileTestHelper
import org.oppia.android.testing.robolectric.RobolectricModule
import org.oppia.android.testing.story.StoryProgressTestHelper
@@ -1912,7 +1912,7 @@ class HomeActivityTest {
@Component(
modules = [
RobolectricModule::class,
- PlatformParameterModule::class, PlatformParameterSingletonModule::class,
+ TestPlatformParameterModule::class, PlatformParameterSingletonModule::class,
TestDispatcherModule::class, ApplicationModule::class,
LoggerModule::class, ContinueModule::class, FractionInputModule::class,
ItemSelectionInputModule::class, MultipleChoiceInputModule::class,
diff --git a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
index e2a65aaac41..2d1d8f883de 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
@@ -82,7 +82,6 @@ import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
import org.oppia.android.domain.oppialogger.analytics.CpuPerformanceSnapshotterModule
import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
-import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
@@ -90,6 +89,7 @@ import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule
import org.oppia.android.testing.OppiaTestRule
import org.oppia.android.testing.TestLogReportingModule
import org.oppia.android.testing.junit.InitializeDefaultLocaleRule
+import org.oppia.android.testing.platformparameter.TestPlatformParameterModule
import org.oppia.android.testing.robolectric.RobolectricModule
import org.oppia.android.testing.threading.TestCoroutineDispatchers
import org.oppia.android.testing.threading.TestDispatcherModule
@@ -729,7 +729,7 @@ class OnboardingFragmentTest {
@Component(
modules = [
RobolectricModule::class,
- PlatformParameterModule::class, PlatformParameterSingletonModule::class,
+ TestPlatformParameterModule::class, PlatformParameterSingletonModule::class,
TestDispatcherModule::class, ApplicationModule::class,
LoggerModule::class, ContinueModule::class, FractionInputModule::class,
ItemSelectionInputModule::class, MultipleChoiceInputModule::class,
diff --git a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
index 712669f5afa..710037b954c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
@@ -73,6 +73,7 @@ import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule
import org.oppia.android.testing.TestImageLoaderModule
import org.oppia.android.testing.TestLogReportingModule
+import org.oppia.android.testing.platformparameter.TestPlatformParameterModule
import org.oppia.android.testing.robolectric.RobolectricModule
import org.oppia.android.testing.threading.TestCoroutineDispatchers
import org.oppia.android.testing.threading.TestDispatcherModule
@@ -91,7 +92,6 @@ import org.oppia.android.util.networking.NetworkConnectionDebugUtilModule
import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule
import org.oppia.android.util.parser.image.ImageParsingModule
-import org.oppia.android.testing.platformparameter.TestPlatformParameterModule
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
import javax.inject.Inject
@@ -161,6 +161,7 @@ class SpotlightFragmentTest {
@Test
fun testSpotlightFragment_requestSpotlight_shouldShowSpotlight() {
+ TestPlatformParameterModule.forceEnableSpotlightUi(true)
launch(
createSpotlightFragmentTestActivity(context)
).use {
@@ -182,6 +183,7 @@ class SpotlightFragmentTest {
@Test
fun testSpotlightFragment_requestDelayedSpotlight_shouldShowSpotlight() {
+ TestPlatformParameterModule.forceEnableSpotlightUi(true)
launch(createSpotlightFragmentTestActivity(context)).use {
testCoroutineDispatchers.runCurrent()
it.onActivity { activity ->
@@ -203,6 +205,7 @@ class SpotlightFragmentTest {
@Test
fun testSpotlightFragment_markSpotlightSeen_checkSpotlightIsNotShowAgain() {
+ TestPlatformParameterModule.forceEnableSpotlightUi(true)
launch(createSpotlightFragmentTestActivity(context)).use {
it.onActivity { activity ->
val spotlightTarget = SpotlightTarget(
@@ -238,6 +241,7 @@ class SpotlightFragmentTest {
@Test
fun testSpotlightFragment_exitSpotlightWithoutClickingDone_checkSpotlightIsShowAgain() {
+ TestPlatformParameterModule.forceEnableSpotlightUi(true)
launch(createSpotlightFragmentTestActivity(context)).use {
it.onActivity { activity ->
val spotlightTarget = SpotlightTarget(
@@ -272,6 +276,7 @@ class SpotlightFragmentTest {
@Test
fun testSpotlightQueuing_requestTwoSpotlights_checkFirstSpotlightShown() {
+ TestPlatformParameterModule.forceEnableSpotlightUi(true)
launch(
createSpotlightFragmentTestActivity(context)
).use {
@@ -302,6 +307,7 @@ class SpotlightFragmentTest {
@Test
fun testSpotlightQueuing_requestTwoSpotlights_pressDone_checkSecondSpotlightShown() {
+ TestPlatformParameterModule.forceEnableSpotlightUi(true)
launch(
createSpotlightFragmentTestActivity(context)
).use {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
index f5699340d8e..f9acce2da02 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
@@ -46,6 +46,7 @@ import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.model.Spotlight.FeatureCase.FIRST_CHAPTER
import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_LESSON_TAB
import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_REVISION_TAB
@@ -120,7 +121,6 @@ import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
import javax.inject.Inject
import javax.inject.Singleton
-import org.oppia.android.app.model.Spotlight
private const val INFO_TAB_POSITION = 0
private const val LESSON_TAB_POSITION = 1
diff --git a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
index 2a6cb16bddf..92faa8df116 100644
--- a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
@@ -857,7 +857,7 @@ class StateFragmentLocalTest {
}
@Test
- fun testHintBarForcedAnnouncement_submitTwoWrongAnswers_checkAnnouncesIn5SecsAfter() {
+ fun testHintBarForcedAnnouncement_submitTwoWrongAnswers_checkAnnouncesAfter5Seconds() {
launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {
startPlayingExploration()
playThroughFractionsState1()
@@ -873,7 +873,7 @@ class StateFragmentLocalTest {
}
@Test
- fun testHintBarForcedAnnouncement_submitTwoWrongAnswers_checkDoesNotRepeatAnnouncementAfter30Sec() {
+ fun testHintBarForcedAnnouncement_submitTwoWrongAnswers_doesNotRepeatAnnouncementAfter30Sec() {
launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {
startPlayingExploration()
playThroughFractionsState1()
diff --git a/testing/src/main/java/org/oppia/android/testing/platformparameter/TestPlatformParameterModule.kt b/testing/src/main/java/org/oppia/android/testing/platformparameter/TestPlatformParameterModule.kt
index d6f52281821..1d820233c1f 100644
--- a/testing/src/main/java/org/oppia/android/testing/platformparameter/TestPlatformParameterModule.kt
+++ b/testing/src/main/java/org/oppia/android/testing/platformparameter/TestPlatformParameterModule.kt
@@ -20,6 +20,7 @@ import org.oppia.android.util.platformparameter.EnableExtraTopicTabsUi
import org.oppia.android.util.platformparameter.EnableInteractionConfigChangeStateRetention
import org.oppia.android.util.platformparameter.EnableLanguageSelectionUi
import org.oppia.android.util.platformparameter.EnablePerformanceMetricsCollection
+import org.oppia.android.util.platformparameter.EnableSpotlightUi
import org.oppia.android.util.platformparameter.LEARNER_STUDY_ANALYTICS_DEFAULT_VALUE
import org.oppia.android.util.platformparameter.LearnerStudyAnalytics
import org.oppia.android.util.platformparameter.PERFORMANCE_METRICS_COLLECTION_HIGH_FREQUENCY_TIME_INTERVAL_IN_MINUTES
@@ -40,8 +41,6 @@ import org.oppia.android.util.platformparameter.SYNC_UP_WORKER_TIME_PERIOD_IN_HO
import org.oppia.android.util.platformparameter.SplashScreenWelcomeMsg
import org.oppia.android.util.platformparameter.SyncUpWorkerTimePeriodHours
import javax.inject.Singleton
-import org.oppia.android.util.platformparameter.ENABLE_SPOTLIGHT_UI_DEFAULT_VALUE
-import org.oppia.android.util.platformparameter.EnableSpotlightUi
/* Fake Platform Parameter Module that provides individual Platform Parameters for testing. */
@Module
@@ -204,7 +203,7 @@ class TestPlatformParameterModule {
ENABLE_INTERACTION_CONFIG_CHANGE_STATE_RETENTION_DEFAULT_VALUE
private var enablePerformanceMetricsCollection =
ENABLE_PERFORMANCE_METRICS_COLLECTION_DEFAULT_VALUE
- private var enableSpotlightUi = ENABLE_SPOTLIGHT_UI_DEFAULT_VALUE
+ private var enableSpotlightUi = true
/** Enables forcing [EnableLanguageSelectionUi] platform parameter flag from tests. */
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
diff --git a/utility/src/main/java/org/oppia/android/util/platformparameter/PlatformParameterConstants.kt b/utility/src/main/java/org/oppia/android/util/platformparameter/PlatformParameterConstants.kt
index 3200c84ffe4..16a633fda6c 100644
--- a/utility/src/main/java/org/oppia/android/util/platformparameter/PlatformParameterConstants.kt
+++ b/utility/src/main/java/org/oppia/android/util/platformparameter/PlatformParameterConstants.kt
@@ -218,7 +218,7 @@ const val PERFORMANCE_METRICS_COLLECTION_LOW_FREQUENCY_TIME_INTERVAL_IN_MINUTES_
annotation class EnableSpotlightUi
/** Default value for the feature flag corresponding to [EnableSpotlightUi]. */
-const val ENABLE_SPOTLIGHT_UI_DEFAULT_VALUE = true
+const val ENABLE_SPOTLIGHT_UI_DEFAULT_VALUE = false
/**
* Qualifier for the platform parameter that controls whether input interaction state is correctly
From 9b7aca499e5063a5bbfa4bc4580082d13e9cca6c Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Mon, 21 Nov 2022 21:38:08 +0530
Subject: [PATCH 125/138] fixes
---
.../player/audio/AudioFragmentPresenter.kt | 8 ++++---
.../app/spotlight/SpotlightFragment.kt | 5 +++--
.../testing/SpotlightFragmentTestActivity.kt | 4 ++--
.../app/topic/TopicFragmentPresenter.kt | 2 +-
.../spotlight_done_button_background.xml | 9 ++++++++
.../state_button_primary_background.xml | 2 +-
.../main/res/layout/bottom_left_overlay.xml | 4 ++--
.../main/res/layout/bottom_right_overlay.xml | 12 +++++-----
app/src/main/res/layout/top_left_overlay.xml | 4 ++--
app/src/main/res/layout/top_right_overlay.xml | 4 ++--
app/src/main/res/values/dimens.xml | 1 +
.../app/spotlight/SpotlightFragmentTest.kt | 22 +++++++++----------
.../PlatformParameterConstants.kt | 2 +-
13 files changed, 45 insertions(+), 34 deletions(-)
create mode 100644 app/src/main/res/drawable/spotlight_done_button_background.xml
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index c18aa140d23..22d02a3f94a 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -130,13 +130,15 @@ class AudioFragmentPresenter @Inject constructor(
Spotlight.FeatureCase.VOICEOVER_LANGUAGE_ICON
)
- getSpotlightFragment().requestSpotlightViewWithDelayedLayout(audioLanguageIconSpotlightTarget)
+ checkNotNull(getSpotlightFragment()).requestSpotlightViewWithDelayedLayout(
+ audioLanguageIconSpotlightTarget
+ )
}
- private fun getSpotlightFragment(): SpotlightFragment {
+ private fun getSpotlightFragment(): SpotlightFragment? {
return activity.supportFragmentManager.findFragmentByTag(
SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
- ) as SpotlightFragment
+ ) as? SpotlightFragment
}
private fun getProfileData(): LiveData {
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index d1d09d58fe1..493d81ee9c2 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -114,8 +114,9 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
object : Observer> {
override fun onChanged(it: AsyncResult?) {
if (it is AsyncResult.Success) {
- if (it.value == SpotlightViewState.SPOTLIGHT_SEEN) return
- createTarget(spotlightTarget)
+ if (it.value == SpotlightViewState.SPOTLIGHT_NOT_SEEN) {
+ createTarget(spotlightTarget)
+ }
featureViewStateLiveData.removeObserver(this)
}
}
diff --git a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
index b8548ad0a1b..e18e9ae1667 100644
--- a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
+++ b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
@@ -20,7 +20,7 @@ class SpotlightFragmentTestActivity : TestActivity() {
spotlightFragmentTestActivityPresenter.handleOnCreate(
intent.getIntExtra(
- PROFILE_ID_ARGUMENT_KEY, /* profileIdKEyDefaultValue */ -1
+ PROFILE_ID_ARGUMENT_KEY, /* profileIdKeyDefaultValue */ -1
)
)
}
@@ -35,7 +35,7 @@ class SpotlightFragmentTestActivity : TestActivity() {
/** Returns the [Intent] for opening [SpotlightFragmentTestActivity]. */
fun createSpotlightFragmentTestActivity(context: Context): Intent {
return Intent(context, SpotlightFragmentTestActivity::class.java).also {
- it.putExtra(PROFILE_ID_ARGUMENT_KEY, /* profileIdKEyDefaultValue */ 0)
+ it.putExtra(PROFILE_ID_ARGUMENT_KEY, /* profileIdKeyDefaultValue */ 0)
}
}
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index fb81233a558..3fc9cda63c7 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -75,7 +75,7 @@ class TopicFragmentPresenter @Inject constructor(
return binding.root
}
- /* Requests the spotlights required in this activity to be enqueued. */
+ /** Requests the spotlights required in this activity to be enqueued. */
fun startSpotlight() {
viewModel.numberOfChaptersCompletedLiveData.observe(fragment) { numberOfChaptersCompleted ->
if (numberOfChaptersCompleted != null) {
diff --git a/app/src/main/res/drawable/spotlight_done_button_background.xml b/app/src/main/res/drawable/spotlight_done_button_background.xml
new file mode 100644
index 00000000000..f5d71620f06
--- /dev/null
+++ b/app/src/main/res/drawable/spotlight_done_button_background.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/state_button_primary_background.xml b/app/src/main/res/drawable/state_button_primary_background.xml
index 6acb29f6cd3..047d0044abc 100644
--- a/app/src/main/res/drawable/state_button_primary_background.xml
+++ b/app/src/main/res/drawable/state_button_primary_background.xml
@@ -1,7 +1,7 @@
-
+
@@ -48,15 +48,15 @@
style="@style/StateButtonActive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
+ android:layout_marginTop="48dp"
android:layout_marginEnd="8dp"
- android:background="@color/color_def_dark_blue"
+ android:background="@drawable/spotlight_done_button_background"
android:gravity="center"
android:minWidth="160dp"
android:minHeight="48dp"
android:onClick="@{(v) -> listener.clickOnDone()}"
android:text="@string/mark_spotlight_seen_button_text"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintEnd_toEndOf="parent" />
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index da67778a6cb..564c7062763 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -48,8 +48,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
- android:layout_marginBottom="52dp"
- android:background="@color/color_def_dark_blue"
+ android:layout_marginBottom="24dp"
+ android:background="@drawable/spotlight_done_button_background"
android:gravity="center"
android:minWidth="160dp"
android:minHeight="48dp"
diff --git a/app/src/main/res/layout/top_right_overlay.xml b/app/src/main/res/layout/top_right_overlay.xml
index 420de9eddb3..676a2dedf33 100644
--- a/app/src/main/res/layout/top_right_overlay.xml
+++ b/app/src/main/res/layout/top_right_overlay.xml
@@ -48,8 +48,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
- android:layout_marginBottom="52dp"
- android:background="@color/color_def_dark_blue"
+ android:layout_marginBottom="24dp"
+ android:background="@drawable/spotlight_done_button_background"
android:gravity="center"
android:minWidth="160dp"
android:minHeight="48dp"
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index de82b47f7d1..cafdc459201 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -766,4 +766,5 @@
21dp
8dp
8dp
+ 4dp
diff --git a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
index 710037b954c..b6de2fd7f6f 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
@@ -153,8 +153,8 @@ class SpotlightFragmentTest {
)
checkNotNull(activity.getSpotlightFragment()).requestSpotlight(spotlightTarget)
- testCoroutineDispatchers.runCurrent()
}
+ testCoroutineDispatchers.runCurrent()
onView(withText(sampleSpotlightText)).check(doesNotExist())
}
}
@@ -175,8 +175,8 @@ class SpotlightFragmentTest {
)
checkNotNull(activity.getSpotlightFragment()).requestSpotlight(spotlightTarget)
- testCoroutineDispatchers.runCurrent()
}
+ testCoroutineDispatchers.runCurrent()
onView(withText(sampleSpotlightText)).check(matches(isDisplayed()))
}
}
@@ -197,8 +197,8 @@ class SpotlightFragmentTest {
checkNotNull(
activity.getSpotlightFragment()
).requestSpotlightViewWithDelayedLayout(spotlightTarget)
- testCoroutineDispatchers.runCurrent()
}
+ testCoroutineDispatchers.runCurrent()
onView(withText(sampleSpotlightText)).check(matches(isDisplayed()))
}
}
@@ -216,8 +216,8 @@ class SpotlightFragmentTest {
)
checkNotNull(activity.getSpotlightFragment()).requestSpotlight(spotlightTarget)
- testCoroutineDispatchers.runCurrent()
}
+ testCoroutineDispatchers.runCurrent()
onView(withId(R.id.close_spotlight_button)).perform(click())
}
@@ -233,8 +233,8 @@ class SpotlightFragmentTest {
)
checkNotNull(activity.getSpotlightFragment()).requestSpotlight(spotlightTarget)
- testCoroutineDispatchers.runCurrent()
}
+ testCoroutineDispatchers.runCurrent()
onView(withText(sampleSpotlightText)).check(doesNotExist())
}
}
@@ -252,8 +252,8 @@ class SpotlightFragmentTest {
)
checkNotNull(activity.getSpotlightFragment()).requestSpotlight(spotlightTarget)
- testCoroutineDispatchers.runCurrent()
}
+ testCoroutineDispatchers.runCurrent()
}
launch(
@@ -268,8 +268,8 @@ class SpotlightFragmentTest {
)
checkNotNull(activity.getSpotlightFragment()).requestSpotlight(spotlightTarget)
- testCoroutineDispatchers.runCurrent()
}
+ testCoroutineDispatchers.runCurrent()
onView(withText(sampleSpotlightText)).check(matches(isDisplayed()))
}
}
@@ -297,10 +297,9 @@ class SpotlightFragmentTest {
)
checkNotNull(activity.getSpotlightFragment()).requestSpotlight(firstSpotlightTarget)
- testCoroutineDispatchers.runCurrent()
checkNotNull(activity.getSpotlightFragment()).requestSpotlight(secondSpotlightTarget)
- testCoroutineDispatchers.runCurrent()
}
+ testCoroutineDispatchers.runCurrent()
onView(withText(sampleSpotlightText)).check(matches(isDisplayed()))
}
}
@@ -328,10 +327,9 @@ class SpotlightFragmentTest {
)
checkNotNull(activity.getSpotlightFragment()).requestSpotlight(firstSpotlightTarget)
- testCoroutineDispatchers.runCurrent()
checkNotNull(activity.getSpotlightFragment()).requestSpotlight(secondSpotlightTarget)
- testCoroutineDispatchers.runCurrent()
}
+ testCoroutineDispatchers.runCurrent()
onView(withId(R.id.close_spotlight_button)).perform(click())
testCoroutineDispatchers.runCurrent()
onView(withText(sampleSecondSpotlightText)).check(matches(isDisplayed()))
@@ -397,4 +395,4 @@ class SpotlightFragmentTest {
override fun getApplicationInjector(): ApplicationInjector = component
}
-}
+}
\ No newline at end of file
diff --git a/utility/src/main/java/org/oppia/android/util/platformparameter/PlatformParameterConstants.kt b/utility/src/main/java/org/oppia/android/util/platformparameter/PlatformParameterConstants.kt
index 16a633fda6c..3200c84ffe4 100644
--- a/utility/src/main/java/org/oppia/android/util/platformparameter/PlatformParameterConstants.kt
+++ b/utility/src/main/java/org/oppia/android/util/platformparameter/PlatformParameterConstants.kt
@@ -218,7 +218,7 @@ const val PERFORMANCE_METRICS_COLLECTION_LOW_FREQUENCY_TIME_INTERVAL_IN_MINUTES_
annotation class EnableSpotlightUi
/** Default value for the feature flag corresponding to [EnableSpotlightUi]. */
-const val ENABLE_SPOTLIGHT_UI_DEFAULT_VALUE = false
+const val ENABLE_SPOTLIGHT_UI_DEFAULT_VALUE = true
/**
* Qualifier for the platform parameter that controls whether input interaction state is correctly
From 60e00b32a503a880b939c1869f3885e2182287cd Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Mon, 21 Nov 2022 23:46:22 +0530
Subject: [PATCH 126/138] final suggestions
---
.../android/app/testing/SpotlightFragmentTestActivity.kt | 4 ++--
.../main/java/org/oppia/android/app/topic/TopicViewModel.kt | 1 +
.../org/oppia/android/app/spotlight/SpotlightFragmentTest.kt | 3 ++-
.../util/platformparameter/PlatformParameterConstants.kt | 2 +-
4 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
index e18e9ae1667..5e107c463db 100644
--- a/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
+++ b/app/src/main/java/org/oppia/android/app/testing/SpotlightFragmentTestActivity.kt
@@ -20,7 +20,7 @@ class SpotlightFragmentTestActivity : TestActivity() {
spotlightFragmentTestActivityPresenter.handleOnCreate(
intent.getIntExtra(
- PROFILE_ID_ARGUMENT_KEY, /* profileIdKeyDefaultValue */ -1
+ PROFILE_ID_ARGUMENT_KEY, /* profileIdKeyDefaultValue= */ -1
)
)
}
@@ -35,7 +35,7 @@ class SpotlightFragmentTestActivity : TestActivity() {
/** Returns the [Intent] for opening [SpotlightFragmentTestActivity]. */
fun createSpotlightFragmentTestActivity(context: Context): Intent {
return Intent(context, SpotlightFragmentTestActivity::class.java).also {
- it.putExtra(PROFILE_ID_ARGUMENT_KEY, /* profileIdKeyDefaultValue */ 0)
+ it.putExtra(PROFILE_ID_ARGUMENT_KEY, /* profileIdKeyDefaultValue= */ 0)
}
}
}
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt b/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
index d953a06547b..5febc7267c4 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicViewModel.kt
@@ -37,6 +37,7 @@ class TopicViewModel @Inject constructor(
}
private val topicListResultLiveData: LiveData> by lazy {
+ // TODO(#4754): Replace with a mechanism that properly accounts for fully completed stories.
topicListController.getPromotedActivityList(
ProfileId.newBuilder().setInternalId(internalProfileId).build()
).toLiveData()
diff --git a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
index b6de2fd7f6f..8243ca9a1f4 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
@@ -395,4 +395,5 @@ class SpotlightFragmentTest {
override fun getApplicationInjector(): ApplicationInjector = component
}
-}
\ No newline at end of file
+}
+en
\ No newline at end of file
diff --git a/utility/src/main/java/org/oppia/android/util/platformparameter/PlatformParameterConstants.kt b/utility/src/main/java/org/oppia/android/util/platformparameter/PlatformParameterConstants.kt
index 3200c84ffe4..16a633fda6c 100644
--- a/utility/src/main/java/org/oppia/android/util/platformparameter/PlatformParameterConstants.kt
+++ b/utility/src/main/java/org/oppia/android/util/platformparameter/PlatformParameterConstants.kt
@@ -218,7 +218,7 @@ const val PERFORMANCE_METRICS_COLLECTION_LOW_FREQUENCY_TIME_INTERVAL_IN_MINUTES_
annotation class EnableSpotlightUi
/** Default value for the feature flag corresponding to [EnableSpotlightUi]. */
-const val ENABLE_SPOTLIGHT_UI_DEFAULT_VALUE = true
+const val ENABLE_SPOTLIGHT_UI_DEFAULT_VALUE = false
/**
* Qualifier for the platform parameter that controls whether input interaction state is correctly
From 7e270916f035d00407dc8faf6b66d87f161c006a Mon Sep 17 00:00:00 2001
From: JishnuGoyal
Date: Mon, 21 Nov 2022 23:48:58 +0530
Subject: [PATCH 127/138] final suggestions
---
.../org/oppia/android/app/spotlight/SpotlightFragmentTest.kt | 1 -
1 file changed, 1 deletion(-)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
index 8243ca9a1f4..11f61b02273 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/spotlight/SpotlightFragmentTest.kt
@@ -396,4 +396,3 @@ class SpotlightFragmentTest {
override fun getApplicationInjector(): ApplicationInjector = component
}
}
-en
\ No newline at end of file
From 32621f8ba2626bf0966578051a466687752916cb Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 24 Nov 2022 18:01:53 +0530
Subject: [PATCH 128/138] suggested fixes
---
.../org/oppia/android/app/spotlight/SpotlightFragment.kt | 8 ++++----
app/src/main/res/layout/bottom_left_overlay.xml | 4 ++--
app/src/main/res/layout/bottom_right_overlay.xml | 4 ++--
app/src/main/res/layout/top_left_overlay.xml | 6 +++---
app/src/main/res/layout/top_right_overlay.xml | 9 ++++-----
app/src/main/res/values/strings.xml | 4 ++--
.../app/player/exploration/ExplorationActivityTest.kt | 6 +++---
7 files changed, 20 insertions(+), 21 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
index 493d81ee9c2..689c8320f3e 100644
--- a/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/spotlight/SpotlightFragment.kt
@@ -5,7 +5,7 @@ import android.os.Bundle
import android.util.DisplayMetrics
import android.view.View
import android.view.ViewGroup.MarginLayoutParams
-import android.view.animation.DecelerateInterpolator
+import android.view.animation.AccelerateInterpolator
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.doOnPreDraw
@@ -137,7 +137,7 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
}
override fun onEnded() {
- targetList.removeFirst()
+ if (targetList.isNotEmpty()) targetList.removeFirst()
val profileId = ProfileId.newBuilder()
.setInternalId(internalProfileId)
.build()
@@ -155,8 +155,8 @@ class SpotlightFragment : InjectableFragment(), SpotlightNavigationListener, Spo
spotlight = Spotlight.Builder(activity)
.setTargets(targetList)
.setBackgroundColorRes(R.color.spotlight_overlay_background)
- .setDuration(1000L)
- .setAnimation(DecelerateInterpolator(2f))
+ .setDuration(500L)
+ .setAnimation(AccelerateInterpolator(0.5f))
.setOnSpotlightListener(object : OnSpotlightListener {
override fun onStarted() {
isSpotlightActive = true
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 55e931dbee7..14ef08d643d 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -55,7 +55,7 @@
android:minHeight="48dp"
android:onClick="@{(v) -> listener.clickOnDone()}"
android:text="@string/mark_spotlight_seen_button_text"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintEnd_toEndOf="parent" />
+ app:layout_constraintBottom_toTopOf="@id/spotlight_hint_text"
+ app:layout_constraintEnd_toEndOf="@id/spotlight_hint_text" />
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index ac9031c479b..0881703d760 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -56,7 +56,7 @@
android:minHeight="48dp"
android:onClick="@{(v) -> listener.clickOnDone()}"
android:text="@string/mark_spotlight_seen_button_text"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
+ app:layout_constraintBottom_toTopOf="@id/spotlight_hint_text"
+ app:layout_constraintEnd_toEndOf="@id/spotlight_hint_text" />
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index 564c7062763..2e519198f12 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -47,7 +47,7 @@
style="@style/StateButtonActive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginEnd="8dp"
+ android:layout_marginTop="8dp"
android:layout_marginBottom="24dp"
android:background="@drawable/spotlight_done_button_background"
android:gravity="center"
@@ -55,7 +55,7 @@
android:minHeight="48dp"
android:onClick="@{(v) -> listener.clickOnDone()}"
android:text="@string/mark_spotlight_seen_button_text"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent" />
+ app:layout_constraintEnd_toEndOf="@id/spotlight_hint_text"
+ app:layout_constraintTop_toBottomOf="@id/spotlight_hint_text" />
diff --git a/app/src/main/res/layout/top_right_overlay.xml b/app/src/main/res/layout/top_right_overlay.xml
index 676a2dedf33..e7bcb3ee2a5 100644
--- a/app/src/main/res/layout/top_right_overlay.xml
+++ b/app/src/main/res/layout/top_right_overlay.xml
@@ -32,6 +32,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
+ android:layout_marginEnd="20dp"
android:background="@drawable/spotlight_hint_text_background"
android:paddingStart="8dp"
android:paddingTop="4dp"
@@ -47,15 +48,13 @@
style="@style/StateButtonActive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginEnd="8dp"
- android:layout_marginBottom="24dp"
+ android:layout_marginTop="8dp"
android:background="@drawable/spotlight_done_button_background"
- android:gravity="center"
android:minWidth="160dp"
android:minHeight="48dp"
android:onClick="@{(v) -> listener.clickOnDone()}"
android:text="@string/mark_spotlight_seen_button_text"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent" />
+ app:layout_constraintEnd_toEndOf="@id/spotlight_hint_text"
+ app:layout_constraintTop_toBottomOf="@id/spotlight_hint_text" />
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 66ced1cb021..c1009220ee9 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -38,8 +38,8 @@
Cancel
Leave
Exit anytime using this button. We will save your progress.
- Would you like %s to read for you? Tap on this button to try!
- Tap to change voiceover language.
+ Would you like %s to read for you? Tap on this button to try it!
+ Tap to change the voiceover language.
Maximum storage capacity reached
Saved progress for the lesson \"%s\" will be deleted.
Continue
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
index d87a4e00569..c7a14e337e8 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
@@ -587,7 +587,7 @@ class ExplorationActivityTest {
)
testCoroutineDispatchers.runCurrent()
- onView(withText("Would you like Oppia to read for you? Tap on this button to try!"))
+ onView(withText("Would you like Oppia to read for you? Tap on this button to try it!"))
.check(matches(isDisplayed()))
}
}
@@ -633,7 +633,7 @@ class ExplorationActivityTest {
)
testCoroutineDispatchers.runCurrent()
- onView(withText("Would you like Oppia to read for you? Tap on this button to try!"))
+ onView(withText("Would you like Oppia to read for you? Tap on this button to try it!"))
.check(doesNotExist())
}
}
@@ -659,7 +659,7 @@ class ExplorationActivityTest {
)
testCoroutineDispatchers.runCurrent()
- onView(withText("Would you like Oppia to read for you? Tap on this button to try!"))
+ onView(withText("Would you like Oppia to read for you? Tap on this button to try it!"))
.check(doesNotExist())
}
}
From 477a7d90b1da79722fe94d05a9f098b4c2509f83 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 24 Nov 2022 22:40:15 +0530
Subject: [PATCH 129/138] remove onboarding spotlight
---
.../onboarding/OnboardingActivityPresenter.kt | 18 ----------
.../app/onboarding/OnboardingFragment.kt | 5 ---
.../onboarding/OnboardingFragmentPresenter.kt | 21 ------------
.../main/res/layout/onboarding_activity.xml | 5 ---
app/src/main/res/values/strings.xml | 1 -
.../app/onboarding/OnboardingFragmentTest.kt | 24 -------------
.../spotlight/SpotlightStateController.kt | 3 --
.../spotlight/SpotlightStateControllerTest.kt | 18 ----------
model/src/main/proto/spotlight.proto | 34 ++++++++-----------
9 files changed, 14 insertions(+), 115 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
index 79108be1bd6..abbe74efc5b 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
@@ -3,8 +3,6 @@ package org.oppia.android.app.onboarding
import androidx.appcompat.app.AppCompatActivity
import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
-import org.oppia.android.app.spotlight.SpotlightFragment
-import org.oppia.android.app.spotlight.SpotlightManager
import javax.inject.Inject
/** The presenter for [OnboardingActivity]. */
@@ -18,14 +16,6 @@ class OnboardingActivityPresenter @Inject constructor(private val activity: AppC
OnboardingFragment()
).commitNow()
}
-
- if (getSpotlightFragment() == null) {
- activity.supportFragmentManager.beginTransaction().add(
- R.id.onboarding_spotlight_fragment_placeholder,
- SpotlightFragment.newInstance(internalProfileId = 0),
- SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
- ).commitNow()
- }
}
private fun getOnboardingFragment(): OnboardingFragment? {
@@ -35,12 +25,4 @@ class OnboardingActivityPresenter @Inject constructor(private val activity: AppC
R.id.onboarding_fragment_placeholder
) as OnboardingFragment?
}
-
- private fun getSpotlightFragment(): SpotlightFragment? {
- return activity
- .supportFragmentManager
- .findFragmentById(
- R.id.onboarding_spotlight_fragment_placeholder
- ) as? SpotlightFragment
- }
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
index 64dc76f9fac..081abae41ee 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
@@ -26,9 +26,4 @@ class OnboardingFragment : InjectableFragment() {
): View? {
return onboardingFragmentPresenter.handleCreateView(inflater, container)
}
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- onboardingFragmentPresenter.startSpotlight()
- }
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index 532de574b6c..4fc99927934 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -11,13 +11,8 @@ import androidx.viewpager2.widget.ViewPager2
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.PolicyPage
-import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.policies.RouteToPoliciesListener
import org.oppia.android.app.recyclerview.BindableAdapter
-import org.oppia.android.app.spotlight.SpotlightFragment
-import org.oppia.android.app.spotlight.SpotlightManager
-import org.oppia.android.app.spotlight.SpotlightShape
-import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.OnboardingFragmentBinding
@@ -60,22 +55,6 @@ class OnboardingFragmentPresenter @Inject constructor(
return binding.root
}
- private fun getSpotlightFragment(): SpotlightFragment? {
- return activity.supportFragmentManager.findFragmentByTag(
- SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
- ) as? SpotlightFragment
- }
-
- fun startSpotlight() {
- val nextSpotlightTarget = SpotlightTarget(
- binding.onboardingFragmentNextImageView,
- resourceHandler.getStringInLocale(R.string.onboarding_next_button_spotlight_hint),
- SpotlightShape.Circle,
- Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON
- )
- checkNotNull(getSpotlightFragment()).requestSpotlightViewWithDelayedLayout(nextSpotlightTarget)
- }
-
private fun setUpViewPager() {
val onboardingViewPagerBindableAdapter = createViewPagerAdapter()
onboardingViewPagerBindableAdapter.setData(
diff --git a/app/src/main/res/layout/onboarding_activity.xml b/app/src/main/res/layout/onboarding_activity.xml
index 04ecacc8a1a..2dcc189a3f8 100644
--- a/app/src/main/res/layout/onboarding_activity.xml
+++ b/app/src/main/res/layout/onboarding_activity.xml
@@ -5,11 +5,6 @@
android:layout_height="match_parent"
tools:context="app.onboarding.OnboardingActivity">
-
-
Profile Edit Fragment Test Activity
Administrator Controls Fragment Test Activity
Continue Studying
- Next
Go to the bottom of the screen for a hint.
Done
diff --git a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
index 2d1d8f883de..e599a03cf6b 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
@@ -223,30 +223,6 @@ class OnboardingFragmentTest {
}
}
- @Test
- fun testNextButtonSpotlight_setToShowOnStartup_checkSpotlightIsShown() {
- launch(OnboardingActivity::class.java).use {
- testCoroutineDispatchers.runCurrent()
- onView(withText(R.string.onboarding_next_button_spotlight_hint)).check(matches(isDisplayed()))
- }
- }
-
- @Test
- fun testOnboardingFragment_checkDefaultSlide_clickSkipButton_shiftsToLastSlide() {
- launch(OnboardingActivity::class.java).use {
- testCoroutineDispatchers.runCurrent()
- skipNextSlideButtonSpotlight()
- onView(withId(R.id.skip_text_view)).perform(click())
- testCoroutineDispatchers.runCurrent()
- onView(
- allOf(
- withId(R.id.slide_title_text_view),
- isCompletelyDisplayed()
- )
- ).check(matches(withText(R.string.onboarding_slide_3_title)))
- }
- }
-
@Test
fun testOnboardingFragment_checkDefaultSlide_getStartedButtonIsNotVisible() {
launch(OnboardingActivity::class.java).use {
diff --git a/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt b/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
index 67ef51bff7f..741ea69fd41 100644
--- a/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
+++ b/domain/src/main/java/org/oppia/android/domain/spotlight/SpotlightStateController.kt
@@ -6,7 +6,6 @@ import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.model.Spotlight.FeatureCase.FEATURE_NOT_SET
import org.oppia.android.app.model.Spotlight.FeatureCase.FIRST_CHAPTER
import org.oppia.android.app.model.Spotlight.FeatureCase.LESSONS_BACK_BUTTON
-import org.oppia.android.app.model.Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON
import org.oppia.android.app.model.Spotlight.FeatureCase.PROMOTED_STORIES
import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_LESSON_TAB
import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_REVISION_TAB
@@ -86,7 +85,6 @@ class SpotlightStateController @Inject constructor(
RETRIEVE_SPOTLIGHT_CHECKPOINT_DATA_PROVIDER_ID
) {
val viewState = when (feature) {
- ONBOARDING_NEXT_BUTTON -> it.onboardingNextButton
TOPIC_LESSON_TAB -> it.topicLessonTab
TOPIC_REVISION_TAB -> it.topicRevisionTab
FIRST_CHAPTER -> it.firstChapter
@@ -117,7 +115,6 @@ class SpotlightStateController @Inject constructor(
) { spotlightStateDatabase ->
spotlightStateDatabase.toBuilder().run {
when (feature) {
- ONBOARDING_NEXT_BUTTON -> this.setOnboardingNextButton(viewState)
TOPIC_LESSON_TAB -> this.setTopicLessonTab(viewState)
TOPIC_REVISION_TAB -> this.setTopicRevisionTab(viewState)
FIRST_CHAPTER -> this.setFirstChapter(viewState)
diff --git a/domain/src/test/java/org/oppia/android/domain/spotlight/SpotlightStateControllerTest.kt b/domain/src/test/java/org/oppia/android/domain/spotlight/SpotlightStateControllerTest.kt
index 1011e4c6122..2a1ecdde597 100644
--- a/domain/src/test/java/org/oppia/android/domain/spotlight/SpotlightStateControllerTest.kt
+++ b/domain/src/test/java/org/oppia/android/domain/spotlight/SpotlightStateControllerTest.kt
@@ -16,7 +16,6 @@ import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.model.Spotlight.FeatureCase.FIRST_CHAPTER
import org.oppia.android.app.model.Spotlight.FeatureCase.LESSONS_BACK_BUTTON
-import org.oppia.android.app.model.Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON
import org.oppia.android.app.model.Spotlight.FeatureCase.PROMOTED_STORIES
import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_LESSON_TAB
import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_REVISION_TAB
@@ -147,23 +146,6 @@ class SpotlightStateControllerTest {
assertThat(result).isEqualTo(SpotlightViewState.SPOTLIGHT_SEEN)
}
- @Test
- fun testRetrieveSpotlightViewState_onboardingNext_notMarked_returnsSpotlightStateNotSeen() {
- val retrieveSpotlightStateProvider =
- spotlightStateController.retrieveSpotlightViewState(profileId0, ONBOARDING_NEXT_BUTTON)
- val result = dataProviderTestMonitor.waitForNextSuccessfulResult(retrieveSpotlightStateProvider)
- assertThat(result).isEqualTo(SpotlightViewState.SPOTLIGHT_NOT_SEEN)
- }
-
- @Test
- fun testRetrieveSpotlightViewState_onboardingNext_marked_returnsSpotlightStateSeen() {
- markSpotlightSeen(ONBOARDING_NEXT_BUTTON)
- val retrieveSpotlightStateProvider =
- spotlightStateController.retrieveSpotlightViewState(profileId0, ONBOARDING_NEXT_BUTTON)
- val result = dataProviderTestMonitor.waitForNextSuccessfulResult(retrieveSpotlightStateProvider)
- assertThat(result).isEqualTo(SpotlightViewState.SPOTLIGHT_SEEN)
- }
-
@Test
fun testRetrieveSpotlightViewState_topicLessonTab_notMarked_returnsSpotlightStateNotSeen() {
val retrieveSpotlightStateProvider =
diff --git a/model/src/main/proto/spotlight.proto b/model/src/main/proto/spotlight.proto
index 1f4e345d427..24b655a8ed0 100644
--- a/model/src/main/proto/spotlight.proto
+++ b/model/src/main/proto/spotlight.proto
@@ -10,29 +10,26 @@ option java_multiple_files = true;
message Spotlight {
// Determines the UI element being spotlit.
oneof feature {
- // Corresponds to the onboarding screen's next button.
- SpotlightViewState onboarding_next_button = 1;
-
// Corresponds to the topic fragment's lessons tab.
- SpotlightViewState topic_lesson_tab = 2;
+ SpotlightViewState topic_lesson_tab = 1;
// Corresponds to the topic fragment's revision tab.
- SpotlightViewState topic_revision_tab = 3;
+ SpotlightViewState topic_revision_tab = 2;
// Corresponds to the first lesson under lessons tab.
- SpotlightViewState first_chapter = 4;
+ SpotlightViewState first_chapter = 3;
// Corresponds to the promoted stories.
- SpotlightViewState promoted_stories = 5;
+ SpotlightViewState promoted_stories = 4;
// Corresponds to the back button in exploration screen.
- SpotlightViewState lessons_back_button = 6;
+ SpotlightViewState lessons_back_button = 5;
// Corresponds to the voice-over icon in exploration screen.
- SpotlightViewState voiceover_play_icon = 7;
+ SpotlightViewState voiceover_play_icon = 6;
// Corresponds to the voice-over language option in audio player.
- SpotlightViewState voiceover_language_icon = 8;
+ SpotlightViewState voiceover_language_icon = 7;
}
}
@@ -51,27 +48,24 @@ enum SpotlightViewState {
// Top level proto that will be used to store SpotlightsViewStates per user profile.
message SpotlightStateDatabase {
- // Corresponds to the onboarding screen's next button.
- SpotlightViewState onboarding_next_button = 1;
-
// Corresponds to the topic fragment's lessons tab.
- SpotlightViewState topic_lesson_tab = 2;
+ SpotlightViewState topic_lesson_tab = 1;
// Corresponds to the topic fragment's revision tab.
- SpotlightViewState topic_revision_tab = 3;
+ SpotlightViewState topic_revision_tab = 2;
// Corresponds to the first lesson under lessons tab.
- SpotlightViewState first_chapter = 4;
+ SpotlightViewState first_chapter = 3;
// Corresponds to the promoted stories.
- SpotlightViewState promoted_stories = 5;
+ SpotlightViewState promoted_stories = 4;
// Corresponds to the back button in exploration screen.
- SpotlightViewState lessons_back_button = 6;
+ SpotlightViewState lessons_back_button = 5;
// Corresponds to the voice-over icon in exploration screen.
- SpotlightViewState voiceover_play_icon = 7;
+ SpotlightViewState voiceover_play_icon = 6;
// Corresponds to the voice-over language option in audio player.
- SpotlightViewState voiceover_language_icon = 8;
+ SpotlightViewState voiceover_language_icon = 7;
}
From 1dd1cdbc6274f8f8444d9f2636241fa4dd7a1bd4 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Thu, 24 Nov 2022 23:15:04 +0530
Subject: [PATCH 130/138] fix conflicts introduced with onboarding screen
spotlight after merge with develop
---
.../onboarding/OnboardingActivityPresenter.kt | 18 ----------------
.../app/onboarding/OnboardingFragment.kt | 5 -----
.../onboarding/OnboardingFragmentPresenter.kt | 21 -------------------
3 files changed, 44 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
index 79108be1bd6..abbe74efc5b 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt
@@ -3,8 +3,6 @@ package org.oppia.android.app.onboarding
import androidx.appcompat.app.AppCompatActivity
import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
-import org.oppia.android.app.spotlight.SpotlightFragment
-import org.oppia.android.app.spotlight.SpotlightManager
import javax.inject.Inject
/** The presenter for [OnboardingActivity]. */
@@ -18,14 +16,6 @@ class OnboardingActivityPresenter @Inject constructor(private val activity: AppC
OnboardingFragment()
).commitNow()
}
-
- if (getSpotlightFragment() == null) {
- activity.supportFragmentManager.beginTransaction().add(
- R.id.onboarding_spotlight_fragment_placeholder,
- SpotlightFragment.newInstance(internalProfileId = 0),
- SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
- ).commitNow()
- }
}
private fun getOnboardingFragment(): OnboardingFragment? {
@@ -35,12 +25,4 @@ class OnboardingActivityPresenter @Inject constructor(private val activity: AppC
R.id.onboarding_fragment_placeholder
) as OnboardingFragment?
}
-
- private fun getSpotlightFragment(): SpotlightFragment? {
- return activity
- .supportFragmentManager
- .findFragmentById(
- R.id.onboarding_spotlight_fragment_placeholder
- ) as? SpotlightFragment
- }
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
index 64dc76f9fac..081abae41ee 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragment.kt
@@ -26,9 +26,4 @@ class OnboardingFragment : InjectableFragment() {
): View? {
return onboardingFragmentPresenter.handleCreateView(inflater, container)
}
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- onboardingFragmentPresenter.startSpotlight()
- }
}
diff --git a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
index 532de574b6c..4fc99927934 100644
--- a/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt
@@ -11,13 +11,8 @@ import androidx.viewpager2.widget.ViewPager2
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.PolicyPage
-import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.policies.RouteToPoliciesListener
import org.oppia.android.app.recyclerview.BindableAdapter
-import org.oppia.android.app.spotlight.SpotlightFragment
-import org.oppia.android.app.spotlight.SpotlightManager
-import org.oppia.android.app.spotlight.SpotlightShape
-import org.oppia.android.app.spotlight.SpotlightTarget
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.OnboardingFragmentBinding
@@ -60,22 +55,6 @@ class OnboardingFragmentPresenter @Inject constructor(
return binding.root
}
- private fun getSpotlightFragment(): SpotlightFragment? {
- return activity.supportFragmentManager.findFragmentByTag(
- SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
- ) as? SpotlightFragment
- }
-
- fun startSpotlight() {
- val nextSpotlightTarget = SpotlightTarget(
- binding.onboardingFragmentNextImageView,
- resourceHandler.getStringInLocale(R.string.onboarding_next_button_spotlight_hint),
- SpotlightShape.Circle,
- Spotlight.FeatureCase.ONBOARDING_NEXT_BUTTON
- )
- checkNotNull(getSpotlightFragment()).requestSpotlightViewWithDelayedLayout(nextSpotlightTarget)
- }
-
private fun setUpViewPager() {
val onboardingViewPagerBindableAdapter = createViewPagerAdapter()
onboardingViewPagerBindableAdapter.setData(
From 8848ecd97ada2e9d5b1962754550cfbd099afa1a Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 25 Nov 2022 00:30:25 +0530
Subject: [PATCH 131/138] fix conflicts introduced with onboarding screen
spotlight after merge with develop
---
.../android/app/onboarding/OnboardingFragmentTest.kt | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
index e599a03cf6b..38a101f185b 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
@@ -315,7 +315,6 @@ class OnboardingFragmentTest {
fun testOnboardingFragment_checkSlide1_clickSkipButton_shiftsToLastSlide() {
launch(OnboardingActivity::class.java).use {
testCoroutineDispatchers.runCurrent()
- skipNextSlideButtonSpotlight()
onView(withId(R.id.onboarding_slide_view_pager)).perform(scrollToPosition(position = 1))
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.skip_text_view)).perform(click())
@@ -424,7 +423,6 @@ class OnboardingFragmentTest {
fun testOnboardingFragment_checkSlide2_clickSkipButton_shiftsToLastSlide() {
launch(OnboardingActivity::class.java).use {
testCoroutineDispatchers.runCurrent()
- skipNextSlideButtonSpotlight()
onView(withId(R.id.onboarding_slide_view_pager)).perform(scrollToPosition(position = 2))
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.skip_text_view)).perform(click())
@@ -496,7 +494,6 @@ class OnboardingFragmentTest {
fun testOnboardingFragment_checkSlide3_clickGetStartedButton_opensProfileActivity() {
launch(OnboardingActivity::class.java).use {
testCoroutineDispatchers.runCurrent()
- skipNextSlideButtonSpotlight()
onView(withId(R.id.onboarding_slide_view_pager)).perform(scrollToPosition(position = 3))
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.get_started_button)).perform(scrollTo(), click())
@@ -552,7 +549,6 @@ class OnboardingFragmentTest {
fun testOnboardingFragment_clickOnSkip_changeOrientation_titleIsCorrect() {
launch(OnboardingActivity::class.java).use {
testCoroutineDispatchers.runCurrent()
- skipNextSlideButtonSpotlight()
onView(withId(R.id.skip_text_view)).perform(click())
testCoroutineDispatchers.runCurrent()
onView(isRoot()).perform(orientationLandscape())
@@ -658,7 +654,6 @@ class OnboardingFragmentTest {
fun testOnboardingFragment_checkSlide3_policiesLinkIsVisible() {
launch(OnboardingActivity::class.java).use {
testCoroutineDispatchers.runCurrent()
- skipNextSlideButtonSpotlight()
onView(withId(R.id.skip_text_view)).perform(click())
testCoroutineDispatchers.runCurrent()
onView(withId(R.id.slide_terms_of_service_and_privacy_policy_links_text_view)).perform(
@@ -696,10 +691,6 @@ class OnboardingFragmentTest {
}
}
- private fun skipNextSlideButtonSpotlight() {
- onView(withId(R.id.close_spotlight_button)).perform(click())
- }
-
// TODO(#59): Figure out a way to reuse modules instead of needing to re-declare them.
@Singleton
@Component(
From 3b8d2c6e8c69e1b7d323e3a02107912a8188fad5 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 25 Nov 2022 02:48:27 +0530
Subject: [PATCH 132/138] finalise done button
---
app/src/main/res/layout/bottom_left_overlay.xml | 5 ++---
app/src/main/res/layout/bottom_right_overlay.xml | 5 ++---
app/src/main/res/layout/top_left_overlay.xml | 1 +
app/src/main/res/layout/top_right_overlay.xml | 1 +
app/src/main/res/values/strings.xml | 2 +-
5 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 14ef08d643d..47de5f0aa07 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -47,15 +47,14 @@
style="@style/StateButtonActive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginEnd="8dp"
- android:layout_marginTop="48dp"
+ android:layout_marginEnd="0dp"
android:background="@drawable/spotlight_done_button_background"
android:gravity="center"
android:minWidth="160dp"
android:minHeight="48dp"
android:onClick="@{(v) -> listener.clickOnDone()}"
android:text="@string/mark_spotlight_seen_button_text"
- app:layout_constraintBottom_toTopOf="@id/spotlight_hint_text"
+ app:layout_constraintTop_toBottomOf="@id/spotlight_hint_text"
app:layout_constraintEnd_toEndOf="@id/spotlight_hint_text" />
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index 0881703d760..d8cbdeae7d3 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -48,15 +48,14 @@
style="@style/StateButtonActive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="48dp"
- android:layout_marginEnd="8dp"
+ android:layout_marginEnd="0dp"
android:background="@drawable/spotlight_done_button_background"
android:gravity="center"
android:minWidth="160dp"
android:minHeight="48dp"
android:onClick="@{(v) -> listener.clickOnDone()}"
android:text="@string/mark_spotlight_seen_button_text"
- app:layout_constraintBottom_toTopOf="@id/spotlight_hint_text"
+ app:layout_constraintTop_toBottomOf="@id/spotlight_hint_text"
app:layout_constraintEnd_toEndOf="@id/spotlight_hint_text" />
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index 2e519198f12..4ce0262f19f 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -48,6 +48,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
+ android:layout_marginEnd="0dp"
android:layout_marginBottom="24dp"
android:background="@drawable/spotlight_done_button_background"
android:gravity="center"
diff --git a/app/src/main/res/layout/top_right_overlay.xml b/app/src/main/res/layout/top_right_overlay.xml
index e7bcb3ee2a5..c24bfebcdcf 100644
--- a/app/src/main/res/layout/top_right_overlay.xml
+++ b/app/src/main/res/layout/top_right_overlay.xml
@@ -49,6 +49,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
+ android:layout_marginEnd="0dp"
android:background="@drawable/spotlight_done_button_background"
android:minWidth="160dp"
android:minHeight="48dp"
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c932d82a2fc..7dbddad746f 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -584,5 +584,5 @@
Administrator Controls Fragment Test Activity
Continue Studying
Go to the bottom of the screen for a hint.
- Done
+ Close
From 5f37d6b3aac2b47fcb58ed2ea7e9cb29a746c559 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 25 Nov 2022 17:44:34 +0530
Subject: [PATCH 133/138] cross button
---
app/src/main/res/drawable/ic_close_black_24.xml | 9 +++++++++
.../drawable/spotlight_done_button_background.xml | 8 ++------
app/src/main/res/layout/bottom_left_overlay.xml | 13 ++++++-------
app/src/main/res/layout/top_left_overlay.xml | 13 +++++--------
app/src/main/res/layout/top_right_overlay.xml | 13 +++++++------
5 files changed, 29 insertions(+), 27 deletions(-)
create mode 100644 app/src/main/res/drawable/ic_close_black_24.xml
diff --git a/app/src/main/res/drawable/ic_close_black_24.xml b/app/src/main/res/drawable/ic_close_black_24.xml
new file mode 100644
index 00000000000..e54a4c301a7
--- /dev/null
+++ b/app/src/main/res/drawable/ic_close_black_24.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/spotlight_done_button_background.xml b/app/src/main/res/drawable/spotlight_done_button_background.xml
index f5d71620f06..8cb2452157e 100644
--- a/app/src/main/res/drawable/spotlight_done_button_background.xml
+++ b/app/src/main/res/drawable/spotlight_done_button_background.xml
@@ -1,9 +1,5 @@
-
-
-
+ android:shape="oval">
+
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 47de5f0aa07..231e68037eb 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -42,19 +42,18 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/spotlight_overlay_arrow" />
-
+ app:layout_constraintEnd_toEndOf="@id/spotlight_hint_text"
+ app:layout_constraintBottom_toTopOf="@id/spotlight_hint_text" />
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index 4ce0262f19f..057b45073ae 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -42,21 +42,18 @@
app:layout_constraintStart_toStartOf="@id/spotlight_overlay_arrow"
app:layout_constraintTop_toBottomOf="@id/spotlight_overlay_arrow" />
-
+ app:layout_constraintBottom_toTopOf="@id/spotlight_hint_text"/>
diff --git a/app/src/main/res/layout/top_right_overlay.xml b/app/src/main/res/layout/top_right_overlay.xml
index c24bfebcdcf..7dfd1bfcf88 100644
--- a/app/src/main/res/layout/top_right_overlay.xml
+++ b/app/src/main/res/layout/top_right_overlay.xml
@@ -43,19 +43,20 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/spotlight_overlay_arrow" />
-
+ app:layout_constraintStart_toStartOf="@id/spotlight_hint_text"
+ app:layout_constraintBottom_toTopOf="@id/spotlight_hint_text"/>
From 6caf6b4d7478c744ba5a8ffb226082e75bdfd3d5 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 25 Nov 2022 21:57:56 +0530
Subject: [PATCH 134/138] finalise cross button design
---
.../main/res/layout/bottom_left_overlay.xml | 58 ++++++++++-------
.../main/res/layout/bottom_right_overlay.xml | 60 +++++++++++-------
app/src/main/res/layout/top_left_overlay.xml | 56 ++++++++++-------
app/src/main/res/layout/top_right_overlay.xml | 63 +++++++++++--------
4 files changed, 141 insertions(+), 96 deletions(-)
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 231e68037eb..39af44ad7e4 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -25,35 +25,47 @@
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_rounded_arrow_up_right" />
-
+ app:layout_constraintStart_toStartOf="@+id/spotlight_overlay_arrow">
-
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index d8cbdeae7d3..9e01feb8816 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -27,35 +27,47 @@
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_rounded_arrow_up_right" />
-
+ app:layout_constraintStart_toStartOf="parent">
-
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index 057b45073ae..f7343144479 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -25,35 +25,45 @@
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_rounded_arrow_up_right" />
-
+ app:layout_constraintTop_toBottomOf="@id/spotlight_overlay_arrow">
-
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/top_right_overlay.xml b/app/src/main/res/layout/top_right_overlay.xml
index 7dfd1bfcf88..c12b9c03985 100644
--- a/app/src/main/res/layout/top_right_overlay.xml
+++ b/app/src/main/res/layout/top_right_overlay.xml
@@ -26,37 +26,48 @@
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_rounded_arrow_up_right" />
-
+ app:layout_constraintTop_toBottomOf="@id/spotlight_overlay_arrow"
+ >
-
+
+
+
+
+
+
+
From 14f8e88c64e9fd7e33a97feef4c553b4bd876132 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Fri, 25 Nov 2022 23:46:34 +0530
Subject: [PATCH 135/138] use spotlight manager instead
---
.../ChapterNotStartedContainerConstraintLayout.kt | 4 ++--
.../android/app/customview/PromotedStoryCardView.kt | 4 ++--
.../app/player/audio/AudioFragmentPresenter.kt | 9 ++++-----
.../exploration/ExplorationActivityPresenter.kt | 8 ++++----
.../exploration/ExplorationFragmentPresenter.kt | 7 +++----
.../oppia/android/app/topic/TopicFragmentPresenter.kt | 11 +++++------
6 files changed, 20 insertions(+), 23 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
index 5df58e5522f..b20920c763a 100644
--- a/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/ChapterNotStartedContainerConstraintLayout.kt
@@ -38,7 +38,7 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
this.index = index
}
- private fun getSpotlightFragment(): SpotlightManager? {
+ private fun getSpotlightManager(): SpotlightManager? {
return fragment.requireActivity().supportFragmentManager.findFragmentByTag(
SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
) as? SpotlightManager
@@ -60,7 +60,7 @@ class ChapterNotStartedContainerConstraintLayout @JvmOverloads constructor(
feature = Spotlight.FeatureCase.FIRST_CHAPTER
)
if (index == 0) {
- checkNotNull(getSpotlightFragment()).requestSpotlightViewWithDelayedLayout(spotlightTarget)
+ checkNotNull(getSpotlightManager()).requestSpotlightViewWithDelayedLayout(spotlightTarget)
}
}
}
diff --git a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
index 3b0eb0129f2..ca104409df7 100644
--- a/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
+++ b/app/src/main/java/org/oppia/android/app/customview/PromotedStoryCardView.kt
@@ -40,11 +40,11 @@ class PromotedStoryCardView @JvmOverloads constructor(
resourceHandler.getStringInLocale(R.string.promoted_story_spotlight_hint),
feature = Spotlight.FeatureCase.PROMOTED_STORIES
)
- checkNotNull(getSpotlightFragment()).requestSpotlightViewWithDelayedLayout(spotlightTarget)
+ checkNotNull(getSpotlightManager()).requestSpotlightViewWithDelayedLayout(spotlightTarget)
}
}
- private fun getSpotlightFragment(): SpotlightManager? {
+ private fun getSpotlightManager(): SpotlightManager? {
return fragment.requireActivity().supportFragmentManager.findFragmentByTag(
SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
) as? SpotlightManager
diff --git a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
index 22d02a3f94a..08804ac5817 100755
--- a/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/audio/AudioFragmentPresenter.kt
@@ -22,7 +22,6 @@ import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.model.State
import org.oppia.android.app.player.audio.AudioViewModel.UiAudioPlayStatus
-import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
@@ -130,15 +129,15 @@ class AudioFragmentPresenter @Inject constructor(
Spotlight.FeatureCase.VOICEOVER_LANGUAGE_ICON
)
- checkNotNull(getSpotlightFragment()).requestSpotlightViewWithDelayedLayout(
+ checkNotNull(getSpotlightManager()).requestSpotlightViewWithDelayedLayout(
audioLanguageIconSpotlightTarget
)
}
- private fun getSpotlightFragment(): SpotlightFragment? {
- return activity.supportFragmentManager.findFragmentByTag(
+ private fun getSpotlightManager(): SpotlightManager? {
+ return fragment.requireActivity().supportFragmentManager.findFragmentByTag(
SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
- ) as? SpotlightFragment
+ ) as? SpotlightManager
}
private fun getProfileData(): LiveData {
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
index 3bc3a0ba0cd..6c6c104b082 100644
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt
@@ -135,7 +135,7 @@ class ExplorationActivityPresenter @Inject constructor(
).commitNow()
}
- if (getSpotlightFragment() == null) {
+ if (getSpotlightManager() == null) {
activity.supportFragmentManager.beginTransaction().add(
R.id.exploration_spotlight_fragment_placeholder,
SpotlightFragment.newInstance(profileId.internalId),
@@ -160,16 +160,16 @@ class ExplorationActivityPresenter @Inject constructor(
SpotlightShape.Circle,
Spotlight.FeatureCase.VOICEOVER_PLAY_ICON
)
- checkNotNull(getSpotlightFragment()).requestSpotlight(audioPlayerSpotlightTarget)
+ checkNotNull(getSpotlightManager()).requestSpotlight(audioPlayerSpotlightTarget)
}
}
}
}
- private fun getSpotlightFragment(): SpotlightFragment? {
+ private fun getSpotlightManager(): SpotlightManager? {
return activity.supportFragmentManager.findFragmentByTag(
SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
- ) as? SpotlightFragment
+ ) as? SpotlightManager
}
fun loadExplorationFragment(readingTextSize: ReadingTextSize) {
diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
index 4b4652c5f63..a28f18c0664 100755
--- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationFragmentPresenter.kt
@@ -14,7 +14,6 @@ import org.oppia.android.app.model.ExplorationFragmentArguments
import org.oppia.android.app.model.ReadingTextSize
import org.oppia.android.app.model.Spotlight
import org.oppia.android.app.player.state.StateFragment
-import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
@@ -97,7 +96,7 @@ class ExplorationFragmentPresenter @Inject constructor(
SpotlightShape.Circle,
Spotlight.FeatureCase.LESSONS_BACK_BUTTON
)
- checkNotNull(getSpotlightFragment()).requestSpotlight(backButtonSpotlightTarget)
+ checkNotNull(getSpotlightManager()).requestSpotlight(backButtonSpotlightTarget)
}
}
@@ -105,10 +104,10 @@ class ExplorationFragmentPresenter @Inject constructor(
.requestVoiceOverIconSpotlight(numberOfLogins)
}
- private fun getSpotlightFragment(): SpotlightFragment? {
+ private fun getSpotlightManager(): SpotlightManager? {
return fragment.requireActivity().supportFragmentManager.findFragmentByTag(
SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
- ) as? SpotlightFragment
+ ) as? SpotlightManager
}
fun handlePlayAudio() {
diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
index 3fc9cda63c7..f04092a39b6 100644
--- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt
@@ -12,7 +12,6 @@ import com.google.android.material.tabs.TabLayoutMediator
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.Spotlight
-import org.oppia.android.app.spotlight.SpotlightFragment
import org.oppia.android.app.spotlight.SpotlightManager
import org.oppia.android.app.spotlight.SpotlightShape
import org.oppia.android.app.spotlight.SpotlightTarget
@@ -87,7 +86,7 @@ class TopicFragmentPresenter @Inject constructor(
SpotlightShape.RoundedRectangle,
Spotlight.FeatureCase.TOPIC_LESSON_TAB
)
- checkNotNull(getSpotlightFragment()).requestSpotlight(lessonsTabSpotlightTarget)
+ checkNotNull(getSpotlightManager()).requestSpotlight(lessonsTabSpotlightTarget)
if (numberOfChaptersCompleted > 2) {
val revisionTabView = tabLayout.getTabAt(computeTabPosition(TopicTab.REVISION))?.view
@@ -97,17 +96,17 @@ class TopicFragmentPresenter @Inject constructor(
SpotlightShape.RoundedRectangle,
Spotlight.FeatureCase.TOPIC_REVISION_TAB
)
- checkNotNull(getSpotlightFragment()).requestSpotlight(revisionTabSpotlightTarget)
+ checkNotNull(getSpotlightManager()).requestSpotlight(revisionTabSpotlightTarget)
}
}
}
}
}
- private fun getSpotlightFragment(): SpotlightFragment? {
- return activity.supportFragmentManager.findFragmentByTag(
+ private fun getSpotlightManager(): SpotlightManager? {
+ return fragment.requireActivity().supportFragmentManager.findFragmentByTag(
SpotlightManager.SPOTLIGHT_FRAGMENT_TAG
- ) as? SpotlightFragment
+ ) as? SpotlightManager
}
private fun setCurrentTab(tab: TopicTab) {
From ad499da685168b6c07e4f2173cd5ff3dec7b7525 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sat, 26 Nov 2022 03:28:03 +0530
Subject: [PATCH 136/138] commit before checkout
---
app/src/main/res/layout/top_left_overlay.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index f7343144479..1bc73de4ee4 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -51,6 +51,7 @@
android:paddingEnd="4dp"
android:paddingBottom="8dp"
android:textSize="20sp"
+ app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/close_spotlight_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
From 66cccae0d907c86ed03111e78207fdd14ef0f3aa Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sat, 26 Nov 2022 17:11:27 +0530
Subject: [PATCH 137/138] requested changes
---
.../main/res/layout/bottom_left_overlay.xml | 3 ++
.../main/res/layout/bottom_right_overlay.xml | 2 ++
app/src/main/res/layout/top_left_overlay.xml | 1 +
app/src/main/res/layout/top_right_overlay.xml | 5 +--
model/src/main/proto/spotlight.proto | 31 ++++++++++---------
5 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/app/src/main/res/layout/bottom_left_overlay.xml b/app/src/main/res/layout/bottom_left_overlay.xml
index 39af44ad7e4..820a9fb32af 100644
--- a/app/src/main/res/layout/bottom_left_overlay.xml
+++ b/app/src/main/res/layout/bottom_left_overlay.xml
@@ -3,6 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
+
@@ -51,6 +52,7 @@
android:paddingEnd="4dp"
android:paddingBottom="8dp"
android:textSize="20sp"
+ app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/close_spotlight_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -60,6 +62,7 @@
style="@style/StateButtonActive"
android:layout_width="48dp"
android:layout_height="48dp"
+ android:layout_marginTop="0dp"
android:background="@drawable/spotlight_done_button_background"
android:onClick="@{(v) -> listener.clickOnDone()}"
app:layout_constraintEnd_toEndOf="parent"
diff --git a/app/src/main/res/layout/bottom_right_overlay.xml b/app/src/main/res/layout/bottom_right_overlay.xml
index 9e01feb8816..836e1850e76 100644
--- a/app/src/main/res/layout/bottom_right_overlay.xml
+++ b/app/src/main/res/layout/bottom_right_overlay.xml
@@ -53,6 +53,7 @@
android:paddingEnd="4dp"
android:paddingBottom="8dp"
android:textSize="20sp"
+ app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/close_spotlight_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -62,6 +63,7 @@
style="@style/StateButtonActive"
android:layout_width="48dp"
android:layout_height="48dp"
+ android:layout_marginTop="0dp"
android:background="@drawable/spotlight_done_button_background"
android:onClick="@{(v) -> listener.clickOnDone()}"
app:layout_constraintEnd_toEndOf="parent"
diff --git a/app/src/main/res/layout/top_left_overlay.xml b/app/src/main/res/layout/top_left_overlay.xml
index 1bc73de4ee4..106668891e3 100644
--- a/app/src/main/res/layout/top_left_overlay.xml
+++ b/app/src/main/res/layout/top_left_overlay.xml
@@ -59,6 +59,7 @@
+ app:layout_constraintTop_toBottomOf="@id/spotlight_overlay_arrow">
@@ -62,6 +62,7 @@
style="@style/StateButtonActive"
android:layout_width="48dp"
android:layout_height="48dp"
+ android:layout_marginTop="0dp"
android:background="@drawable/spotlight_done_button_background"
android:onClick="@{(v) -> listener.clickOnDone()}"
app:layout_constraintEnd_toEndOf="parent"
diff --git a/model/src/main/proto/spotlight.proto b/model/src/main/proto/spotlight.proto
index 24b655a8ed0..d885c9c4faa 100644
--- a/model/src/main/proto/spotlight.proto
+++ b/model/src/main/proto/spotlight.proto
@@ -11,25 +11,25 @@ message Spotlight {
// Determines the UI element being spotlit.
oneof feature {
// Corresponds to the topic fragment's lessons tab.
- SpotlightViewState topic_lesson_tab = 1;
+ SpotlightViewState topic_lesson_tab = 2;
// Corresponds to the topic fragment's revision tab.
- SpotlightViewState topic_revision_tab = 2;
+ SpotlightViewState topic_revision_tab = 3;
// Corresponds to the first lesson under lessons tab.
- SpotlightViewState first_chapter = 3;
+ SpotlightViewState first_chapter = 4;
// Corresponds to the promoted stories.
- SpotlightViewState promoted_stories = 4;
+ SpotlightViewState promoted_stories = 5;
// Corresponds to the back button in exploration screen.
- SpotlightViewState lessons_back_button = 5;
+ SpotlightViewState lessons_back_button = 6;
// Corresponds to the voice-over icon in exploration screen.
- SpotlightViewState voiceover_play_icon = 6;
+ SpotlightViewState voiceover_play_icon = 7;
// Corresponds to the voice-over language option in audio player.
- SpotlightViewState voiceover_language_icon = 7;
+ SpotlightViewState voiceover_language_icon = 8;
}
}
@@ -48,24 +48,27 @@ enum SpotlightViewState {
// Top level proto that will be used to store SpotlightsViewStates per user profile.
message SpotlightStateDatabase {
+ // Corresponds to the onboarding screen's next button which was removed.
+ reserved 1;
+
// Corresponds to the topic fragment's lessons tab.
- SpotlightViewState topic_lesson_tab = 1;
+ SpotlightViewState topic_lesson_tab = 2;
// Corresponds to the topic fragment's revision tab.
- SpotlightViewState topic_revision_tab = 2;
+ SpotlightViewState topic_revision_tab = 3;
// Corresponds to the first lesson under lessons tab.
- SpotlightViewState first_chapter = 3;
+ SpotlightViewState first_chapter = 4;
// Corresponds to the promoted stories.
- SpotlightViewState promoted_stories = 4;
+ SpotlightViewState promoted_stories = 5;
// Corresponds to the back button in exploration screen.
- SpotlightViewState lessons_back_button = 5;
+ SpotlightViewState lessons_back_button = 6;
// Corresponds to the voice-over icon in exploration screen.
- SpotlightViewState voiceover_play_icon = 6;
+ SpotlightViewState voiceover_play_icon = 7;
// Corresponds to the voice-over language option in audio player.
- SpotlightViewState voiceover_language_icon = 7;
+ SpotlightViewState voiceover_language_icon = 8;
}
From c5690819350e1a11d9943a04254219f8d9c033b1 Mon Sep 17 00:00:00 2001
From: JishnuGoyal <64526117+JishnuGoyal@users.noreply.github.com>
Date: Sun, 27 Nov 2022 09:57:58 +0530
Subject: [PATCH 138/138] suggested changes
---
app/src/main/res/values/strings.xml | 1 -
model/src/main/proto/spotlight.proto | 4 ++++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7dbddad746f..073d27dcaf3 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -584,5 +584,4 @@
Administrator Controls Fragment Test Activity
Continue Studying
Go to the bottom of the screen for a hint.
- Close
diff --git a/model/src/main/proto/spotlight.proto b/model/src/main/proto/spotlight.proto
index d885c9c4faa..f6bad25532a 100644
--- a/model/src/main/proto/spotlight.proto
+++ b/model/src/main/proto/spotlight.proto
@@ -9,6 +9,10 @@ option java_multiple_files = true;
// the app that highlight certain UI elements and show how/what they should be used for.
message Spotlight {
// Determines the UI element being spotlit.
+
+ // Corresponds to the onboarding screen's next button which was removed.
+ reserved 1;
+
oneof feature {
// Corresponds to the topic fragment's lessons tab.
SpotlightViewState topic_lesson_tab = 2;