diff --git a/app/src/main/java/org/oppia/app/story/StoryFragmentPresenter.kt b/app/src/main/java/org/oppia/app/story/StoryFragmentPresenter.kt index cee4a659568..b5e07e445be 100644 --- a/app/src/main/java/org/oppia/app/story/StoryFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/app/story/StoryFragmentPresenter.kt @@ -7,6 +7,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity +import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearSmoothScroller @@ -22,6 +23,9 @@ import org.oppia.app.story.storyitemviewmodel.StoryHeaderViewModel import org.oppia.app.story.storyitemviewmodel.StoryItemViewModel import org.oppia.app.viewmodel.ViewModelProvider import org.oppia.domain.oppialogger.OppiaLogger +import org.oppia.util.gcsresource.DefaultResourceBucketName +import org.oppia.util.parser.HtmlParser +import org.oppia.util.parser.TopicHtmlParserEntityType import org.oppia.util.system.OppiaClock import javax.inject.Inject @@ -31,7 +35,10 @@ class StoryFragmentPresenter @Inject constructor( private val fragment: Fragment, private val oppiaLogger: OppiaLogger, private val oppiaClock: OppiaClock, - private val viewModelProvider: ViewModelProvider + private val viewModelProvider: ViewModelProvider, + private val htmlParserFactory: HtmlParser.Factory, + @DefaultResourceBucketName private val resourceBucketName: String, + @TopicHtmlParserEntityType private val entityType: String ) { private val routeToExplorationListener = activity as RouteToExplorationListener @@ -109,11 +116,29 @@ class StoryFragmentPresenter @Inject constructor( setViewModel = StoryHeaderViewBinding::setViewModel, transformViewModel = { it as StoryHeaderViewModel } ) - .registerViewDataBinder( + .registerViewBinder( viewType = ViewType.VIEW_TYPE_CHAPTER, - inflateDataBinding = StoryChapterViewBinding::inflate, - setViewModel = StoryChapterViewBinding::setViewModel, - transformViewModel = { it as StoryChapterSummaryViewModel } + inflateView = { parent -> + StoryChapterViewBinding.inflate( + LayoutInflater.from(parent.context), + parent, + /* attachToParent= */ false + ).root + }, + bindView = { view, viewModel -> + val binding = DataBindingUtil.findBinding(view)!! + val storyItemViewModel = viewModel as StoryChapterSummaryViewModel + binding.viewModel = storyItemViewModel + binding.htmlContent = + htmlParserFactory.create( + resourceBucketName, + entityType, + storyItemViewModel.storyId, + imageCenterAlign = true + ).parseOppiaHtml( + storyItemViewModel.summary, binding.chapterSummary + ) + } ) .build() } diff --git a/app/src/main/res/layout-land/story_chapter_view.xml b/app/src/main/res/layout-land/story_chapter_view.xml index b2eaed2fab3..ba14b4d2984 100644 --- a/app/src/main/res/layout-land/story_chapter_view.xml +++ b/app/src/main/res/layout-land/story_chapter_view.xml @@ -8,6 +8,10 @@ + + @@ -74,7 +78,7 @@ android:ellipsize="end" android:fontFamily="sans-serif" android:maxLines="3" - android:text="@{viewModel.summary}" + android:text="@{htmlContent}" android:textColor="@color/oppiaPrimaryText" android:textSize="16sp" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/main/res/layout/story_chapter_view.xml b/app/src/main/res/layout/story_chapter_view.xml index fe0babbcf5d..73ca723f600 100644 --- a/app/src/main/res/layout/story_chapter_view.xml +++ b/app/src/main/res/layout/story_chapter_view.xml @@ -8,6 +8,10 @@ + + @@ -87,7 +91,7 @@ android:ellipsize="end" android:fontFamily="sans-serif" android:maxLines="4" - android:text="@{viewModel.summary}" + android:text="@{htmlContent}" android:textColor="@color/oppiaPrimaryText" android:textSize="16sp" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/sharedTest/java/org/oppia/app/story/StoryFragmentTest.kt b/app/src/sharedTest/java/org/oppia/app/story/StoryFragmentTest.kt index 54c0868ebe9..c055f069600 100644 --- a/app/src/sharedTest/java/org/oppia/app/story/StoryFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/app/story/StoryFragmentTest.kt @@ -195,6 +195,41 @@ class StoryFragmentTest { } } + @Test + fun testStoryFragment_chapterSummaryIsShownCorrectly() { + launch(createStoryActivityIntent()).use { + waitForTheView(withText("Chapter 1: What is a Fraction?")) + onView(allOf(withId(R.id.story_chapter_list))).perform( + scrollToPosition( + 1 + ) + ) + onView(atPositionOnView(R.id.story_chapter_list, 1, R.id.chapter_summary)).check( + matches( + withText("This is outline/summary for What is a Fraction?") + ) + ) + } + } + + @Test + fun testStoryFragment_changeConfiguration_chapterSummaryIsShownCorrectly() { + launch(createStoryActivityIntent()).use { + onView(isRoot()).perform(orientationLandscape()) + waitForTheView(withText("Chapter 1: What is a Fraction?")) + onView(allOf(withId(R.id.story_chapter_list))).perform( + scrollToPosition( + 1 + ) + ) + onView(atPositionOnView(R.id.story_chapter_list, 1, R.id.chapter_summary)).check( + matches( + withText("This is outline/summary for What is a Fraction?") + ) + ) + } + } + @Test fun testStoryFragment_changeConfiguration_correctStoryCountInHeader() { launch(createStoryActivityIntent()).use { diff --git a/domain/src/main/assets/wANbh4oOClga.json b/domain/src/main/assets/wANbh4oOClga.json index caab70740b0..ff6f1fa1ca9 100644 --- a/domain/src/main/assets/wANbh4oOClga.json +++ b/domain/src/main/assets/wANbh4oOClga.json @@ -19,7 +19,7 @@ "objective": "Learn about fractions in detail.", "id": "umPkwp0L1M0-" }, - "outline": "", + "outline": "This is outline/summary for What is a Fraction?", "title": "What is a Fraction?", "acquired_skill_ids": [] }, @@ -40,7 +40,7 @@ "objective": "Learn about fractions and equal parts.", "id": "MjZzEVOG47_1" }, - "outline": "", + "outline": "This is outline/summary for The Meaning of Equal Parts", "title": "The Meaning of Equal Parts", "acquired_skill_ids": [] } diff --git a/domain/src/main/java/org/oppia/domain/topic/TopicController.kt b/domain/src/main/java/org/oppia/domain/topic/TopicController.kt index 2c128c4103d..c0fccd4a095 100755 --- a/domain/src/main/java/org/oppia/domain/topic/TopicController.kt +++ b/domain/src/main/java/org/oppia/domain/topic/TopicController.kt @@ -585,6 +585,7 @@ class TopicController @Inject constructor( ChapterSummary.newBuilder() .setExplorationId(explorationId) .setName(chapter.getString("title")) + .setSummary(chapter.getString("outline")) .setChapterPlayState(ChapterPlayState.COMPLETION_STATUS_UNSPECIFIED) .setChapterThumbnail(createChapterThumbnail(chapter)) .build() diff --git a/domain/src/test/java/org/oppia/domain/topic/TopicControllerTest.kt b/domain/src/test/java/org/oppia/domain/topic/TopicControllerTest.kt index 7a65b25a290..cb53bf937d5 100755 --- a/domain/src/test/java/org/oppia/domain/topic/TopicControllerTest.kt +++ b/domain/src/test/java/org/oppia/domain/topic/TopicControllerTest.kt @@ -401,6 +401,20 @@ class TopicControllerTest { assertThat(story.getChapter(0).name).isEqualTo("Fifth Exploration") } + @Test + @ExperimentalCoroutinesApi + fun testRetrieveStory_validStory_returnsStoryWithChapterSummary() = + runBlockingTest(coroutineContext) { + topicController.getStory(profileId1, FRACTIONS_TOPIC_ID, FRACTIONS_STORY_ID_0) + .observeForever(mockStorySummaryObserver) + advanceUntilIdle() + + verifyGetStorySucceeded() + val story = storySummaryResultCaptor.value!!.getOrThrow() + assertThat(story.getChapter(0).summary) + .isEqualTo("This is outline/summary for What is a Fraction?") + } + @Test @ExperimentalCoroutinesApi fun testRetrieveStory_validStory_returnsStoryWithChapterThumbnail() =