From 87c6fb2812caca3bb1fe54e2e35ee8434aadf23c Mon Sep 17 00:00:00 2001
From: "Mr. 17" <saptakmanna100@gmail.com>
Date: Tue, 14 Nov 2023 22:43:45 +0530
Subject: [PATCH] Fix #3596: Adds Audio Loading UI (#5179)

<!-- READ ME FIRST: Please fill in the explanation section below and
check off every point from the Essential Checklist! -->
## Explanation
<!--
- Explain what your PR does. If this PR fixes an existing bug, please
include
- "Fixes #bugnum:" in the explanation so that GitHub can auto-close the
issue
  - when this PR is merged.
  -->

Fixes #3596

This PR adds an indeterminate progress bar when the audio is loading,
before it starts playing.

## Essential Checklist
<!-- Please tick the relevant boxes by putting an "x" in them. -->
- [x] The PR title and explanation each start with "Fix #bugnum: " (If
this PR fixes part of an issue, prefix the title with "Fix part of
#bugnum: ...".)
- [x] Any changes to
[scripts/assets](https://github.com/oppia/oppia-android/tree/develop/scripts/assets)
files have their rationale included in the PR explanation.
- [x] The PR follows the [style
guide](https://github.com/oppia/oppia-android/wiki/Coding-style-guide).
- [x] The PR does not contain any unnecessary code changes from Android
Studio
([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#undo-unnecessary-changes)).
- [x] The PR is made from a branch that's **not** called "develop" and
is up-to-date with "develop".
- [x] The PR is **assigned** to the appropriate reviewers
([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#clarification-regarding-assignees-and-reviewers-section)).

## For UI-specific PRs only
<!-- Delete these section if this PR does not include UI-related
changes. -->
If your PR includes UI-related changes, then:
- Add screenshots for portrait/landscape for both a tablet & phone of
the before & after UI changes
- For the screenshots above, include both English and pseudo-localized
(RTL) screenshots (see [RTL
guide](https://github.com/oppia/oppia-android/wiki/RTL-Guidelines))
- Add a video showing the full UX flow with a screen reader enabled (see
[accessibility
guide](https://github.com/oppia/oppia-android/wiki/Accessibility-A11y-Guide))
- Add a screenshot demonstrating that you ran affected Espresso tests
locally & that they're passing


https://github.com/oppia/oppia-android/assets/84731134/5c6fe393-5d89-4bda-a144-57bdc42a9c57

---------

Co-authored-by: Adhiambo Peres <59600948+adhiamboperes@users.noreply.github.com>
---
 app/src/main/res/layout/audio_fragment.xml    | 15 +++++++
 app/src/main/res/values/component_colors.xml  |  1 +
 app/src/main/res/values/dimens.xml            |  8 +++-
 .../exploration/ExplorationActivityTest.kt    | 39 ++++++++++++++++++-
 4 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/app/src/main/res/layout/audio_fragment.xml b/app/src/main/res/layout/audio_fragment.xml
index d849e51c03c..20ca0081c0e 100755
--- a/app/src/main/res/layout/audio_fragment.xml
+++ b/app/src/main/res/layout/audio_fragment.xml
@@ -36,6 +36,20 @@
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent">
 
+      <com.google.android.material.progressindicator.CircularProgressIndicator
+        android:id="@+id/audio_fragment_voiceover_progressbar"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:indeterminate="true"
+        android:visibility="@{viewModel.playStatusLiveData == UiAudioPlayStatus.LOADING ? View.VISIBLE : View.GONE}"
+        app:indicatorColor="@color/component_color_audio_fragment_voiceover_progressbar_color"
+        app:indicatorSize="@dimen/audio_fragment_progress_indicator_size"
+        app:trackThickness="@dimen/audio_fragment_progress_indicator_track_thickness"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="@+id/play_pause_audio_icon"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
       <ImageView
         android:id="@+id/play_pause_audio_icon"
         android:layout_width="52dp"
@@ -44,6 +58,7 @@
         android:clickable="@{viewModel.playStatusLiveData != UiAudioPlayStatus.LOADING}"
         android:contentDescription="@{viewModel.playStatusLiveData == UiAudioPlayStatus.PLAYING ? @string/audio_pause_description : @string/audio_play_description}"
         android:onClick="@{(v) -> viewModel.togglePlayPause(viewModel.playStatusLiveData)}"
+        android:visibility="@{viewModel.playStatusLiveData != UiAudioPlayStatus.LOADING ? View.VISIBLE : View.INVISIBLE}"
         android:padding="12dp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintStart_toStartOf="parent"
diff --git a/app/src/main/res/values/component_colors.xml b/app/src/main/res/values/component_colors.xml
index 9c312ee2ed0..35df91176ed 100644
--- a/app/src/main/res/values/component_colors.xml
+++ b/app/src/main/res/values/component_colors.xml
@@ -245,6 +245,7 @@
   <color name="component_color_concept_card_fragment_toolbar_color">@color/color_palette_concept_card_toolbar_color</color>
   <!-- Audio Fragment -->
   <color name="component_color_audio_fragment_background_color">@color/color_palette_audio_fragment_background_color</color>
+  <color name="component_color_audio_fragment_voiceover_progressbar_color">@color/color_palette_icon_background_secondary_color</color>
   <color name="component_color_audio_fragment_seekbar_progress_color">@color/color_palette_icon_background_secondary_color</color>
   <color name="component_color_audio_fragment_seekbar_color">@color/color_palette_seekbar_progress_background_color</color>
   <color name="component_color_audio_fragment_seekbar_thumb_shadow_color">@color/color_palette_seekbar_thumb_shadow_color</color>
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 4361dce5674..65e5ca43e22 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -8,8 +8,6 @@
   <dimen name="answer_tick_margin">12dp</dimen>
   <integer name="fade_in_duration_ms">1000</integer>
   <integer name="fade_out_duration_ms">1000</integer>
-  <dimen name="audio_fragment_corner_radius">8dp</dimen>
-  <dimen name="audio_fragment_margin">28dp</dimen>
   <dimen name="cellular_data_dialog_padding">24dp</dimen>
   <dimen name="state_previous_next_button_radius">4dp</dimen>
   <dimen name="train_checkbox_padding">18dp</dimen>
@@ -769,4 +767,10 @@
   <dimen name="resume_lesson_chapter_flexbox_margin_end">28dp</dimen>
   <dimen name="resume_lesson_chapter_flexbox_margin_top">32dp</dimen>
   <dimen name="resume_lesson_start_over_button_margin">8dp</dimen>
+
+  <!--  AudioFragment-->
+  <dimen name="audio_fragment_corner_radius">8dp</dimen>
+  <dimen name="audio_fragment_margin">28dp</dimen>
+  <dimen name="audio_fragment_progress_indicator_size">20dp</dimen>
+  <dimen name="audio_fragment_progress_indicator_track_thickness">3dp</dimen>
 </resources>
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 27c75850e7d..165f250bde4 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
@@ -1071,7 +1071,7 @@ class ExplorationActivityTest {
       onView(withId(R.id.action_audio_player)).perform(click())
 
       testCoroutineDispatchers.runCurrent()
-      onView(withId(R.id.play_pause_audio_icon)).check(matches(isDisplayed()))
+      onView(withId(R.id.audio_bar_container)).check(matches(isDisplayed()))
       onView(withText(context.getString(R.string.cellular_data_alert_dialog_title)))
         .check(doesNotExist())
     }
@@ -1295,6 +1295,43 @@ class ExplorationActivityTest {
     explorationDataController.stopPlayingExploration(isCompletion = false)
   }
 
+  @Test
+  fun testExplorationActivity_loadingAudio_progressbarIsDisplayed() {
+    markAllSpotlightsSeen()
+    setUpAudio()
+    launch<ExplorationActivity>(
+      createExplorationActivityIntent(
+        internalProfileId,
+        RATIOS_TOPIC_ID,
+        RATIOS_STORY_ID_0,
+        RATIOS_EXPLORATION_ID_0,
+        shouldSavePartialProgress = false
+      )
+    ).use {
+      explorationDataController.startPlayingNewExploration(
+        internalProfileId,
+        RATIOS_TOPIC_ID,
+        RATIOS_STORY_ID_0,
+        RATIOS_EXPLORATION_ID_0
+      )
+      networkConnectionUtil.setCurrentConnectionStatus(ProdConnectionStatus.LOCAL)
+      testCoroutineDispatchers.runCurrent()
+      onView(withId(R.id.action_audio_player)).perform(click())
+
+      testCoroutineDispatchers.runCurrent()
+      onView(withId(R.id.audio_bar_container)).check(matches(isDisplayed()))
+      onView(withId(R.id.audio_fragment_voiceover_progressbar)).check(matches(isDisplayed()))
+
+      waitForTheView(withDrawable(R.drawable.ic_pause_circle_filled_white_24dp))
+      onView(withId(R.id.play_pause_audio_icon)).check(
+        matches(
+          withDrawable(R.drawable.ic_pause_circle_filled_white_24dp)
+        )
+      )
+    }
+    explorationDataController.stopPlayingExploration(isCompletion = false)
+  }
+
   // TODO(#89): Check this test case too. It works in pair with below test cases.
   @Test
   fun testExpActivity_showUnsavedExpDialog_cancel_dismissesDialog() {