home: make loading indicator less intrusive
This commit is contained in:
parent
64ce312976
commit
9ccc4cf2ae
2 changed files with 43 additions and 140 deletions
|
@ -20,13 +20,12 @@ package org.oxycblt.auxio.home
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.SystemClock
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.core.view.MenuCompat
|
import androidx.core.view.MenuCompat
|
||||||
|
import androidx.core.view.isInvisible
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
@ -313,75 +312,32 @@ class HomeFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateIndexerState(state: IndexingState?) {
|
private fun updateIndexerState(state: IndexingState?) {
|
||||||
// TODO: Reduce intrusiveness of current loading state:
|
|
||||||
// 1. "Dry" loads
|
|
||||||
val binding = requireBinding()
|
val binding = requireBinding()
|
||||||
when (state) {
|
when (state) {
|
||||||
is IndexingState.Completed -> setupCompleteState(binding, state.error)
|
is IndexingState.Completed -> {
|
||||||
is IndexingState.Indexing -> setupIndexingState(binding, state.progress)
|
binding.homeIndexingContainer.isInvisible = state.error == null
|
||||||
null -> {
|
binding.homeIndexingProgress.isInvisible = state.error != null
|
||||||
L.d("Indexer is in indeterminate state")
|
binding.homeIndexingError.isInvisible = state.error == null
|
||||||
binding.homeIndexingContainer.visibility = View.INVISIBLE
|
|
||||||
}
|
}
|
||||||
}
|
is IndexingState.Indexing -> {
|
||||||
}
|
binding.homeIndexingContainer.isInvisible = false
|
||||||
|
|
||||||
private fun setupCompleteState(binding: FragmentHomeBinding, error: Exception?) {
|
|
||||||
if (error == null) {
|
|
||||||
L.d("Received ok response")
|
|
||||||
binding.homeIndexingContainer.visibility = View.INVISIBLE
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
L.d("Received non-ok response")
|
|
||||||
val context = requireContext()
|
|
||||||
binding.homeIndexingContainer.visibility = View.VISIBLE
|
|
||||||
binding.homeIndexingProgress.visibility = View.INVISIBLE
|
|
||||||
binding.homeIndexingActions.visibility = View.VISIBLE
|
|
||||||
|
|
||||||
L.d("Showing generic error")
|
|
||||||
binding.homeIndexingStatus.setText(R.string.err_index_failed)
|
|
||||||
// Configure the action to act as a reload trigger.
|
|
||||||
binding.homeIndexingTry.apply {
|
|
||||||
visibility = View.VISIBLE
|
|
||||||
text = context.getString(R.string.lbl_retry)
|
|
||||||
setOnClickListener { musicModel.rescan() }
|
|
||||||
}
|
|
||||||
binding.homeIndexingMore.apply {
|
|
||||||
visibility = View.VISIBLE
|
|
||||||
setOnClickListener {
|
|
||||||
findNavController().navigateSafe(HomeFragmentDirections.reportError(error))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupIndexingState(binding: FragmentHomeBinding, progress: IndexingProgress) {
|
|
||||||
// Remove all content except for the progress indicator.
|
|
||||||
binding.homeIndexingContainer.visibility = View.VISIBLE
|
|
||||||
binding.homeIndexingProgress.visibility = View.VISIBLE
|
|
||||||
binding.homeIndexingActions.visibility = View.INVISIBLE
|
|
||||||
|
|
||||||
when (progress) {
|
|
||||||
is IndexingProgress.Indeterminate -> {
|
|
||||||
// In a query/initialization state, show a generic loading status.
|
|
||||||
binding.homeIndexingStatus.text = getString(R.string.lng_indexing)
|
|
||||||
binding.homeIndexingProgress.isIndeterminate = true
|
|
||||||
}
|
|
||||||
is IndexingProgress.Songs -> {
|
|
||||||
// Actively loading songs, show the current progress.
|
|
||||||
binding.homeIndexingProgress.apply {
|
binding.homeIndexingProgress.apply {
|
||||||
isIndeterminate = false
|
isInvisible = false
|
||||||
max = progress.explored
|
when (state.progress) {
|
||||||
this.progress = progress.loaded
|
is IndexingProgress.Songs -> {
|
||||||
|
isIndeterminate = false
|
||||||
|
progress = state.progress.loaded
|
||||||
|
max = state.progress.explored
|
||||||
|
}
|
||||||
|
is IndexingProgress.Indeterminate -> {
|
||||||
|
isIndeterminate = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Avoid aggressively updating the UI for rapid progress updates.
|
binding.homeIndexingError.isInvisible = true
|
||||||
val now = SystemClock.elapsedRealtime()
|
}
|
||||||
if (lastUpdateTime > -1 && (now - lastUpdateTime) < 250) {
|
null -> {
|
||||||
return
|
binding.homeIndexingContainer.isInvisible = true
|
||||||
}
|
|
||||||
lastUpdateTime = SystemClock.elapsedRealtime()
|
|
||||||
binding.homeIndexingStatus.text =
|
|
||||||
getString(R.string.fmt_indexing, progress.loaded, progress.explored)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,86 +65,33 @@
|
||||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
||||||
tools:layout="@layout/fragment_home_list" />
|
tools:layout="@layout/fragment_home_list" />
|
||||||
|
|
||||||
<org.oxycblt.auxio.home.EdgeFrameLayout
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:id="@+id/home_indexing_container"
|
android:id="@+id/home_indexing_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="top|start"
|
||||||
android:layout_margin="@dimen/spacing_medium"
|
android:transitionGroup="true"
|
||||||
android:fitsSystemWindows="true"
|
android:layout_margin="@dimen/spacing_medium">
|
||||||
android:visibility="invisible">
|
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/home_indexing_progress"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center">
|
android:layout_margin="@dimen/spacing_tiny" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<ImageView
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/home_indexing_error"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="48dp"
|
||||||
android:animateLayoutChanges="true">
|
android:layout_height="48dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:contentDescription="@string/err_index_failed"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
android:src="@drawable/ic_feature_request_24"
|
||||||
|
app:tint="?attr/colorError"
|
||||||
|
tools:visibility="invisible" />
|
||||||
|
|
||||||
<TextView
|
</com.google.android.material.card.MaterialCardView>
|
||||||
android:id="@+id/home_indexing_status"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="@dimen/spacing_medium"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="@string/lng_indexing"
|
|
||||||
android:textAppearance="@style/TextAppearance.Auxio.BodyLarge"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/home_indexing_actions"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintVertical_chainStyle="packed"
|
|
||||||
tools:text="Status" />
|
|
||||||
|
|
||||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
|
||||||
android:id="@+id/home_indexing_progress"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="@dimen/spacing_medium"
|
|
||||||
android:layout_marginEnd="@dimen/spacing_medium"
|
|
||||||
android:indeterminate="true"
|
|
||||||
app:indeterminateAnimationType="disjoint"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/home_indexing_actions"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/home_indexing_actions" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/home_indexing_actions"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="@dimen/spacing_medium"
|
|
||||||
android:layout_marginEnd="@dimen/spacing_medium"
|
|
||||||
android:layout_marginBottom="@dimen/spacing_medium"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:visibility="invisible"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
tools:layout_editor_absoluteX="16dp">
|
|
||||||
|
|
||||||
<org.oxycblt.auxio.ui.RippleFixMaterialButton
|
|
||||||
android:id="@+id/home_indexing_try"
|
|
||||||
style="@style/Widget.Auxio.Button.Primary"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="@dimen/spacing_small"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/lbl_retry" />
|
|
||||||
|
|
||||||
<org.oxycblt.auxio.ui.RippleFixMaterialButton
|
|
||||||
android:id="@+id/home_indexing_more"
|
|
||||||
style="@style/Widget.Auxio.Button.Secondary"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="@dimen/spacing_small"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/lbl_show_error_info" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
|
||||||
|
|
||||||
</org.oxycblt.auxio.home.EdgeFrameLayout>
|
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue