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() {