Update storage usage indicator
This commit is contained in:
@@ -10,9 +10,11 @@ import android.view.ViewOutlineProvider
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.FloatRange
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import org.koitharu.kotatsu.parsers.util.replaceWith
|
||||
import org.koitharu.kotatsu.utils.ext.resolveDp
|
||||
import com.google.android.material.R as materialR
|
||||
import kotlin.random.Random
|
||||
import org.koitharu.kotatsu.parsers.util.replaceWith
|
||||
import org.koitharu.kotatsu.utils.ext.getThemeColor
|
||||
import org.koitharu.kotatsu.utils.ext.resolveDp
|
||||
|
||||
class SegmentedBarView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
@@ -22,17 +24,20 @@ class SegmentedBarView @JvmOverloads constructor(
|
||||
|
||||
private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
|
||||
private val segmentsData = ArrayList<Segment>()
|
||||
private val minSegmentSize = context.resources.resolveDp(3f)
|
||||
private val segmentsSizes = ArrayList<Float>()
|
||||
private val outlineColor = context.getThemeColor(materialR.attr.colorOutline)
|
||||
private var cornerSize = 0f
|
||||
|
||||
var segments: List<Segment>
|
||||
get() = segmentsData
|
||||
set(value) {
|
||||
segmentsData.replaceWith(value)
|
||||
updateSizes()
|
||||
invalidate()
|
||||
}
|
||||
|
||||
init {
|
||||
paint.style = Paint.Style.FILL
|
||||
paint.strokeWidth = context.resources.resolveDp(1f)
|
||||
outlineProvider = OutlineProvider()
|
||||
clipToOutline = true
|
||||
|
||||
@@ -46,15 +51,44 @@ class SegmentedBarView @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
||||
super.onSizeChanged(w, h, oldw, oldh)
|
||||
cornerSize = h / 2f
|
||||
updateSizes()
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
var x = 0f
|
||||
val w = width.toFloat()
|
||||
for (segment in segmentsData) {
|
||||
paint.color = segment.color
|
||||
val segmentWidth = (w * segment.percent).coerceAtLeast(minSegmentSize)
|
||||
canvas.drawRect(x, 0f, x + segmentWidth, height.toFloat(), paint)
|
||||
x += segmentWidth
|
||||
if (segmentsSizes.isEmpty()) {
|
||||
return
|
||||
}
|
||||
val w = width.toFloat()
|
||||
var x = w - segmentsSizes.last()
|
||||
for (i in (0 until segmentsData.size).reversed()) {
|
||||
val segment = segmentsData[i]
|
||||
paint.color = segment.color
|
||||
paint.style = Paint.Style.FILL
|
||||
val segmentWidth = segmentsSizes[i]
|
||||
canvas.drawRoundRect(0f, 0f, x + cornerSize, height.toFloat(), cornerSize, cornerSize, paint)
|
||||
paint.color = outlineColor
|
||||
paint.style = Paint.Style.STROKE
|
||||
canvas.drawRoundRect(0f, 0f, x + cornerSize, height.toFloat(), cornerSize, cornerSize, paint)
|
||||
x -= segmentWidth
|
||||
}
|
||||
paint.color = outlineColor
|
||||
paint.style = Paint.Style.STROKE
|
||||
canvas.drawRoundRect(0f, 0f, w, height.toFloat(), cornerSize, cornerSize, paint)
|
||||
}
|
||||
|
||||
private fun updateSizes() {
|
||||
segmentsSizes.clear()
|
||||
segmentsSizes.ensureCapacity(segmentsData.size + 1)
|
||||
var w = width.toFloat()
|
||||
for (segment in segmentsData) {
|
||||
val segmentWidth = (w * segment.percent).coerceAtLeast(cornerSize)
|
||||
segmentsSizes.add(segmentWidth)
|
||||
w -= segmentWidth
|
||||
}
|
||||
segmentsSizes.add(w)
|
||||
}
|
||||
|
||||
class Segment(
|
||||
@@ -86,4 +120,4 @@ class SegmentedBarView @JvmOverloads constructor(
|
||||
outline.setRoundRect(0, 0, view.width, view.height, view.height / 2f)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,11 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat.startActivity
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import coil.ImageLoader
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
@@ -15,6 +17,7 @@ import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.domain.reverseAsync
|
||||
import org.koitharu.kotatsu.base.ui.BaseFragment
|
||||
import org.koitharu.kotatsu.base.ui.list.SectionedSelectionController
|
||||
import org.koitharu.kotatsu.base.ui.util.RecyclerViewOwner
|
||||
import org.koitharu.kotatsu.base.ui.util.ReversibleAction
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.databinding.FragmentLibraryBinding
|
||||
@@ -34,6 +37,7 @@ import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
@AndroidEntryPoint
|
||||
class LibraryFragment :
|
||||
BaseFragment<FragmentLibraryBinding>(),
|
||||
RecyclerViewOwner,
|
||||
LibraryListEventListener {
|
||||
|
||||
@Inject
|
||||
@@ -46,6 +50,9 @@ class LibraryFragment :
|
||||
private var adapter: LibraryAdapter? = null
|
||||
private var selectionController: SectionedSelectionController<LibrarySectionModel>? = null
|
||||
|
||||
override val recyclerView: RecyclerView
|
||||
get() = binding.recyclerView
|
||||
|
||||
override fun onInflateView(inflater: LayoutInflater, container: ViewGroup?): FragmentLibraryBinding {
|
||||
return FragmentLibraryBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@ class SettingsActivity :
|
||||
ACTION_READER -> ReaderSettingsFragment()
|
||||
ACTION_SUGGESTIONS -> SuggestionsSettingsFragment()
|
||||
ACTION_SHIKIMORI -> ShikimoriSettingsFragment()
|
||||
ACTION_HISTORY -> HistorySettingsFragment()
|
||||
ACTION_TRACKER -> TrackerSettingsFragment()
|
||||
ACTION_SOURCE -> SourceSettingsFragment.newInstance(
|
||||
intent.getSerializableExtra(EXTRA_SOURCE) as? MangaSource ?: MangaSource.LOCAL,
|
||||
@@ -153,6 +154,7 @@ class SettingsActivity :
|
||||
private const val ACTION_READER = "${BuildConfig.APPLICATION_ID}.action.MANAGE_READER_SETTINGS"
|
||||
private const val ACTION_SUGGESTIONS = "${BuildConfig.APPLICATION_ID}.action.MANAGE_SUGGESTIONS"
|
||||
private const val ACTION_TRACKER = "${BuildConfig.APPLICATION_ID}.action.MANAGE_TRACKER"
|
||||
private const val ACTION_HISTORY = "${BuildConfig.APPLICATION_ID}.action.MANAGE_HISTORY"
|
||||
private const val ACTION_SOURCE = "${BuildConfig.APPLICATION_ID}.action.MANAGE_SOURCE_SETTINGS"
|
||||
private const val ACTION_SHIKIMORI = "${BuildConfig.APPLICATION_ID}.action.MANAGE_SHIKIMORI_SETTINGS"
|
||||
private const val ACTION_MANAGE_SOURCES = "${BuildConfig.APPLICATION_ID}.action.MANAGE_SOURCES_LIST"
|
||||
@@ -178,6 +180,10 @@ class SettingsActivity :
|
||||
Intent(context, SettingsActivity::class.java)
|
||||
.setAction(ACTION_TRACKER)
|
||||
|
||||
fun newHistorySettingsIntent(context: Context) =
|
||||
Intent(context, SettingsActivity::class.java)
|
||||
.setAction(ACTION_HISTORY)
|
||||
|
||||
fun newManageSourcesIntent(context: Context) =
|
||||
Intent(context, SettingsActivity::class.java)
|
||||
.setAction(ACTION_MANAGE_SOURCES)
|
||||
|
||||
@@ -60,6 +60,7 @@ class ToolsFragment :
|
||||
override fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.button_settings -> startActivity(SettingsActivity.newIntent(v.context))
|
||||
R.id.button_manage -> startActivity(SettingsActivity.newHistorySettingsIntent(v.context))
|
||||
R.id.button_downloads -> startActivity(DownloadsActivity.newIntent(v.context))
|
||||
R.id.button_download -> {
|
||||
val url = viewModel.appUpdate.value?.apkUrl ?: return
|
||||
@@ -98,6 +99,7 @@ class ToolsFragment :
|
||||
val otherSegment = SegmentedBarView.Segment(usage.otherCache.percent, segmentColor(3))
|
||||
|
||||
with(binding.layoutStorage) {
|
||||
buttonManage.setOnClickListener(this@ToolsFragment)
|
||||
bar.segments = listOf(storageSegment, pagesSegment, otherSegment)
|
||||
val pattern = getString(R.string.memory_usage_pattern)
|
||||
labelStorage.text = pattern.format(
|
||||
@@ -131,7 +133,7 @@ class ToolsFragment :
|
||||
@ColorInt
|
||||
private fun segmentColor(i: Int): Int {
|
||||
val hue = (93.6f * i) % 360
|
||||
val color = ColorUtils.HSLToColor(floatArrayOf(hue, 0.5f, 0.5f))
|
||||
val color = ColorUtils.HSLToColor(floatArrayOf(hue, 0.4f, 0.6f))
|
||||
val backgroundColor = requireContext().getThemeColor(materialR.attr.colorSecondaryContainer)
|
||||
return MaterialColors.harmonize(color, backgroundColor)
|
||||
}
|
||||
|
||||
@@ -6,19 +6,36 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/screen_padding">
|
||||
android:paddingStart="@dimen/screen_padding"
|
||||
android:paddingTop="@dimen/margin_small"
|
||||
android:paddingBottom="@dimen/screen_padding"
|
||||
tools:ignore="RtlSymmetry">
|
||||
|
||||
<TextView
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/storage_usage"
|
||||
android:textAppearance="?textAppearanceTitleMedium" />
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/storage_usage"
|
||||
android:textAppearance="?textAppearanceTitleMedium" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_manage"
|
||||
style="@style/Widget.Material3.Button.TextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/manage" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<org.koitharu.kotatsu.base.ui.widgets.SegmentedBarView
|
||||
android:id="@+id/bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"
|
||||
android:layout_marginVertical="@dimen/margin_normal"
|
||||
android:layout_height="16dp"
|
||||
android:layout_marginEnd="@dimen/screen_padding"
|
||||
android:background="?colorSecondaryContainer" />
|
||||
|
||||
<TextView
|
||||
@@ -26,6 +43,8 @@
|
||||
style="@style/Widget.Kotatsu.TextView.Indicator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_normal"
|
||||
android:layout_marginEnd="@dimen/screen_padding"
|
||||
android:text="@string/saved_manga"
|
||||
android:visibility="gone"
|
||||
app:drawableStartCompat="@drawable/bg_circle"
|
||||
@@ -38,6 +57,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_small"
|
||||
android:layout_marginEnd="@dimen/screen_padding"
|
||||
android:text="@string/pages_cache"
|
||||
android:visibility="gone"
|
||||
app:drawableStartCompat="@drawable/bg_circle"
|
||||
@@ -50,6 +70,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_small"
|
||||
android:layout_marginEnd="@dimen/screen_padding"
|
||||
android:text="@string/other_cache"
|
||||
android:visibility="gone"
|
||||
app:drawableStartCompat="@drawable/bg_circle"
|
||||
@@ -62,8 +83,9 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_small"
|
||||
android:layout_marginEnd="@dimen/screen_padding"
|
||||
android:text="@string/computing_"
|
||||
app:drawableStartCompat="@drawable/bg_circle"
|
||||
app:drawableTint="?colorSecondaryContainer" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
Reference in New Issue
Block a user