mirror of
https://github.com/mihonapp/mihon.git
synced 2024-11-29 19:53:17 -05:00
Utilize more KTX extensions (#7348)
This commit is contained in:
parent
cd5bcc3673
commit
c2520bff12
20 changed files with 89 additions and 98 deletions
|
@ -29,7 +29,7 @@ class BackupCreatorJob(private val context: Context, workerParams: WorkerParamet
|
||||||
override suspend fun doWork(): Result {
|
override suspend fun doWork(): Result {
|
||||||
val preferences = Injekt.get<PreferencesHelper>()
|
val preferences = Injekt.get<PreferencesHelper>()
|
||||||
val notifier = BackupNotifier(context)
|
val notifier = BackupNotifier(context)
|
||||||
val uri = inputData.getString(LOCATION_URI_KEY)?.let { Uri.parse(it) }
|
val uri = inputData.getString(LOCATION_URI_KEY)?.toUri()
|
||||||
?: preferences.backupsDirectory().get().toUri()
|
?: preferences.backupsDirectory().get().toUri()
|
||||||
val flags = inputData.getInt(BACKUP_FLAGS_KEY, BackupConst.BACKUP_ALL)
|
val flags = inputData.getInt(BACKUP_FLAGS_KEY, BackupConst.BACKUP_ALL)
|
||||||
val isAutoBackup = inputData.getBoolean(IS_AUTO_BACKUP_KEY, true)
|
val isAutoBackup = inputData.getBoolean(IS_AUTO_BACKUP_KEY, true)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import androidx.core.net.toUri
|
||||||
import eu.kanade.tachiyomi.extension.util.ExtensionInstaller
|
import eu.kanade.tachiyomi.extension.util.ExtensionInstaller
|
||||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ object NotificationHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun openUrl(context: Context, url: String): PendingIntent {
|
fun openUrl(context: Context, url: String): PendingIntent {
|
||||||
val notificationIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
val notificationIntent = Intent(Intent.ACTION_VIEW, url.toUri())
|
||||||
return PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE)
|
return PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package eu.kanade.tachiyomi.data.saver
|
package eu.kanade.tachiyomi.data.saver
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.ContentValues
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
|
import androidx.core.content.contentValuesOf
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||||
import eu.kanade.tachiyomi.util.storage.cacheImageDir
|
import eu.kanade.tachiyomi.util.storage.cacheImageDir
|
||||||
|
@ -39,15 +39,13 @@ class ImageSaver(
|
||||||
val pictureDir =
|
val pictureDir =
|
||||||
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
|
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
|
||||||
|
|
||||||
val contentValues = ContentValues().apply {
|
val contentValues = contentValuesOf(
|
||||||
put(MediaStore.Images.Media.DISPLAY_NAME, image.name)
|
MediaStore.Images.Media.DISPLAY_NAME to image.name,
|
||||||
put(MediaStore.Images.Media.MIME_TYPE, type.mime)
|
MediaStore.Images.Media.MIME_TYPE to type.mime,
|
||||||
put(
|
MediaStore.Images.Media.RELATIVE_PATH to
|
||||||
MediaStore.Images.Media.RELATIVE_PATH,
|
|
||||||
"${Environment.DIRECTORY_PICTURES}/${context.getString(R.string.app_name)}/" +
|
"${Environment.DIRECTORY_PICTURES}/${context.getString(R.string.app_name)}/" +
|
||||||
(image.location as Location.Pictures).relativePath,
|
(image.location as Location.Pictures).relativePath,
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
val picture = context.contentResolver.insert(
|
val picture = context.contentResolver.insert(
|
||||||
pictureDir,
|
pictureDir,
|
||||||
|
|
|
@ -2,14 +2,14 @@ package eu.kanade.tachiyomi.ui.base.controller
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Editable
|
|
||||||
import android.text.TextWatcher
|
|
||||||
import android.text.style.CharacterStyle
|
import android.text.style.CharacterStyle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.appcompat.widget.SearchView
|
import androidx.appcompat.widget.SearchView
|
||||||
|
import androidx.core.text.getSpans
|
||||||
|
import androidx.core.widget.doAfterTextChanged
|
||||||
import androidx.viewbinding.ViewBinding
|
import androidx.viewbinding.ViewBinding
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||||
|
@ -59,17 +59,9 @@ abstract class SearchableNucleusController<VB : ViewBinding, P : BasePresenter<*
|
||||||
val searchAutoComplete: SearchView.SearchAutoComplete = searchView.findViewById(
|
val searchAutoComplete: SearchView.SearchAutoComplete = searchView.findViewById(
|
||||||
R.id.search_src_text,
|
R.id.search_src_text,
|
||||||
)
|
)
|
||||||
searchAutoComplete.addTextChangedListener(object : TextWatcher {
|
searchAutoComplete.doAfterTextChanged { editable ->
|
||||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
|
editable?.getSpans<CharacterStyle>()?.forEach { editable.removeSpan(it) }
|
||||||
|
}
|
||||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
|
|
||||||
|
|
||||||
override fun afterTextChanged(editable: Editable) {
|
|
||||||
editable.getSpans(0, editable.length, CharacterStyle::class.java)
|
|
||||||
.forEach { editable.removeSpan(it) }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
searchView.queryTextEvents()
|
searchView.queryTextEvents()
|
||||||
.onEach {
|
.onEach {
|
||||||
|
|
|
@ -19,7 +19,9 @@ import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceGroupAdapter
|
import androidx.preference.PreferenceGroupAdapter
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
|
import androidx.preference.get
|
||||||
import androidx.preference.getOnBindEditTextListener
|
import androidx.preference.getOnBindEditTextListener
|
||||||
|
import androidx.preference.isNotEmpty
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.preference.SharedPreferencesDataStore
|
import eu.kanade.tachiyomi.data.preference.SharedPreferencesDataStore
|
||||||
|
@ -111,8 +113,8 @@ class SourcePreferencesController(bundle: Bundle? = null) :
|
||||||
source.setupPreferenceScreen(newScreen)
|
source.setupPreferenceScreen(newScreen)
|
||||||
|
|
||||||
// Reparent the preferences
|
// Reparent the preferences
|
||||||
while (newScreen.preferenceCount != 0) {
|
while (newScreen.isNotEmpty()) {
|
||||||
val pref = newScreen.getPreference(0)
|
val pref = newScreen[0]
|
||||||
pref.isIconSpaceReserved = false
|
pref.isIconSpaceReserved = false
|
||||||
pref.order = Int.MAX_VALUE // reset to default order
|
pref.order = Int.MAX_VALUE // reset to default order
|
||||||
|
|
||||||
|
@ -143,7 +145,7 @@ class SourcePreferencesController(bundle: Bundle? = null) :
|
||||||
val screen = preference.parent!!
|
val screen = preference.parent!!
|
||||||
|
|
||||||
lastOpenPreferencePosition = (0 until screen.preferenceCount).indexOfFirst {
|
lastOpenPreferencePosition = (0 until screen.preferenceCount).indexOfFirst {
|
||||||
screen.getPreference(it) === preference
|
screen[it] === preference
|
||||||
}
|
}
|
||||||
|
|
||||||
val f = when (preference) {
|
val f = when (preference) {
|
||||||
|
@ -169,7 +171,7 @@ class SourcePreferencesController(bundle: Bundle? = null) :
|
||||||
override fun <T : Preference> findPreference(key: CharSequence): T? {
|
override fun <T : Preference> findPreference(key: CharSequence): T? {
|
||||||
// We track [lastOpenPreferencePosition] when displaying the dialog
|
// We track [lastOpenPreferencePosition] when displaying the dialog
|
||||||
// [key] isn't useful since there may be duplicates
|
// [key] isn't useful since there may be duplicates
|
||||||
return preferenceScreen!!.getPreference(lastOpenPreferencePosition!!) as T
|
return preferenceScreen!![lastOpenPreferencePosition!!] as T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.get
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
@ -202,7 +203,7 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||||
numColumnsJob?.cancel()
|
numColumnsJob?.cancel()
|
||||||
|
|
||||||
var oldPosition = RecyclerView.NO_POSITION
|
var oldPosition = RecyclerView.NO_POSITION
|
||||||
val oldRecycler = binding.catalogueView.getChildAt(1)
|
val oldRecycler = binding.catalogueView[1]
|
||||||
if (oldRecycler is RecyclerView) {
|
if (oldRecycler is RecyclerView) {
|
||||||
oldPosition = (oldRecycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
|
oldPosition = (oldRecycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
|
||||||
oldRecycler.adapter = null
|
oldRecycler.adapter = null
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.util.AttributeSet
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.get
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.kanade.tachiyomi.databinding.SourceFilterSheetBinding
|
import eu.kanade.tachiyomi.databinding.SourceFilterSheetBinding
|
||||||
|
@ -55,7 +56,7 @@ class SourceFilterSheet(
|
||||||
init {
|
init {
|
||||||
recycler.adapter = adapter
|
recycler.adapter = adapter
|
||||||
recycler.setHasFixedSize(true)
|
recycler.setHasFixedSize(true)
|
||||||
(binding.root.getChildAt(1) as ViewGroup).addView(recycler)
|
(binding.root[1] as ViewGroup).addView(recycler)
|
||||||
addView(binding.root)
|
addView(binding.root)
|
||||||
binding.filterBtn.setOnClickListener { onFilterClicked() }
|
binding.filterBtn.setOnClickListener { onFilterClicked() }
|
||||||
binding.resetBtn.setOnClickListener { onResetClicked() }
|
binding.resetBtn.setOnClickListener { onResetClicked() }
|
||||||
|
|
|
@ -3,11 +3,11 @@ package eu.kanade.tachiyomi.ui.reader
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.text.Spannable
|
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
import android.text.style.ScaleXSpan
|
import android.text.style.ScaleXSpan
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import androidx.appcompat.widget.AppCompatTextView
|
import androidx.appcompat.widget.AppCompatTextView
|
||||||
|
import androidx.core.text.set
|
||||||
import eu.kanade.tachiyomi.widget.OutlineSpan
|
import eu.kanade.tachiyomi.widget.OutlineSpan
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,10 +31,10 @@ class PageIndicatorTextView(
|
||||||
// Also add a bit of spacing between each character, as the stroke overlaps them
|
// Also add a bit of spacing between each character, as the stroke overlaps them
|
||||||
val finalText = SpannableString(currText.asIterable().joinToString("\u00A0")).apply {
|
val finalText = SpannableString(currText.asIterable().joinToString("\u00A0")).apply {
|
||||||
// Apply text outline
|
// Apply text outline
|
||||||
setSpan(spanOutline, 1, length - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
set(1, length - 1, spanOutline)
|
||||||
|
|
||||||
for (i in 1..lastIndex step 2) {
|
for (i in 1..lastIndex step 2) {
|
||||||
setSpan(ScaleXSpan(0.2f), i, i + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
set(i, i + 1, ScaleXSpan(0.2f))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ import android.view.animation.AnimationUtils
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.graphics.ColorUtils
|
import androidx.core.graphics.ColorUtils
|
||||||
import androidx.core.transition.addListener
|
import androidx.core.transition.doOnEnd
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.core.view.WindowInsetsControllerCompat
|
import androidx.core.view.WindowInsetsControllerCompat
|
||||||
|
@ -621,9 +621,9 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
|
||||||
updateCropBordersShortcut()
|
updateCropBordersShortcut()
|
||||||
if (window.sharedElementEnterTransition is MaterialContainerTransform) {
|
if (window.sharedElementEnterTransition is MaterialContainerTransform) {
|
||||||
// Wait until transition is complete to avoid crash on API 26
|
// Wait until transition is complete to avoid crash on API 26
|
||||||
window.sharedElementEnterTransition.addListener(
|
window.sharedElementEnterTransition.doOnEnd {
|
||||||
onEnd = { setOrientation(presenter.getMangaOrientationType()) },
|
setOrientation(presenter.getMangaOrientationType())
|
||||||
)
|
}
|
||||||
} else {
|
} else {
|
||||||
setOrientation(presenter.getMangaOrientationType())
|
setOrientation(presenter.getMangaOrientationType())
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,8 @@ import android.util.AttributeSet
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewPropertyAnimator
|
import android.view.ViewPropertyAnimator
|
||||||
import androidx.core.graphics.withSave
|
import androidx.core.graphics.withScale
|
||||||
|
import androidx.core.graphics.withTranslation
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
|
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.navigation.DisabledNavigation
|
import eu.kanade.tachiyomi.ui.reader.viewer.navigation.DisabledNavigation
|
||||||
|
@ -63,17 +64,15 @@ class ReaderNavigationOverlayView(context: Context, attributeSet: AttributeSet)
|
||||||
navigation?.regions?.forEach { region ->
|
navigation?.regions?.forEach { region ->
|
||||||
val rect = region.rectF
|
val rect = region.rectF
|
||||||
|
|
||||||
canvas?.withSave {
|
// Scale rect from 1f,1f to screen width and height
|
||||||
// Scale rect from 1f,1f to screen width and height
|
canvas?.withScale(width.toFloat(), height.toFloat()) {
|
||||||
scale(width.toFloat(), height.toFloat())
|
|
||||||
regionPaint.color = context.getColor(region.type.colorRes)
|
regionPaint.color = context.getColor(region.type.colorRes)
|
||||||
drawRect(rect, regionPaint)
|
drawRect(rect, regionPaint)
|
||||||
}
|
}
|
||||||
// Don't want scale anymore because it messes with drawText
|
|
||||||
canvas?.withSave {
|
|
||||||
// Translate origin to rect start (left, top)
|
|
||||||
translate((width * rect.left), (height * rect.top))
|
|
||||||
|
|
||||||
|
// Don't want scale anymore because it messes with drawText
|
||||||
|
// Translate origin to rect start (left, top)
|
||||||
|
canvas?.withTranslation(x = (width * rect.left), y = (height * rect.top)) {
|
||||||
// Calculate center of rect width on screen
|
// Calculate center of rect width on screen
|
||||||
val x = width * (abs(rect.left - rect.right) / 2)
|
val x = width * (abs(rect.left - rect.right) / 2)
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import androidx.annotation.AttrRes
|
||||||
import androidx.annotation.CallSuper
|
import androidx.annotation.CallSuper
|
||||||
import androidx.annotation.StyleRes
|
import androidx.annotation.StyleRes
|
||||||
import androidx.appcompat.widget.AppCompatImageView
|
import androidx.appcompat.widget.AppCompatImageView
|
||||||
|
import androidx.core.os.postDelayed
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import coil.dispose
|
import coil.dispose
|
||||||
import coil.imageLoader
|
import coil.imageLoader
|
||||||
|
@ -110,7 +111,7 @@ open class ReaderPageImageView @JvmOverloads constructor(
|
||||||
|
|
||||||
private fun SubsamplingScaleImageView.landscapeZoom(forward: Boolean) {
|
private fun SubsamplingScaleImageView.landscapeZoom(forward: Boolean) {
|
||||||
if (config != null && config!!.landscapeZoom && config!!.minimumScaleType == SCALE_TYPE_CENTER_INSIDE && sWidth > sHeight && scale == minScale) {
|
if (config != null && config!!.landscapeZoom && config!!.minimumScaleType == SCALE_TYPE_CENTER_INSIDE && sWidth > sHeight && scale == minScale) {
|
||||||
handler?.postDelayed({
|
handler?.postDelayed(500) {
|
||||||
val point = when (config!!.zoomStartPosition) {
|
val point = when (config!!.zoomStartPosition) {
|
||||||
ZoomStartPosition.LEFT -> if (forward) PointF(0F, 0F) else PointF(sWidth.toFloat(), 0F)
|
ZoomStartPosition.LEFT -> if (forward) PointF(0F, 0F) else PointF(sWidth.toFloat(), 0F)
|
||||||
ZoomStartPosition.RIGHT -> if (forward) PointF(sWidth.toFloat(), 0F) else PointF(0F, 0F)
|
ZoomStartPosition.RIGHT -> if (forward) PointF(sWidth.toFloat(), 0F) else PointF(0F, 0F)
|
||||||
|
@ -123,7 +124,7 @@ open class ReaderPageImageView @JvmOverloads constructor(
|
||||||
.withEasing(EASE_IN_OUT_QUAD)
|
.withEasing(EASE_IN_OUT_QUAD)
|
||||||
.withInterruptible(true)
|
.withInterruptible(true)
|
||||||
.start()
|
.start()
|
||||||
}, 500,)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import androidx.appcompat.widget.AppCompatTextView
|
import androidx.appcompat.widget.AppCompatTextView
|
||||||
|
import androidx.core.view.updatePadding
|
||||||
import com.google.android.material.progressindicator.CircularProgressIndicator
|
import com.google.android.material.progressindicator.CircularProgressIndicator
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
|
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
|
||||||
|
@ -55,7 +56,7 @@ class PagerTransitionHolder(
|
||||||
orientation = VERTICAL
|
orientation = VERTICAL
|
||||||
gravity = Gravity.CENTER
|
gravity = Gravity.CENTER
|
||||||
val sidePadding = 64.dpToPx
|
val sidePadding = 64.dpToPx
|
||||||
setPadding(sidePadding, 0, sidePadding, 0)
|
updatePadding(left = sidePadding, right = sidePadding)
|
||||||
|
|
||||||
val transitionView = ReaderTransitionView(context)
|
val transitionView = ReaderTransitionView(context)
|
||||||
addView(transitionView)
|
addView(transitionView)
|
||||||
|
|
|
@ -7,6 +7,8 @@ import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceCategory
|
import androidx.preference.PreferenceCategory
|
||||||
import androidx.preference.PreferenceGroup
|
import androidx.preference.PreferenceGroup
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
|
import androidx.preference.forEach
|
||||||
|
import androidx.preference.get
|
||||||
import eu.kanade.tachiyomi.ui.setting.SettingsAdvancedController
|
import eu.kanade.tachiyomi.ui.setting.SettingsAdvancedController
|
||||||
import eu.kanade.tachiyomi.ui.setting.SettingsAppearanceController
|
import eu.kanade.tachiyomi.ui.setting.SettingsAppearanceController
|
||||||
import eu.kanade.tachiyomi.ui.setting.SettingsBackupController
|
import eu.kanade.tachiyomi.ui.setting.SettingsBackupController
|
||||||
|
@ -56,7 +58,7 @@ object SettingsSearchHelper {
|
||||||
val settingsPrefScreen = ctrl.setupPreferenceScreen(preferenceManager.createPreferenceScreen(context))
|
val settingsPrefScreen = ctrl.setupPreferenceScreen(preferenceManager.createPreferenceScreen(context))
|
||||||
val prefCount = settingsPrefScreen.preferenceCount
|
val prefCount = settingsPrefScreen.preferenceCount
|
||||||
for (i in 0 until prefCount) {
|
for (i in 0 until prefCount) {
|
||||||
val rootPref = settingsPrefScreen.getPreference(i)
|
val rootPref = settingsPrefScreen[i]
|
||||||
if (rootPref.title == null) continue // no title, not a preference. (note: only info notes appear to not have titles)
|
if (rootPref.title == null) continue // no title, not a preference. (note: only info notes appear to not have titles)
|
||||||
getSettingSearchResult(ctrl, rootPref, "${settingsPrefScreen.title}")
|
getSettingSearchResult(ctrl, rootPref, "${settingsPrefScreen.title}")
|
||||||
}
|
}
|
||||||
|
@ -86,18 +88,14 @@ object SettingsSearchHelper {
|
||||||
when {
|
when {
|
||||||
pref is PreferenceGroup -> {
|
pref is PreferenceGroup -> {
|
||||||
val breadcrumbsStr = addLocalizedBreadcrumb(breadcrumbs, "${pref.title}")
|
val breadcrumbsStr = addLocalizedBreadcrumb(breadcrumbs, "${pref.title}")
|
||||||
|
pref.forEach {
|
||||||
for (x in 0 until pref.preferenceCount) {
|
getSettingSearchResult(ctrl, it, breadcrumbsStr) // recursion
|
||||||
val subPref = pref.getPreference(x)
|
|
||||||
getSettingSearchResult(ctrl, subPref, breadcrumbsStr) // recursion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pref is PreferenceCategory -> {
|
pref is PreferenceCategory -> {
|
||||||
val breadcrumbsStr = addLocalizedBreadcrumb(breadcrumbs, "${pref.title}")
|
val breadcrumbsStr = addLocalizedBreadcrumb(breadcrumbs, "${pref.title}")
|
||||||
|
pref.forEach {
|
||||||
for (x in 0 until pref.preferenceCount) {
|
getSettingSearchResult(ctrl, it, breadcrumbsStr) // recursion
|
||||||
val subPref = pref.getPreference(x)
|
|
||||||
getSettingSearchResult(ctrl, subPref, breadcrumbsStr) // recursion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(pref.title != null && pref.isVisible) -> {
|
(pref.title != null && pref.isVisible) -> {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package eu.kanade.tachiyomi.util.lang
|
package eu.kanade.tachiyomi.util.lang
|
||||||
|
|
||||||
import android.os.Build
|
import androidx.core.text.parseAsHtml
|
||||||
import android.text.Html
|
|
||||||
import net.greypanther.natsort.CaseInsensitiveSimpleNaturalComparator
|
import net.greypanther.natsort.CaseInsensitiveSimpleNaturalComparator
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
|
@ -64,9 +63,5 @@ fun String.takeBytes(n: Int): String {
|
||||||
* HTML-decode the string
|
* HTML-decode the string
|
||||||
*/
|
*/
|
||||||
fun String.htmlDecode(): String {
|
fun String.htmlDecode(): String {
|
||||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
return this.parseAsHtml().toString()
|
||||||
Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY).toString()
|
|
||||||
} else {
|
|
||||||
Html.fromHtml(this).toString()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -262,7 +262,7 @@ fun Context.openInBrowser(uri: Uri, forceDefaultBrowser: Boolean = false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.defaultBrowserPackageName(): String? {
|
fun Context.defaultBrowserPackageName(): String? {
|
||||||
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("http://"))
|
val browserIntent = Intent(Intent.ACTION_VIEW, "http://".toUri())
|
||||||
return packageManager.resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY)
|
return packageManager.resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY)
|
||||||
?.activityInfo?.packageName
|
?.activityInfo?.packageName
|
||||||
?.takeUnless { it in DeviceUtil.invalidDefaultBrowsers }
|
?.takeUnless { it in DeviceUtil.invalidDefaultBrowsers }
|
||||||
|
|
|
@ -16,6 +16,7 @@ import androidx.core.graphics.alpha
|
||||||
import androidx.core.graphics.applyCanvas
|
import androidx.core.graphics.applyCanvas
|
||||||
import androidx.core.graphics.blue
|
import androidx.core.graphics.blue
|
||||||
import androidx.core.graphics.createBitmap
|
import androidx.core.graphics.createBitmap
|
||||||
|
import androidx.core.graphics.get
|
||||||
import androidx.core.graphics.green
|
import androidx.core.graphics.green
|
||||||
import androidx.core.graphics.red
|
import androidx.core.graphics.red
|
||||||
import com.hippo.unifile.UniFile
|
import com.hippo.unifile.UniFile
|
||||||
|
@ -273,14 +274,14 @@ object ImageUtil {
|
||||||
val leftOffsetX = left - offsetX
|
val leftOffsetX = left - offsetX
|
||||||
val rightOffsetX = right + offsetX
|
val rightOffsetX = right + offsetX
|
||||||
|
|
||||||
val topLeftPixel = image.getPixel(left, top)
|
val topLeftPixel = image[left, top]
|
||||||
val topRightPixel = image.getPixel(right, top)
|
val topRightPixel = image[right, top]
|
||||||
val midLeftPixel = image.getPixel(left, midY)
|
val midLeftPixel = image[left, midY]
|
||||||
val midRightPixel = image.getPixel(right, midY)
|
val midRightPixel = image[right, midY]
|
||||||
val topCenterPixel = image.getPixel(midX, top)
|
val topCenterPixel = image[midX, top]
|
||||||
val botLeftPixel = image.getPixel(left, bot)
|
val botLeftPixel = image[left, bot]
|
||||||
val bottomCenterPixel = image.getPixel(midX, bot)
|
val bottomCenterPixel = image[midX, bot]
|
||||||
val botRightPixel = image.getPixel(right, bot)
|
val botRightPixel = image[right, bot]
|
||||||
|
|
||||||
val topLeftIsDark = topLeftPixel.isDark()
|
val topLeftIsDark = topLeftPixel.isDark()
|
||||||
val topRightIsDark = topRightPixel.isDark()
|
val topRightIsDark = topRightPixel.isDark()
|
||||||
|
@ -333,8 +334,8 @@ object ImageUtil {
|
||||||
var whiteStreak = false
|
var whiteStreak = false
|
||||||
val notOffset = x == left || x == right
|
val notOffset = x == left || x == right
|
||||||
inner@ for ((index, y) in (0 until image.height step image.height / 25).withIndex()) {
|
inner@ for ((index, y) in (0 until image.height step image.height / 25).withIndex()) {
|
||||||
val pixel = image.getPixel(x, y)
|
val pixel = image[x, y]
|
||||||
val pixelOff = image.getPixel(x + (if (x < image.width / 2) -offsetX else offsetX), y)
|
val pixelOff = image[x + (if (x < image.width / 2) -offsetX else offsetX), y]
|
||||||
if (pixel.isWhite()) {
|
if (pixel.isWhite()) {
|
||||||
whitePixelsStreak++
|
whitePixelsStreak++
|
||||||
whitePixels++
|
whitePixels++
|
||||||
|
@ -425,8 +426,8 @@ object ImageUtil {
|
||||||
val topCornersIsDark = topLeftIsDark && topRightIsDark
|
val topCornersIsDark = topLeftIsDark && topRightIsDark
|
||||||
val botCornersIsDark = botLeftIsDark && botRightIsDark
|
val botCornersIsDark = botLeftIsDark && botRightIsDark
|
||||||
|
|
||||||
val topOffsetCornersIsDark = image.getPixel(leftOffsetX, top).isDark() && image.getPixel(rightOffsetX, top).isDark()
|
val topOffsetCornersIsDark = image[leftOffsetX, top].isDark() && image[rightOffsetX, top].isDark()
|
||||||
val botOffsetCornersIsDark = image.getPixel(leftOffsetX, bot).isDark() && image.getPixel(rightOffsetX, bot).isDark()
|
val botOffsetCornersIsDark = image[leftOffsetX, bot].isDark() && image[rightOffsetX, bot].isDark()
|
||||||
|
|
||||||
val gradient = when {
|
val gradient = when {
|
||||||
darkBG && botCornersIsWhite -> {
|
darkBG && botCornersIsWhite -> {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.widget
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
|
import androidx.core.content.withStyledAttributes
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
@ -27,9 +28,9 @@ class AutofitRecyclerView @JvmOverloads constructor(context: Context, attrs: Att
|
||||||
init {
|
init {
|
||||||
if (attrs != null) {
|
if (attrs != null) {
|
||||||
val attrsArray = intArrayOf(android.R.attr.columnWidth)
|
val attrsArray = intArrayOf(android.R.attr.columnWidth)
|
||||||
val array = context.obtainStyledAttributes(attrs, attrsArray)
|
context.withStyledAttributes(attrs, attrsArray) {
|
||||||
columnWidth = array.getDimensionPixelSize(0, -1)
|
columnWidth = getDimensionPixelSize(0, -1)
|
||||||
array.recycle()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
layoutManager = manager
|
layoutManager = manager
|
||||||
|
|
|
@ -9,6 +9,7 @@ import androidx.annotation.AttrRes
|
||||||
import androidx.annotation.CallSuper
|
import androidx.annotation.CallSuper
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.core.view.updatePadding
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||||
|
@ -230,7 +231,7 @@ open class ExtendedNavigationView @JvmOverloads constructor(
|
||||||
is SeparatorHolder -> {
|
is SeparatorHolder -> {
|
||||||
val view = holder.itemView
|
val view = holder.itemView
|
||||||
val item = items[position] as Item.Separator
|
val item = items[position] as Item.Separator
|
||||||
view.setPadding(0, item.paddingTop, 0, item.paddingBottom)
|
view.updatePadding(top = item.paddingTop, bottom = item.paddingBottom)
|
||||||
}
|
}
|
||||||
is RadioHolder -> {
|
is RadioHolder -> {
|
||||||
val item = items[position] as Item.Radio
|
val item = items[position] as Item.Radio
|
||||||
|
|
|
@ -11,6 +11,7 @@ import androidx.annotation.ArrayRes
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
import androidx.appcompat.view.menu.MenuBuilder
|
import androidx.appcompat.view.menu.MenuBuilder
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
|
import androidx.core.content.withStyledAttributes
|
||||||
import androidx.core.view.forEach
|
import androidx.core.view.forEach
|
||||||
import androidx.core.view.get
|
import androidx.core.view.get
|
||||||
import com.fredporciuncula.flow.preferences.Preference
|
import com.fredporciuncula.flow.preferences.Preference
|
||||||
|
@ -51,16 +52,15 @@ class MaterialSpinnerView @JvmOverloads constructor(context: Context, attrs: Att
|
||||||
init {
|
init {
|
||||||
addView(binding.root)
|
addView(binding.root)
|
||||||
|
|
||||||
val attr = context.obtainStyledAttributes(attrs, R.styleable.MaterialSpinnerView)
|
context.withStyledAttributes(set = attrs, attrs = R.styleable.MaterialSpinnerView) {
|
||||||
|
val title = getString(R.styleable.MaterialSpinnerView_title).orEmpty()
|
||||||
|
binding.title.text = title
|
||||||
|
|
||||||
val title = attr.getString(R.styleable.MaterialSpinnerView_title).orEmpty()
|
val viewEntries = (getTextArray(R.styleable.MaterialSpinnerView_android_entries)
|
||||||
binding.title.text = title
|
?: emptyArray()).map { it.toString() }
|
||||||
|
entries = viewEntries
|
||||||
val entries = (attr.getTextArray(R.styleable.MaterialSpinnerView_android_entries) ?: emptyArray()).map { it.toString() }
|
binding.details.text = viewEntries.firstOrNull().orEmpty()
|
||||||
this.entries = entries
|
}
|
||||||
binding.details.text = entries.firstOrNull().orEmpty()
|
|
||||||
|
|
||||||
attr.recycle()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setSelection(selection: Int) {
|
fun setSelection(selection: Int) {
|
||||||
|
@ -152,9 +152,7 @@ class MaterialSpinnerView @JvmOverloads constructor(context: Context, attrs: Att
|
||||||
popup.menu.forEach {
|
popup.menu.forEach {
|
||||||
it.icon = emptyIcon
|
it.icon = emptyIcon
|
||||||
}
|
}
|
||||||
popup.menu.getItem(selectedPosition)?.let {
|
popup.menu[selectedPosition].icon = checkmarkIcon
|
||||||
it.icon = checkmarkIcon
|
|
||||||
}
|
|
||||||
popup.setOnMenuItemClickListener { menuItem ->
|
popup.setOnMenuItemClickListener { menuItem ->
|
||||||
val pos = menuClicked(menuItem)
|
val pos = menuClicked(menuItem)
|
||||||
onItemClick(pos)
|
onItemClick(pos)
|
||||||
|
|
|
@ -12,6 +12,8 @@ import android.util.AttributeSet
|
||||||
import android.view.animation.LinearInterpolator
|
import android.view.animation.LinearInterpolator
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.annotation.FloatRange
|
import androidx.annotation.FloatRange
|
||||||
|
import androidx.core.graphics.drawable.updateBounds
|
||||||
|
import androidx.core.graphics.withTranslation
|
||||||
import androidx.lifecycle.coroutineScope
|
import androidx.lifecycle.coroutineScope
|
||||||
import androidx.lifecycle.findViewTreeLifecycleOwner
|
import androidx.lifecycle.findViewTreeLifecycleOwner
|
||||||
import com.google.android.material.shape.MaterialShapeDrawable
|
import com.google.android.material.shape.MaterialShapeDrawable
|
||||||
|
@ -84,15 +86,14 @@ class TachiyomiAppBarLayout @JvmOverloads constructor(
|
||||||
|
|
||||||
override fun draw(canvas: Canvas) {
|
override fun draw(canvas: Canvas) {
|
||||||
super.draw(canvas)
|
super.draw(canvas)
|
||||||
val saveCount = canvas.save()
|
canvas.withTranslation(y = -currentOffset.toFloat()) {
|
||||||
canvas.translate(0f, -currentOffset.toFloat())
|
statusBarForeground?.draw(this)
|
||||||
statusBarForeground?.draw(canvas)
|
}
|
||||||
canvas.restoreToCount(saveCount)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
|
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
|
||||||
super.onLayout(changed, l, t, r, b)
|
super.onLayout(changed, l, t, r, b)
|
||||||
statusBarForeground?.setBounds(0, 0, width, paddingTop)
|
statusBarForeground?.updateBounds(right = width, bottom = paddingTop)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOffsetChanged(offset: Int) {
|
override fun onOffsetChanged(offset: Int) {
|
||||||
|
|
Loading…
Reference in a new issue