From 0cff83acdf5c6201909461e9194d4f64767a2058 Mon Sep 17 00:00:00 2001 From: kevingitonga Date: Tue, 7 Jun 2022 10:57:28 +0300 Subject: [PATCH 01/50] Fix #4186 Uncheck all selection on developer options not working --- .../MarkChaptersCompletedFragmentPresenter.kt | 11 +++++++++++ .../MarkStoriesCompletedFragmentPresenter.kt | 9 ++++++++- .../MarkTopicsCompletedFragmentPresenter.kt | 9 ++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt index 69bfbe61824..4ffdafd0040 100644 --- a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt @@ -78,6 +78,17 @@ class MarkChaptersCompletedFragmentPresenter @Inject constructor( ) } } + } else if (binding.isAllChecked == true) { + binding.isAllChecked = false + getMarkChaptersCompletedViewModel().getItemList().forEach { viewModel -> + if (viewModel is ChapterSummaryViewModel) { + if (!viewModel.checkIfChapterIsCompleted()) + chapterUnselected( + viewModel.chapterIndex, + viewModel.nextStoryIndex + ) + } + } } } diff --git a/app/src/main/java/org/oppia/android/app/devoptions/markstoriescompleted/MarkStoriesCompletedFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/devoptions/markstoriescompleted/MarkStoriesCompletedFragmentPresenter.kt index ccd9671bbd6..b58b07faaa6 100644 --- a/app/src/main/java/org/oppia/android/app/devoptions/markstoriescompleted/MarkStoriesCompletedFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/devoptions/markstoriescompleted/MarkStoriesCompletedFragmentPresenter.kt @@ -64,8 +64,11 @@ class MarkStoriesCompletedFragmentPresenter @Inject constructor( } binding.markStoriesCompletedAllCheckBoxContainer.setOnClickListener { - if (binding.isAllChecked == null || binding.isAllChecked == false) + if (binding.isAllChecked == null || binding.isAllChecked == false) { binding.isAllChecked = true + } else if (binding.isAllChecked == true) { + binding.isAllChecked = false + } } binding.markStoriesCompletedAllCheckBox.setOnCheckedChangeListener { _, isChecked -> @@ -74,6 +77,10 @@ class MarkStoriesCompletedFragmentPresenter @Inject constructor( if (!viewModel.isCompleted) storySelected(viewModel.storySummary.storyId) } + } else { + getMarkStoriesCompletedViewModel().getStorySummaryMap().values.forEach { viewModel -> + if (!viewModel.isCompleted) storyUnselected(viewModel.storySummary.storyId) + } } bindingAdapter.notifyDataSetChanged() } diff --git a/app/src/main/java/org/oppia/android/app/devoptions/marktopicscompleted/MarkTopicsCompletedFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/devoptions/marktopicscompleted/MarkTopicsCompletedFragmentPresenter.kt index 3d78e8bba4d..7d2ab4de700 100644 --- a/app/src/main/java/org/oppia/android/app/devoptions/marktopicscompleted/MarkTopicsCompletedFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/devoptions/marktopicscompleted/MarkTopicsCompletedFragmentPresenter.kt @@ -64,8 +64,11 @@ class MarkTopicsCompletedFragmentPresenter @Inject constructor( } binding.markTopicsCompletedAllCheckBoxContainer.setOnClickListener { - if (binding.isAllChecked == null || binding.isAllChecked == false) + if (binding.isAllChecked == null || binding.isAllChecked == false) { binding.isAllChecked = true + } else if (binding.isAllChecked == true) { + binding.isAllChecked = false + } } binding.markTopicsCompletedAllCheckBox.setOnCheckedChangeListener { _, isChecked -> @@ -73,6 +76,10 @@ class MarkTopicsCompletedFragmentPresenter @Inject constructor( getMarkTopicsCompletedViewModel().getTopicList().forEach { viewModel -> if (!viewModel.isCompleted) topicSelected(viewModel.topic.topicId) } + } else { + getMarkTopicsCompletedViewModel().getTopicList().forEach { viewModel -> + if (!viewModel.isCompleted) topicUnselected(viewModel.topic.topicId) + } } bindingAdapter.notifyDataSetChanged() } From 52953644cf88d75a5a0637b7b128e96bdbb1de42 Mon Sep 17 00:00:00 2001 From: kevingitonga Date: Wed, 8 Jun 2022 16:26:39 +0300 Subject: [PATCH 02/50] Fix #4186 Add changes to code as suggested on code review. --- .../MarkChaptersCompletedFragmentPresenter.kt | 8 ++------ .../MarkTopicsCompletedFragmentPresenter.kt | 6 +----- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt index 4ffdafd0040..3e59f1d393e 100644 --- a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt @@ -72,8 +72,7 @@ class MarkChaptersCompletedFragmentPresenter @Inject constructor( if (viewModel is ChapterSummaryViewModel) { if (!viewModel.checkIfChapterIsCompleted()) chapterSelected( - viewModel.chapterIndex, - viewModel.nextStoryIndex, + viewModel.chapterIndex, viewModel.nextStoryIndex, viewModel.chapterSummary.explorationId ) } @@ -83,10 +82,7 @@ class MarkChaptersCompletedFragmentPresenter @Inject constructor( getMarkChaptersCompletedViewModel().getItemList().forEach { viewModel -> if (viewModel is ChapterSummaryViewModel) { if (!viewModel.checkIfChapterIsCompleted()) - chapterUnselected( - viewModel.chapterIndex, - viewModel.nextStoryIndex - ) + chapterUnselected(viewModel.chapterIndex, viewModel.nextStoryIndex) } } } diff --git a/app/src/main/java/org/oppia/android/app/devoptions/marktopicscompleted/MarkTopicsCompletedFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/devoptions/marktopicscompleted/MarkTopicsCompletedFragmentPresenter.kt index 7d2ab4de700..0b62ca2caed 100644 --- a/app/src/main/java/org/oppia/android/app/devoptions/marktopicscompleted/MarkTopicsCompletedFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/devoptions/marktopicscompleted/MarkTopicsCompletedFragmentPresenter.kt @@ -64,11 +64,7 @@ class MarkTopicsCompletedFragmentPresenter @Inject constructor( } binding.markTopicsCompletedAllCheckBoxContainer.setOnClickListener { - if (binding.isAllChecked == null || binding.isAllChecked == false) { - binding.isAllChecked = true - } else if (binding.isAllChecked == true) { - binding.isAllChecked = false - } + binding.isAllChecked = !(binding.isAllChecked ?: false) } binding.markTopicsCompletedAllCheckBox.setOnCheckedChangeListener { _, isChecked -> From ca5bca5e93a96d6dee5ea7142716eedb00d6bc2d Mon Sep 17 00:00:00 2001 From: kevingitonga Date: Thu, 9 Jun 2022 10:15:54 +0300 Subject: [PATCH 03/50] Fix #4186 Undo changes on line wrap as advised by code reviewer. --- .../MarkChaptersCompletedFragmentPresenter.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt index 3e59f1d393e..bc8074d4f7d 100644 --- a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt @@ -72,7 +72,8 @@ class MarkChaptersCompletedFragmentPresenter @Inject constructor( if (viewModel is ChapterSummaryViewModel) { if (!viewModel.checkIfChapterIsCompleted()) chapterSelected( - viewModel.chapterIndex, viewModel.nextStoryIndex, + viewModel.chapterIndex, + viewModel.nextStoryIndex, viewModel.chapterSummary.explorationId ) } From 20e93e421a767cf087b63470fd7146fbe89e6330 Mon Sep 17 00:00:00 2001 From: kevingitonga Date: Fri, 10 Jun 2022 13:14:35 +0300 Subject: [PATCH 04/50] Fix #2581 Marquee restarts automatically in certain scenarios. --- .../oppia/android/app/story/StoryFragmentPresenter.kt | 11 +++++++++++ .../oppia/android/app/topic/TopicFragmentPresenter.kt | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt index baa1efc5b09..3583424fe5a 100644 --- a/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt @@ -1,6 +1,8 @@ package org.oppia.android.app.story import android.content.res.Resources +import android.os.Handler +import android.os.Looper import android.text.SpannableString import android.text.Spanned import android.text.TextPaint @@ -86,6 +88,15 @@ class StoryFragmentPresenter @Inject constructor( binding.storyToolbarTitle.isSelected = true } + Handler(Looper.getMainLooper()).postDelayed( + { + if (binding.storyToolbarTitle.isSelected) { + binding.storyToolbarTitle.isSelected = false + } + }, + 25000 + ) + linearLayoutManager = LinearLayoutManager(activity.applicationContext) linearSmoothScroller = createSmoothScroller() 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 9b32a29e1e3..8c42b6d117a 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,5 +1,7 @@ package org.oppia.android.app.topic +import android.os.Handler +import android.os.Looper import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -61,6 +63,15 @@ class TopicFragmentPresenter @Inject constructor( binding.topicToolbarTitle.isSelected = true } + Handler(Looper.getMainLooper()).postDelayed( + { + if (binding.topicToolbarTitle.isSelected) { + binding.topicToolbarTitle.isSelected = false + } + }, + 25000 + ) + val viewModel = getTopicViewModel() viewModel.setInternalProfileId(internalProfileId) viewModel.setTopicId(topicId) From 841a35e3cc33420077320d4bb7d4a1eac0b8e8f3 Mon Sep 17 00:00:00 2001 From: kevingitonga Date: Mon, 13 Jun 2022 09:38:43 +0300 Subject: [PATCH 05/50] Fix #2581 Marquee restarts automatically in certain scenarios. --- .../android/app/story/StoryFragmentPresenter.kt | 17 +++++++---------- .../android/app/topic/TopicFragmentPresenter.kt | 17 +++++++---------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt index 3583424fe5a..0f07394806b 100644 --- a/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt @@ -1,8 +1,6 @@ package org.oppia.android.app.story import android.content.res.Resources -import android.os.Handler -import android.os.Looper import android.text.SpannableString import android.text.Spanned import android.text.TextPaint @@ -30,6 +28,7 @@ import org.oppia.android.app.story.storyitemviewmodel.StoryHeaderViewModel import org.oppia.android.app.story.storyitemviewmodel.StoryItemViewModel import org.oppia.android.app.topic.RouteToResumeLessonListener import org.oppia.android.app.translation.AppLanguageResourceHandler +import org.oppia.android.app.utility.LifecycleSafeTimerFactory import org.oppia.android.databinding.StoryChapterViewBinding import org.oppia.android.databinding.StoryFragmentBinding import org.oppia.android.databinding.StoryHeaderViewBinding @@ -51,6 +50,7 @@ class StoryFragmentPresenter @Inject constructor( private val explorationDataController: ExplorationDataController, @DefaultResourceBucketName private val resourceBucketName: String, @TopicHtmlParserEntityType private val entityType: String, + private val lifecycleSafeTimerFactory: LifecycleSafeTimerFactory, private val resourceHandler: AppLanguageResourceHandler ) { private val routeToExplorationListener = activity as RouteToExplorationListener @@ -88,14 +88,11 @@ class StoryFragmentPresenter @Inject constructor( binding.storyToolbarTitle.isSelected = true } - Handler(Looper.getMainLooper()).postDelayed( - { - if (binding.storyToolbarTitle.isSelected) { - binding.storyToolbarTitle.isSelected = false - } - }, - 25000 - ) + lifecycleSafeTimerFactory.createTimer(25000).observe(fragment.viewLifecycleOwner) { + if (binding.storyToolbarTitle.isSelected) { + binding.storyToolbarTitle.isSelected = false + } + } linearLayoutManager = LinearLayoutManager(activity.applicationContext) linearSmoothScroller = createSmoothScroller() 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 8c42b6d117a..935e87b45da 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,7 +1,5 @@ package org.oppia.android.app.topic -import android.os.Handler -import android.os.Looper import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -14,6 +12,7 @@ import com.google.android.material.tabs.TabLayoutMediator import org.oppia.android.R import org.oppia.android.app.fragment.FragmentScope import org.oppia.android.app.translation.AppLanguageResourceHandler +import org.oppia.android.app.utility.LifecycleSafeTimerFactory import org.oppia.android.app.viewmodel.ViewModelProvider import org.oppia.android.databinding.TopicFragmentBinding import org.oppia.android.domain.oppialogger.OppiaLogger @@ -26,6 +25,7 @@ class TopicFragmentPresenter @Inject constructor( private val fragment: Fragment, private val viewModelProvider: ViewModelProvider, private val oppiaLogger: OppiaLogger, + private val lifecycleSafeTimerFactory: LifecycleSafeTimerFactory, @EnablePracticeTab private val enablePracticeTab: Boolean, private val resourceHandler: AppLanguageResourceHandler ) { @@ -63,14 +63,11 @@ class TopicFragmentPresenter @Inject constructor( binding.topicToolbarTitle.isSelected = true } - Handler(Looper.getMainLooper()).postDelayed( - { - if (binding.topicToolbarTitle.isSelected) { - binding.topicToolbarTitle.isSelected = false - } - }, - 25000 - ) + lifecycleSafeTimerFactory.createTimer(25000).observe(fragment.viewLifecycleOwner) { + if (binding.topicToolbarTitle.isSelected) { + binding.topicToolbarTitle.isSelected = false + } + } val viewModel = getTopicViewModel() viewModel.setInternalProfileId(internalProfileId) From f82b874f7218e4787736fef44a96b38d52505460 Mon Sep 17 00:00:00 2001 From: kevingitonga Date: Fri, 10 Jun 2022 13:14:35 +0300 Subject: [PATCH 06/50] Fix #2581 Marquee restarts automatically in certain scenarios. --- .../oppia/android/app/story/StoryFragmentPresenter.kt | 11 +++++++++++ .../oppia/android/app/topic/TopicFragmentPresenter.kt | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt index baa1efc5b09..3583424fe5a 100644 --- a/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt @@ -1,6 +1,8 @@ package org.oppia.android.app.story import android.content.res.Resources +import android.os.Handler +import android.os.Looper import android.text.SpannableString import android.text.Spanned import android.text.TextPaint @@ -86,6 +88,15 @@ class StoryFragmentPresenter @Inject constructor( binding.storyToolbarTitle.isSelected = true } + Handler(Looper.getMainLooper()).postDelayed( + { + if (binding.storyToolbarTitle.isSelected) { + binding.storyToolbarTitle.isSelected = false + } + }, + 25000 + ) + linearLayoutManager = LinearLayoutManager(activity.applicationContext) linearSmoothScroller = createSmoothScroller() 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 9b32a29e1e3..8c42b6d117a 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,5 +1,7 @@ package org.oppia.android.app.topic +import android.os.Handler +import android.os.Looper import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -61,6 +63,15 @@ class TopicFragmentPresenter @Inject constructor( binding.topicToolbarTitle.isSelected = true } + Handler(Looper.getMainLooper()).postDelayed( + { + if (binding.topicToolbarTitle.isSelected) { + binding.topicToolbarTitle.isSelected = false + } + }, + 25000 + ) + val viewModel = getTopicViewModel() viewModel.setInternalProfileId(internalProfileId) viewModel.setTopicId(topicId) From 008333c22cf00d1d0194af5b26167119c5a033cd Mon Sep 17 00:00:00 2001 From: kevingitonga Date: Mon, 13 Jun 2022 09:38:43 +0300 Subject: [PATCH 07/50] Fix #2581 Marquee restarts automatically in certain scenarios. --- .../android/app/story/StoryFragmentPresenter.kt | 17 +++++++---------- .../android/app/topic/TopicFragmentPresenter.kt | 17 +++++++---------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt index 3583424fe5a..0f07394806b 100644 --- a/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt @@ -1,8 +1,6 @@ package org.oppia.android.app.story import android.content.res.Resources -import android.os.Handler -import android.os.Looper import android.text.SpannableString import android.text.Spanned import android.text.TextPaint @@ -30,6 +28,7 @@ import org.oppia.android.app.story.storyitemviewmodel.StoryHeaderViewModel import org.oppia.android.app.story.storyitemviewmodel.StoryItemViewModel import org.oppia.android.app.topic.RouteToResumeLessonListener import org.oppia.android.app.translation.AppLanguageResourceHandler +import org.oppia.android.app.utility.LifecycleSafeTimerFactory import org.oppia.android.databinding.StoryChapterViewBinding import org.oppia.android.databinding.StoryFragmentBinding import org.oppia.android.databinding.StoryHeaderViewBinding @@ -51,6 +50,7 @@ class StoryFragmentPresenter @Inject constructor( private val explorationDataController: ExplorationDataController, @DefaultResourceBucketName private val resourceBucketName: String, @TopicHtmlParserEntityType private val entityType: String, + private val lifecycleSafeTimerFactory: LifecycleSafeTimerFactory, private val resourceHandler: AppLanguageResourceHandler ) { private val routeToExplorationListener = activity as RouteToExplorationListener @@ -88,14 +88,11 @@ class StoryFragmentPresenter @Inject constructor( binding.storyToolbarTitle.isSelected = true } - Handler(Looper.getMainLooper()).postDelayed( - { - if (binding.storyToolbarTitle.isSelected) { - binding.storyToolbarTitle.isSelected = false - } - }, - 25000 - ) + lifecycleSafeTimerFactory.createTimer(25000).observe(fragment.viewLifecycleOwner) { + if (binding.storyToolbarTitle.isSelected) { + binding.storyToolbarTitle.isSelected = false + } + } linearLayoutManager = LinearLayoutManager(activity.applicationContext) linearSmoothScroller = createSmoothScroller() 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 8c42b6d117a..935e87b45da 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,7 +1,5 @@ package org.oppia.android.app.topic -import android.os.Handler -import android.os.Looper import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -14,6 +12,7 @@ import com.google.android.material.tabs.TabLayoutMediator import org.oppia.android.R import org.oppia.android.app.fragment.FragmentScope import org.oppia.android.app.translation.AppLanguageResourceHandler +import org.oppia.android.app.utility.LifecycleSafeTimerFactory import org.oppia.android.app.viewmodel.ViewModelProvider import org.oppia.android.databinding.TopicFragmentBinding import org.oppia.android.domain.oppialogger.OppiaLogger @@ -26,6 +25,7 @@ class TopicFragmentPresenter @Inject constructor( private val fragment: Fragment, private val viewModelProvider: ViewModelProvider, private val oppiaLogger: OppiaLogger, + private val lifecycleSafeTimerFactory: LifecycleSafeTimerFactory, @EnablePracticeTab private val enablePracticeTab: Boolean, private val resourceHandler: AppLanguageResourceHandler ) { @@ -63,14 +63,11 @@ class TopicFragmentPresenter @Inject constructor( binding.topicToolbarTitle.isSelected = true } - Handler(Looper.getMainLooper()).postDelayed( - { - if (binding.topicToolbarTitle.isSelected) { - binding.topicToolbarTitle.isSelected = false - } - }, - 25000 - ) + lifecycleSafeTimerFactory.createTimer(25000).observe(fragment.viewLifecycleOwner) { + if (binding.topicToolbarTitle.isSelected) { + binding.topicToolbarTitle.isSelected = false + } + } val viewModel = getTopicViewModel() viewModel.setInternalProfileId(internalProfileId) From 3e9986397a2afcef84fe8482a91aa8023c895381 Mon Sep 17 00:00:00 2001 From: kevingitonga Date: Tue, 14 Jun 2022 09:49:11 +0300 Subject: [PATCH 08/50] Revert "Fix #4186 Undo changes on line wrap as advised by code reviewer." This reverts commit ca5bca5e93a96d6dee5ea7142716eedb00d6bc2d. --- .../MarkChaptersCompletedFragmentPresenter.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt index bc8074d4f7d..3e59f1d393e 100644 --- a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt @@ -72,8 +72,7 @@ class MarkChaptersCompletedFragmentPresenter @Inject constructor( if (viewModel is ChapterSummaryViewModel) { if (!viewModel.checkIfChapterIsCompleted()) chapterSelected( - viewModel.chapterIndex, - viewModel.nextStoryIndex, + viewModel.chapterIndex, viewModel.nextStoryIndex, viewModel.chapterSummary.explorationId ) } From 4a60eac16af11664325dafb9800bf6a95954d751 Mon Sep 17 00:00:00 2001 From: kevingitonga Date: Tue, 14 Jun 2022 09:49:22 +0300 Subject: [PATCH 09/50] Revert "Fix #4186 Add changes to code as suggested on code review." This reverts commit 52953644cf88d75a5a0637b7b128e96bdbb1de42. --- .../MarkChaptersCompletedFragmentPresenter.kt | 8 ++++++-- .../MarkTopicsCompletedFragmentPresenter.kt | 6 +++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt index 3e59f1d393e..4ffdafd0040 100644 --- a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt @@ -72,7 +72,8 @@ class MarkChaptersCompletedFragmentPresenter @Inject constructor( if (viewModel is ChapterSummaryViewModel) { if (!viewModel.checkIfChapterIsCompleted()) chapterSelected( - viewModel.chapterIndex, viewModel.nextStoryIndex, + viewModel.chapterIndex, + viewModel.nextStoryIndex, viewModel.chapterSummary.explorationId ) } @@ -82,7 +83,10 @@ class MarkChaptersCompletedFragmentPresenter @Inject constructor( getMarkChaptersCompletedViewModel().getItemList().forEach { viewModel -> if (viewModel is ChapterSummaryViewModel) { if (!viewModel.checkIfChapterIsCompleted()) - chapterUnselected(viewModel.chapterIndex, viewModel.nextStoryIndex) + chapterUnselected( + viewModel.chapterIndex, + viewModel.nextStoryIndex + ) } } } diff --git a/app/src/main/java/org/oppia/android/app/devoptions/marktopicscompleted/MarkTopicsCompletedFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/devoptions/marktopicscompleted/MarkTopicsCompletedFragmentPresenter.kt index 0b62ca2caed..7d2ab4de700 100644 --- a/app/src/main/java/org/oppia/android/app/devoptions/marktopicscompleted/MarkTopicsCompletedFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/devoptions/marktopicscompleted/MarkTopicsCompletedFragmentPresenter.kt @@ -64,7 +64,11 @@ class MarkTopicsCompletedFragmentPresenter @Inject constructor( } binding.markTopicsCompletedAllCheckBoxContainer.setOnClickListener { - binding.isAllChecked = !(binding.isAllChecked ?: false) + if (binding.isAllChecked == null || binding.isAllChecked == false) { + binding.isAllChecked = true + } else if (binding.isAllChecked == true) { + binding.isAllChecked = false + } } binding.markTopicsCompletedAllCheckBox.setOnCheckedChangeListener { _, isChecked -> From 94222cf1623bb505f5eda761c9f5e992184ea434 Mon Sep 17 00:00:00 2001 From: kevingitonga Date: Tue, 14 Jun 2022 09:49:30 +0300 Subject: [PATCH 10/50] Revert "Fix #4186 Uncheck all selection on developer options not working" This reverts commit 0cff83acdf5c6201909461e9194d4f64767a2058. --- .../MarkChaptersCompletedFragmentPresenter.kt | 11 ----------- .../MarkStoriesCompletedFragmentPresenter.kt | 9 +-------- .../MarkTopicsCompletedFragmentPresenter.kt | 9 +-------- 3 files changed, 2 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt index 4ffdafd0040..69bfbe61824 100644 --- a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt @@ -78,17 +78,6 @@ class MarkChaptersCompletedFragmentPresenter @Inject constructor( ) } } - } else if (binding.isAllChecked == true) { - binding.isAllChecked = false - getMarkChaptersCompletedViewModel().getItemList().forEach { viewModel -> - if (viewModel is ChapterSummaryViewModel) { - if (!viewModel.checkIfChapterIsCompleted()) - chapterUnselected( - viewModel.chapterIndex, - viewModel.nextStoryIndex - ) - } - } } } diff --git a/app/src/main/java/org/oppia/android/app/devoptions/markstoriescompleted/MarkStoriesCompletedFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/devoptions/markstoriescompleted/MarkStoriesCompletedFragmentPresenter.kt index b58b07faaa6..ccd9671bbd6 100644 --- a/app/src/main/java/org/oppia/android/app/devoptions/markstoriescompleted/MarkStoriesCompletedFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/devoptions/markstoriescompleted/MarkStoriesCompletedFragmentPresenter.kt @@ -64,11 +64,8 @@ class MarkStoriesCompletedFragmentPresenter @Inject constructor( } binding.markStoriesCompletedAllCheckBoxContainer.setOnClickListener { - if (binding.isAllChecked == null || binding.isAllChecked == false) { + if (binding.isAllChecked == null || binding.isAllChecked == false) binding.isAllChecked = true - } else if (binding.isAllChecked == true) { - binding.isAllChecked = false - } } binding.markStoriesCompletedAllCheckBox.setOnCheckedChangeListener { _, isChecked -> @@ -77,10 +74,6 @@ class MarkStoriesCompletedFragmentPresenter @Inject constructor( if (!viewModel.isCompleted) storySelected(viewModel.storySummary.storyId) } - } else { - getMarkStoriesCompletedViewModel().getStorySummaryMap().values.forEach { viewModel -> - if (!viewModel.isCompleted) storyUnselected(viewModel.storySummary.storyId) - } } bindingAdapter.notifyDataSetChanged() } diff --git a/app/src/main/java/org/oppia/android/app/devoptions/marktopicscompleted/MarkTopicsCompletedFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/devoptions/marktopicscompleted/MarkTopicsCompletedFragmentPresenter.kt index 7d2ab4de700..3d78e8bba4d 100644 --- a/app/src/main/java/org/oppia/android/app/devoptions/marktopicscompleted/MarkTopicsCompletedFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/devoptions/marktopicscompleted/MarkTopicsCompletedFragmentPresenter.kt @@ -64,11 +64,8 @@ class MarkTopicsCompletedFragmentPresenter @Inject constructor( } binding.markTopicsCompletedAllCheckBoxContainer.setOnClickListener { - if (binding.isAllChecked == null || binding.isAllChecked == false) { + if (binding.isAllChecked == null || binding.isAllChecked == false) binding.isAllChecked = true - } else if (binding.isAllChecked == true) { - binding.isAllChecked = false - } } binding.markTopicsCompletedAllCheckBox.setOnCheckedChangeListener { _, isChecked -> @@ -76,10 +73,6 @@ class MarkTopicsCompletedFragmentPresenter @Inject constructor( getMarkTopicsCompletedViewModel().getTopicList().forEach { viewModel -> if (!viewModel.isCompleted) topicSelected(viewModel.topic.topicId) } - } else { - getMarkTopicsCompletedViewModel().getTopicList().forEach { viewModel -> - if (!viewModel.isCompleted) topicUnselected(viewModel.topic.topicId) - } } bindingAdapter.notifyDataSetChanged() } From c8b74e868dd9be3cc19af1db13428442f368cda1 Mon Sep 17 00:00:00 2001 From: kevingitonga Date: Wed, 15 Jun 2022 16:36:49 +0300 Subject: [PATCH 11/50] Insert timer in OnClick listener to enable unselect during subsequent clicks. --- .../org/oppia/android/app/story/StoryFragmentPresenter.kt | 6 ++---- .../org/oppia/android/app/topic/TopicFragmentPresenter.kt | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt index 0f07394806b..2f2cfa09240 100644 --- a/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt @@ -86,11 +86,9 @@ class StoryFragmentPresenter @Inject constructor( binding.storyToolbarTitle.setOnClickListener { binding.storyToolbarTitle.isSelected = true - } - lifecycleSafeTimerFactory.createTimer(25000).observe(fragment.viewLifecycleOwner) { - if (binding.storyToolbarTitle.isSelected) { - binding.storyToolbarTitle.isSelected = false + lifecycleSafeTimerFactory.createTimer(25000).observe(fragment.viewLifecycleOwner) { + binding.storyToolbarTitle.isSelected = false } } 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 935e87b45da..04416966ed9 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 @@ -61,11 +61,9 @@ class TopicFragmentPresenter @Inject constructor( binding.topicToolbar.setOnClickListener { binding.topicToolbarTitle.isSelected = true - } - lifecycleSafeTimerFactory.createTimer(25000).observe(fragment.viewLifecycleOwner) { - if (binding.topicToolbarTitle.isSelected) { - binding.topicToolbarTitle.isSelected = false + lifecycleSafeTimerFactory.createTimer(25000).observe(fragment.viewLifecycleOwner) { + binding.topicToolbarTitle.isSelected = false } } From ab46619d7a59497b4cc16b0c79cb25f419c5c789 Mon Sep 17 00:00:00 2001 From: kevingitonga Date: Thu, 18 Aug 2022 18:52:16 +0300 Subject: [PATCH 12/50] Introduce custom translation animation logic to fix issue with the core marquee api. --- .../android/app/customview/MarqueeView.kt | 232 ++++++++++++++++++ .../LicenseTextViewerActivityPresenter.kt | 2 +- .../ExplorationActivityPresenter.kt | 2 +- .../app/story/StoryFragmentPresenter.kt | 6 +- .../app/topic/TopicFragmentPresenter.kt | 10 +- .../RevisionCardActivityPresenter.kt | 2 +- .../res/layout-sw600dp/story_fragment.xml | 5 + .../main/res/layout/exploration_activity.xml | 5 + .../layout/license_text_viewer_activity.xml | 5 + .../res/layout/revision_card_activity.xml | 5 + app/src/main/res/layout/story_fragment.xml | 7 +- app/src/main/res/layout/topic_fragment.xml | 9 +- app/src/main/res/values/styles.xml | 6 - 13 files changed, 271 insertions(+), 25 deletions(-) create mode 100644 app/src/main/java/org/oppia/android/app/customview/MarqueeView.kt diff --git a/app/src/main/java/org/oppia/android/app/customview/MarqueeView.kt b/app/src/main/java/org/oppia/android/app/customview/MarqueeView.kt new file mode 100644 index 00000000000..ec8a89218bf --- /dev/null +++ b/app/src/main/java/org/oppia/android/app/customview/MarqueeView.kt @@ -0,0 +1,232 @@ +package org.oppia.android.app.customview + +import android.annotation.TargetApi +import android.content.Context +import android.graphics.Paint +import android.os.Build +import android.text.Editable +import android.text.TextWatcher +import android.util.AttributeSet +import android.view.Gravity +import android.view.animation.Animation +import android.view.animation.Interpolator +import android.view.animation.LinearInterpolator +import android.view.animation.TranslateAnimation +import android.widget.FrameLayout +import android.widget.LinearLayout +import android.widget.ScrollView +import android.widget.TextView +import java.lang.RuntimeException +import kotlin.math.abs + +/** + * Provides a simple marquee effect for a single [android.widget.TextView]. + * Reference: https://github.com/ened/Android-MarqueeView/blob/master/library/src/main/java/asia/ivity/android/marqueeview/MarqueeView.java + */ +class MarqueeView : LinearLayout { + private lateinit var mTextField: TextView + private lateinit var mScrollView: ScrollView + private lateinit var mMoveTextOut: Animation + private lateinit var mMoveTextIn: Animation + private lateinit var mPaint: Paint + private var mMarqueeNeeded = false + private var mTextDifference = 0f + private var mAutoStart = false + private var mInterpolator: Interpolator = LinearInterpolator() + private var mCancelled = false + private lateinit var mAnimationStartRunnable: Runnable + private var mStarted = false + + private val textviewVirtualWidth = 2000 + private val tag = MarqueeView::class.java.simpleName + + /**Control the speed. The lower this value, the faster it will scroll.*/ + private var mSpeed = 15 + + /**Control the pause between the animations.*/ + private var mAnimationPause = 2000 + + constructor(context: Context?) : super(context) { + init() + } + + constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) { + init() + } + + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super( + context, + attrs, + defStyle + ) { + init() + } + + private fun init() { + // init helper + mPaint = Paint() + mPaint.isAntiAlias = true + mPaint.strokeWidth = 1f + mPaint.strokeCap = Paint.Cap.ROUND + mInterpolator = LinearInterpolator() + } + + override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) { + super.onLayout(changed, l, t, r, b) + if (childCount != 1) { + throw RuntimeException("MarqueeView must have exactly one child element.") + } + if (changed && ::mScrollView.isInitialized.not()) { + if (getChildAt(0) !is TextView) { + throw RuntimeException("The child view of this MarqueeView must be a TextView instance.") + } + initView(context) + prepareAnimation() + if (mAutoStart) { + startMarquee() + } + } + } + + /** + * Starts the configured marquee effect. + */ + fun startMarquee() { + if (mMarqueeNeeded) { + startTextFieldAnimation() + } + mCancelled = false + mStarted = true + } + + /** + * Animates the child Textfield with the provided animation params. + */ + private fun startTextFieldAnimation() { + mAnimationStartRunnable = Runnable { mTextField.startAnimation(mMoveTextOut) } + postDelayed(mAnimationStartRunnable, mAnimationPause.toLong()) + } + + /** + * Disables the animations. + */ + private fun reset() { + mCancelled = true + if (::mAnimationStartRunnable.isInitialized) { + removeCallbacks(mAnimationStartRunnable) + } + mTextField.clearAnimation() + mStarted = false + mMoveTextOut.reset() + mMoveTextIn.reset() + cutTextView() + invalidate() + } + + /** + * Prepare the animation to render the marquee effect. + */ + private fun prepareAnimation() { + // Measure + mPaint.textSize = mTextField.textSize + mPaint.typeface = mTextField.typeface + val mTextWidth = mPaint.measureText(mTextField.text.toString()) + + // See how much functions are needed at all + mMarqueeNeeded = mTextWidth > measuredWidth + mTextDifference = abs(mTextWidth - measuredWidth) + + val duration = (mTextDifference * mSpeed).toInt() + mMoveTextOut = TranslateAnimation(0f, -mTextDifference, 0f, 0f) + mMoveTextOut.duration = duration.toLong() + mMoveTextOut.interpolator = mInterpolator + mMoveTextOut.fillAfter = true + mMoveTextIn = TranslateAnimation(-mTextDifference, 0f, 0f, 0f) + mMoveTextIn.duration = duration.toLong() + mMoveTextIn.startOffset = mAnimationPause.toLong() + mMoveTextIn.interpolator = mInterpolator + mMoveTextIn.fillAfter = true + mMoveTextOut.setAnimationListener(object : Animation.AnimationListener { + override fun onAnimationStart(animation: Animation) { + expandTextView() + } + + override fun onAnimationEnd(animation: Animation) { + if (mCancelled) { + reset() + return + } + mTextField.startAnimation(mMoveTextIn) + } + + override fun onAnimationRepeat(animation: Animation) {} + }) + mMoveTextIn.setAnimationListener(object : Animation.AnimationListener { + override fun onAnimationStart(animation: Animation) {} + override fun onAnimationEnd(animation: Animation) { + cutTextView() + if (mCancelled) { + reset() + return + } + } + + override fun onAnimationRepeat(animation: Animation) {} + }) + } + + /** + * Initiate the view by adding scrollview and adding view items. + */ + private fun initView(context: Context) { + // Scroll View + val svLayoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT) + svLayoutParams.gravity = Gravity.CENTER + mScrollView = ScrollView(context) + + // Scroll View - Text Field + mTextField = getChildAt(0) as TextView + removeView(mTextField) + mScrollView.addView( + mTextField, + FrameLayout.LayoutParams(mTextField.measuredWidth, LayoutParams.WRAP_CONTENT) + ) + mTextField.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(charSequence: CharSequence, i: Int, i2: Int, i3: Int) {} + override fun onTextChanged(charSequence: CharSequence, i: Int, i2: Int, i3: Int) {} + override fun afterTextChanged(editable: Editable) { + val continueAnimation = mStarted + reset() + prepareAnimation() + cutTextView() + post { + if (continueAnimation) { + startMarquee() + } + } + } + }) + addView(mScrollView, svLayoutParams) + } + + /** + * Expand textview to show the rest of hidden text. + */ + private fun expandTextView() { + val lp = mTextField.layoutParams + lp.width = textviewVirtualWidth + mTextField.layoutParams = lp + } + + /** + * Revert back text to initial cut state after animation finishes. + */ + private fun cutTextView() { + if (mTextField.width != measuredWidth) { + val lp = mTextField.layoutParams + lp.width = measuredWidth + mTextField.layoutParams = lp + } + } +} diff --git a/app/src/main/java/org/oppia/android/app/help/thirdparty/LicenseTextViewerActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/help/thirdparty/LicenseTextViewerActivityPresenter.kt index d4c5c34b262..069a100a122 100644 --- a/app/src/main/java/org/oppia/android/app/help/thirdparty/LicenseTextViewerActivityPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/help/thirdparty/LicenseTextViewerActivityPresenter.kt @@ -45,7 +45,7 @@ class LicenseTextViewerActivityPresenter @Inject constructor( } binding.licenseTextViewerActivityToolbarTitle.setOnClickListener { - binding.licenseTextViewerActivityToolbarTitle.isSelected = true + binding.marqueeView.startMarquee() } if (getLicenseTextViewerFragment() == null) { 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 23f64e84d87..cbb97e18f1d 100755 --- 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 @@ -93,7 +93,7 @@ class ExplorationActivityPresenter @Inject constructor( activity.setSupportActionBar(explorationToolbar) binding.explorationToolbarTitle.setOnClickListener { - binding.explorationToolbarTitle.isSelected = true + binding.marqueeView.startMarquee() } binding.explorationToolbar.setNavigationOnClickListener { diff --git a/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt index 2f2cfa09240..2ff2295d1aa 100644 --- a/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt @@ -85,11 +85,7 @@ class StoryFragmentPresenter @Inject constructor( } binding.storyToolbarTitle.setOnClickListener { - binding.storyToolbarTitle.isSelected = true - - lifecycleSafeTimerFactory.createTimer(25000).observe(fragment.viewLifecycleOwner) { - binding.storyToolbarTitle.isSelected = false - } + binding.marqueeView?.startMarquee() } linearLayoutManager = LinearLayoutManager(activity.applicationContext) 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 04416966ed9..2f7f1ba95aa 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.translation.AppLanguageResourceHandler -import org.oppia.android.app.utility.LifecycleSafeTimerFactory import org.oppia.android.app.viewmodel.ViewModelProvider import org.oppia.android.databinding.TopicFragmentBinding import org.oppia.android.domain.oppialogger.OppiaLogger @@ -25,7 +24,6 @@ class TopicFragmentPresenter @Inject constructor( private val fragment: Fragment, private val viewModelProvider: ViewModelProvider, private val oppiaLogger: OppiaLogger, - private val lifecycleSafeTimerFactory: LifecycleSafeTimerFactory, @EnablePracticeTab private val enablePracticeTab: Boolean, private val resourceHandler: AppLanguageResourceHandler ) { @@ -59,12 +57,8 @@ class TopicFragmentPresenter @Inject constructor( (activity as TopicActivity).finish() } - binding.topicToolbar.setOnClickListener { - binding.topicToolbarTitle.isSelected = true - - lifecycleSafeTimerFactory.createTimer(25000).observe(fragment.viewLifecycleOwner) { - binding.topicToolbarTitle.isSelected = false - } + binding.topicToolbarTitle.setOnClickListener { + binding.marqueeView.startMarquee() } val viewModel = getTopicViewModel() diff --git a/app/src/main/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityPresenter.kt index 78ce25bfb86..3e252d0502d 100644 --- a/app/src/main/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityPresenter.kt @@ -58,7 +58,7 @@ class RevisionCardActivityPresenter @Inject constructor( (activity as RevisionCardActivity).finish() } binding.revisionCardToolbarTitle.setOnClickListener { - binding.revisionCardToolbarTitle.isSelected = true + binding.marqueeView.startMarquee() } subscribeToSubtopicTitle() diff --git a/app/src/main/res/layout-sw600dp/story_fragment.xml b/app/src/main/res/layout-sw600dp/story_fragment.xml index 7034d446655..08b8508d9e3 100644 --- a/app/src/main/res/layout-sw600dp/story_fragment.xml +++ b/app/src/main/res/layout-sw600dp/story_fragment.xml @@ -36,6 +36,10 @@ app:navigationContentDescription="@string/navigate_up" app:navigationIcon="?attr/homeAsUpIndicator"> + + diff --git a/app/src/main/res/layout/exploration_activity.xml b/app/src/main/res/layout/exploration_activity.xml index d17a705b995..36dccbe581d 100755 --- a/app/src/main/res/layout/exploration_activity.xml +++ b/app/src/main/res/layout/exploration_activity.xml @@ -38,6 +38,10 @@ android:layout_height="wrap_content" android:orientation="horizontal"> + + + + diff --git a/app/src/main/res/layout/revision_card_activity.xml b/app/src/main/res/layout/revision_card_activity.xml index 2ae1f72b4c4..71633d59904 100644 --- a/app/src/main/res/layout/revision_card_activity.xml +++ b/app/src/main/res/layout/revision_card_activity.xml @@ -29,12 +29,17 @@ app:navigationContentDescription="@string/navigate_up" app:navigationIcon="?attr/homeAsUpIndicator"> + + diff --git a/app/src/main/res/layout/story_fragment.xml b/app/src/main/res/layout/story_fragment.xml index 4b01a0bedf9..407da1b1f6f 100644 --- a/app/src/main/res/layout/story_fragment.xml +++ b/app/src/main/res/layout/story_fragment.xml @@ -36,13 +36,18 @@ app:navigationContentDescription="@string/navigate_up" app:navigationIcon="?attr/homeAsUpIndicator"> + + diff --git a/app/src/main/res/layout/topic_fragment.xml b/app/src/main/res/layout/topic_fragment.xml index 76cf7c1940b..b38f2585c0f 100644 --- a/app/src/main/res/layout/topic_fragment.xml +++ b/app/src/main/res/layout/topic_fragment.xml @@ -34,13 +34,18 @@ app:navigationContentDescription="@string/navigate_up" app:navigationIcon="?attr/homeAsUpIndicator"> + +