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.os.Bundle
|
||||
import android.os.SystemClock
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.view.MenuCompat
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.fragment.app.Fragment
|
||||
|
@ -313,75 +312,32 @@ class HomeFragment :
|
|||
}
|
||||
|
||||
private fun updateIndexerState(state: IndexingState?) {
|
||||
// TODO: Reduce intrusiveness of current loading state:
|
||||
// 1. "Dry" loads
|
||||
val binding = requireBinding()
|
||||
when (state) {
|
||||
is IndexingState.Completed -> setupCompleteState(binding, state.error)
|
||||
is IndexingState.Indexing -> setupIndexingState(binding, state.progress)
|
||||
null -> {
|
||||
L.d("Indexer is in indeterminate state")
|
||||
binding.homeIndexingContainer.visibility = View.INVISIBLE
|
||||
is IndexingState.Completed -> {
|
||||
binding.homeIndexingContainer.isInvisible = state.error == null
|
||||
binding.homeIndexingProgress.isInvisible = state.error != null
|
||||
binding.homeIndexingError.isInvisible = state.error == null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
is IndexingState.Indexing -> {
|
||||
binding.homeIndexingContainer.isInvisible = false
|
||||
binding.homeIndexingProgress.apply {
|
||||
isIndeterminate = false
|
||||
max = progress.explored
|
||||
this.progress = progress.loaded
|
||||
isInvisible = false
|
||||
when (state.progress) {
|
||||
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.
|
||||
val now = SystemClock.elapsedRealtime()
|
||||
if (lastUpdateTime > -1 && (now - lastUpdateTime) < 250) {
|
||||
return
|
||||
}
|
||||
lastUpdateTime = SystemClock.elapsedRealtime()
|
||||
binding.homeIndexingStatus.text =
|
||||
getString(R.string.fmt_indexing, progress.loaded, progress.explored)
|
||||
binding.homeIndexingError.isInvisible = true
|
||||
}
|
||||
null -> {
|
||||
binding.homeIndexingContainer.isInvisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,86 +65,33 @@
|
|||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
||||
tools:layout="@layout/fragment_home_list" />
|
||||
|
||||
<org.oxycblt.auxio.home.EdgeFrameLayout
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/home_indexing_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="@dimen/spacing_medium"
|
||||
android:fitsSystemWindows="true"
|
||||
android:visibility="invisible">
|
||||
android:layout_gravity="top|start"
|
||||
android:transitionGroup="true"
|
||||
android:layout_margin="@dimen/spacing_medium">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:layout_width="match_parent"
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:id="@+id/home_indexing_progress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center">
|
||||
android:layout_margin="@dimen/spacing_tiny" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:animateLayoutChanges="true">
|
||||
<ImageView
|
||||
android:id="@+id/home_indexing_error"
|
||||
android:layout_width="48dp"
|
||||
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
|
||||
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>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
|
Loading…
Reference in a new issue