mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-20 06:29:17 +01:00
Change sorting order of installed extensions
Default is Name Other options are Recently updated, Recently installed, and Language
This commit is contained in:
parent
fa80fa94a0
commit
7e812f9530
@ -152,6 +152,8 @@ object PreferenceKeys {
|
|||||||
|
|
||||||
const val automaticExtUpdates = "automatic_ext_updates"
|
const val automaticExtUpdates = "automatic_ext_updates"
|
||||||
|
|
||||||
|
const val installedExtensionsOrder = "installed_extensions_order"
|
||||||
|
|
||||||
const val autoHideHopper = "autohide_hopper"
|
const val autoHideHopper = "autohide_hopper"
|
||||||
|
|
||||||
const val hopperLongPress = "hopper_long_press"
|
const val hopperLongPress = "hopper_long_press"
|
||||||
|
@ -14,6 +14,7 @@ import eu.kanade.tachiyomi.R
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
import eu.kanade.tachiyomi.data.track.TrackService
|
||||||
import eu.kanade.tachiyomi.data.updater.AutoUpdaterJob
|
import eu.kanade.tachiyomi.data.updater.AutoUpdaterJob
|
||||||
|
import eu.kanade.tachiyomi.extension.model.InstalledExtensionsOrder
|
||||||
import eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet
|
import eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet
|
||||||
import eu.kanade.tachiyomi.ui.reader.settings.OrientationType
|
import eu.kanade.tachiyomi.ui.reader.settings.OrientationType
|
||||||
import eu.kanade.tachiyomi.ui.reader.settings.PageLayout
|
import eu.kanade.tachiyomi.ui.reader.settings.PageLayout
|
||||||
@ -297,6 +298,8 @@ class PreferencesHelper(val context: Context) {
|
|||||||
|
|
||||||
fun automaticExtUpdates() = flowPrefs.getBoolean(Keys.automaticExtUpdates, true)
|
fun automaticExtUpdates() = flowPrefs.getBoolean(Keys.automaticExtUpdates, true)
|
||||||
|
|
||||||
|
fun installedExtensionsOrder() = flowPrefs.getInt(Keys.installedExtensionsOrder, InstalledExtensionsOrder.Name.value)
|
||||||
|
|
||||||
fun collapsedCategories() = rxPrefs.getStringSet("collapsed_categories", mutableSetOf())
|
fun collapsedCategories() = rxPrefs.getStringSet("collapsed_categories", mutableSetOf())
|
||||||
|
|
||||||
fun collapsedDynamicCategories() = flowPrefs.getStringSet("collapsed_dynamic_categories", mutableSetOf())
|
fun collapsedDynamicCategories() = flowPrefs.getStringSet("collapsed_dynamic_categories", mutableSetOf())
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.model
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
|
|
||||||
|
enum class InstalledExtensionsOrder(val value: Int, @StringRes val nameRes: Int) {
|
||||||
|
Name(0, R.string.name),
|
||||||
|
RecentlyUpdated(1, R.string.recently_updated),
|
||||||
|
RecentlyInstalled(2, R.string.recently_installed),
|
||||||
|
Language(3, R.string.language),
|
||||||
|
;
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun fromValue(preference: Int) = values().find { it.value == preference } ?: Name
|
||||||
|
fun fromPreference(pref: PreferencesHelper) = fromValue(pref.installedExtensionsOrder().get())
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,11 @@
|
|||||||
package eu.kanade.tachiyomi.ui.extension
|
package eu.kanade.tachiyomi.ui.extension
|
||||||
|
|
||||||
|
import android.widget.TextView
|
||||||
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.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.ui.extension.ExtensionAdapter.OnButtonClickListener
|
import eu.kanade.tachiyomi.ui.extension.ExtensionAdapter.OnButtonClickListener
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter that holds the catalogue cards.
|
* Adapter that holds the catalogue cards.
|
||||||
@ -12,6 +15,10 @@ import eu.kanade.tachiyomi.ui.extension.ExtensionAdapter.OnButtonClickListener
|
|||||||
class ExtensionAdapter(val listener: OnButtonClickListener) :
|
class ExtensionAdapter(val listener: OnButtonClickListener) :
|
||||||
FlexibleAdapter<IFlexible<*>>(null, listener, true) {
|
FlexibleAdapter<IFlexible<*>>(null, listener, true) {
|
||||||
|
|
||||||
|
val preferences: PreferencesHelper by injectLazy()
|
||||||
|
|
||||||
|
var installedSortOrder = preferences.installedExtensionsOrder().get()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setDisplayHeadersAtStartUp(true)
|
setDisplayHeadersAtStartUp(true)
|
||||||
}
|
}
|
||||||
@ -25,5 +32,6 @@ class ExtensionAdapter(val listener: OnButtonClickListener) :
|
|||||||
fun onButtonClick(position: Int)
|
fun onButtonClick(position: Int)
|
||||||
fun onCancelClick(position: Int)
|
fun onCancelClick(position: Int)
|
||||||
fun onUpdateAllClicked(position: Int)
|
fun onUpdateAllClicked(position: Int)
|
||||||
|
fun onExtSortClicked(view: TextView, position: Int)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.extension.ExtensionManager
|
|||||||
import eu.kanade.tachiyomi.extension.ExtensionsChangedListener
|
import eu.kanade.tachiyomi.extension.ExtensionsChangedListener
|
||||||
import eu.kanade.tachiyomi.extension.model.Extension
|
import eu.kanade.tachiyomi.extension.model.Extension
|
||||||
import eu.kanade.tachiyomi.extension.model.InstallStep
|
import eu.kanade.tachiyomi.extension.model.InstallStep
|
||||||
|
import eu.kanade.tachiyomi.extension.model.InstalledExtensionsOrder
|
||||||
import eu.kanade.tachiyomi.source.LocalSource
|
import eu.kanade.tachiyomi.source.LocalSource
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
@ -24,7 +25,6 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.awaitAll
|
import kotlinx.coroutines.awaitAll
|
||||||
import kotlinx.coroutines.flow.collect
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.flow.filter
|
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@ -181,11 +181,25 @@ class ExtensionBottomPresenter(
|
|||||||
|
|
||||||
val items = mutableListOf<ExtensionItem>()
|
val items = mutableListOf<ExtensionItem>()
|
||||||
|
|
||||||
val updatesSorted = installed.filter { it.hasUpdate && (showNsfwExtensions || !it.isNsfw) }.sortedBy { it.pkgName }
|
val updatesSorted = installed.filter { it.hasUpdate && (showNsfwExtensions || !it.isNsfw) }.sortedBy { it.name }
|
||||||
|
val sortOrder = InstalledExtensionsOrder.fromPreference(preferences)
|
||||||
val installedSorted = installed
|
val installedSorted = installed
|
||||||
.filter { !it.hasUpdate && (showNsfwExtensions || !it.isNsfw) }
|
.filter { !it.hasUpdate && (showNsfwExtensions || !it.isNsfw) }
|
||||||
.sortedWith(compareBy({ !it.isObsolete }, { it.pkgName }))
|
.sortedWith(
|
||||||
val untrustedSorted = untrusted.sortedBy { it.pkgName }
|
compareBy(
|
||||||
|
{ !it.isObsolete },
|
||||||
|
{
|
||||||
|
when (sortOrder) {
|
||||||
|
InstalledExtensionsOrder.Name -> it.name
|
||||||
|
InstalledExtensionsOrder.RecentlyUpdated -> Long.MAX_VALUE - extensionUpdateDate(it.pkgName)
|
||||||
|
InstalledExtensionsOrder.RecentlyInstalled -> Long.MAX_VALUE - extensionInstallDate(it.pkgName)
|
||||||
|
InstalledExtensionsOrder.Language -> it.lang
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ it.name }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val untrustedSorted = untrusted.sortedBy { it.name }
|
||||||
val availableSorted = available
|
val availableSorted = available
|
||||||
// Filter out already installed extensions and disabled languages
|
// Filter out already installed extensions and disabled languages
|
||||||
.filter { avail ->
|
.filter { avail ->
|
||||||
@ -194,7 +208,7 @@ class ExtensionBottomPresenter(
|
|||||||
(avail.lang in activeLangs || avail.lang == "all") &&
|
(avail.lang in activeLangs || avail.lang == "all") &&
|
||||||
(showNsfwExtensions || !avail.isNsfw)
|
(showNsfwExtensions || !avail.isNsfw)
|
||||||
}
|
}
|
||||||
.sortedBy { it.pkgName }
|
.sortedBy { it.name }
|
||||||
|
|
||||||
if (updatesSorted.isNotEmpty()) {
|
if (updatesSorted.isNotEmpty()) {
|
||||||
val header = ExtensionGroupItem(
|
val header = ExtensionGroupItem(
|
||||||
@ -211,7 +225,7 @@ class ExtensionBottomPresenter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (installedSorted.isNotEmpty() || untrustedSorted.isNotEmpty()) {
|
if (installedSorted.isNotEmpty() || untrustedSorted.isNotEmpty()) {
|
||||||
val header = ExtensionGroupItem(context.getString(R.string.installed), installedSorted.size + untrustedSorted.size)
|
val header = ExtensionGroupItem(context.getString(R.string.installed), installedSorted.size + untrustedSorted.size, installedSorting = preferences.installedExtensionsOrder().get())
|
||||||
items += installedSorted.map { extension ->
|
items += installedSorted.map { extension ->
|
||||||
ExtensionItem(extension, header, currentDownloads[extension.pkgName])
|
ExtensionItem(extension, header, currentDownloads[extension.pkgName])
|
||||||
}
|
}
|
||||||
@ -237,8 +251,25 @@ class ExtensionBottomPresenter(
|
|||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun extensionInstallDate(pkgName: String): Long {
|
||||||
|
val context = bottomSheet.context
|
||||||
|
return try {
|
||||||
|
context.packageManager.getPackageInfo(pkgName, 0).firstInstallTime
|
||||||
|
} catch (e: java.lang.Exception) {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun extensionUpdateDate(pkgName: String): Long {
|
||||||
|
val context = bottomSheet.context
|
||||||
|
return try {
|
||||||
|
context.packageManager.getPackageInfo(pkgName, 0).lastUpdateTime
|
||||||
|
} catch (e: java.lang.Exception) {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getExtensionUpdateCount(): Int = preferences.extensionUpdatesCount().getOrDefault()
|
fun getExtensionUpdateCount(): Int = preferences.extensionUpdatesCount().getOrDefault()
|
||||||
fun getAutoCheckPref() = preferences.automaticExtUpdates()
|
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
private fun updateInstallStep(
|
private fun updateInstallStep(
|
||||||
|
@ -6,6 +6,7 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.TextView
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
@ -18,6 +19,7 @@ import eu.kanade.tachiyomi.data.preference.getOrDefault
|
|||||||
import eu.kanade.tachiyomi.databinding.ExtensionsBottomSheetBinding
|
import eu.kanade.tachiyomi.databinding.ExtensionsBottomSheetBinding
|
||||||
import eu.kanade.tachiyomi.databinding.RecyclerWithScrollerBinding
|
import eu.kanade.tachiyomi.databinding.RecyclerWithScrollerBinding
|
||||||
import eu.kanade.tachiyomi.extension.model.Extension
|
import eu.kanade.tachiyomi.extension.model.Extension
|
||||||
|
import eu.kanade.tachiyomi.extension.model.InstalledExtensionsOrder
|
||||||
import eu.kanade.tachiyomi.ui.extension.details.ExtensionDetailsController
|
import eu.kanade.tachiyomi.ui.extension.details.ExtensionDetailsController
|
||||||
import eu.kanade.tachiyomi.ui.migration.MangaAdapter
|
import eu.kanade.tachiyomi.ui.migration.MangaAdapter
|
||||||
import eu.kanade.tachiyomi.ui.migration.MangaItem
|
import eu.kanade.tachiyomi.ui.migration.MangaItem
|
||||||
@ -30,6 +32,7 @@ import eu.kanade.tachiyomi.util.view.collapse
|
|||||||
import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
|
import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
|
||||||
import eu.kanade.tachiyomi.util.view.expand
|
import eu.kanade.tachiyomi.util.view.expand
|
||||||
import eu.kanade.tachiyomi.util.view.isExpanded
|
import eu.kanade.tachiyomi.util.view.isExpanded
|
||||||
|
import eu.kanade.tachiyomi.util.view.popupMenu
|
||||||
import eu.kanade.tachiyomi.util.view.smoothScrollToTop
|
import eu.kanade.tachiyomi.util.view.smoothScrollToTop
|
||||||
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
||||||
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
||||||
@ -217,6 +220,18 @@ class ExtensionBottomSheet @JvmOverloads constructor(context: Context, attrs: At
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onExtSortClicked(view: TextView, position: Int) {
|
||||||
|
view.popupMenu(
|
||||||
|
InstalledExtensionsOrder.values().map { it.value to it.nameRes },
|
||||||
|
presenter.preferences.installedExtensionsOrder().get()
|
||||||
|
) {
|
||||||
|
presenter.preferences.installedExtensionsOrder().set(itemId)
|
||||||
|
extAdapter?.installedSortOrder = itemId
|
||||||
|
view.setText(InstalledExtensionsOrder.fromValue(itemId).nameRes)
|
||||||
|
presenter.refreshExtensions()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun updateAllExtensions(position: Int) {
|
fun updateAllExtensions(position: Int) {
|
||||||
val header = (extAdapter?.getSectionHeader(position)) as? ExtensionGroupItem ?: return
|
val header = (extAdapter?.getSectionHeader(position)) as? ExtensionGroupItem ?: return
|
||||||
val items = extAdapter?.getSectionItemPositions(header)
|
val items = extAdapter?.getSectionItemPositions(header)
|
||||||
|
@ -8,6 +8,7 @@ import androidx.recyclerview.widget.RecyclerView
|
|||||||
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.ExtensionCardHeaderBinding
|
import eu.kanade.tachiyomi.databinding.ExtensionCardHeaderBinding
|
||||||
|
import eu.kanade.tachiyomi.extension.model.InstalledExtensionsOrder
|
||||||
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
||||||
|
|
||||||
class ExtensionGroupHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>) :
|
class ExtensionGroupHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>) :
|
||||||
@ -19,6 +20,9 @@ class ExtensionGroupHolder(view: View, adapter: FlexibleAdapter<IFlexible<Recycl
|
|||||||
binding.extButton.setOnClickListener {
|
binding.extButton.setOnClickListener {
|
||||||
(adapter as? ExtensionAdapter)?.listener?.onUpdateAllClicked(bindingAdapterPosition)
|
(adapter as? ExtensionAdapter)?.listener?.onUpdateAllClicked(bindingAdapterPosition)
|
||||||
}
|
}
|
||||||
|
binding.extSort.setOnClickListener {
|
||||||
|
(adapter as? ExtensionAdapter)?.listener?.onExtSortClicked(binding.extSort, bindingAdapterPosition)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
@ -26,5 +30,9 @@ class ExtensionGroupHolder(view: View, adapter: FlexibleAdapter<IFlexible<Recycl
|
|||||||
binding.title.text = item.name
|
binding.title.text = item.name
|
||||||
binding.extButton.isVisible = item.canUpdate != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
binding.extButton.isVisible = item.canUpdate != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||||
binding.extButton.isEnabled = item.canUpdate == true
|
binding.extButton.isEnabled = item.canUpdate == true
|
||||||
|
binding.extSort.isVisible = item.installedSorting != null
|
||||||
|
binding.extSort.setText(InstalledExtensionsOrder.fromValue(item.installedSorting ?: 0).nameRes)
|
||||||
|
binding.extSort.post {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ import eu.kanade.tachiyomi.R
|
|||||||
* @param name The header name.
|
* @param name The header name.
|
||||||
* @param size The number of items in the group.
|
* @param size The number of items in the group.
|
||||||
*/
|
*/
|
||||||
data class ExtensionGroupItem(val name: String, val size: Int, var canUpdate: Boolean? = null) : AbstractHeaderItem<ExtensionGroupHolder>() {
|
data class ExtensionGroupItem(val name: String, val size: Int, var canUpdate: Boolean? = null, var installedSorting: Int? = null) : AbstractHeaderItem<ExtensionGroupHolder>() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the layout resource of this item.
|
* Returns the layout resource of this item.
|
||||||
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.extension
|
|||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.core.view.isGone
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import coil.clear
|
import coil.clear
|
||||||
import coil.load
|
import coil.load
|
||||||
@ -14,6 +15,8 @@ import eu.kanade.tachiyomi.util.system.LocaleHelper
|
|||||||
import eu.kanade.tachiyomi.data.image.coil.CoverViewTarget
|
import eu.kanade.tachiyomi.data.image.coil.CoverViewTarget
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.databinding.ExtensionCardItemBinding
|
import eu.kanade.tachiyomi.databinding.ExtensionCardItemBinding
|
||||||
|
import eu.kanade.tachiyomi.extension.model.InstalledExtensionsOrder
|
||||||
|
import eu.kanade.tachiyomi.util.system.timeSpanFromNow
|
||||||
import eu.kanade.tachiyomi.util.view.resetStrokeColor
|
import eu.kanade.tachiyomi.util.view.resetStrokeColor
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
@ -41,7 +44,34 @@ class ExtensionHolder(view: View, val adapter: ExtensionAdapter) :
|
|||||||
|
|
||||||
// Set source name
|
// Set source name
|
||||||
binding.extTitle.text = extension.name
|
binding.extTitle.text = extension.name
|
||||||
binding.version.text = extension.versionName
|
|
||||||
|
val infoText = mutableListOf(extension.versionName)
|
||||||
|
if (extension is Extension.Installed) {
|
||||||
|
when (InstalledExtensionsOrder.fromValue(adapter.installedSortOrder)) {
|
||||||
|
InstalledExtensionsOrder.RecentlyUpdated -> {
|
||||||
|
binding.date.isVisible = true
|
||||||
|
binding.date.text = itemView.context.getString(
|
||||||
|
R.string.updated_,
|
||||||
|
extensionUpdateDate(extension.pkgName).timeSpanFromNow
|
||||||
|
)
|
||||||
|
infoText.add("")
|
||||||
|
}
|
||||||
|
InstalledExtensionsOrder.RecentlyInstalled -> {
|
||||||
|
binding.date.isVisible = true
|
||||||
|
binding.date.text = itemView.context.getString(
|
||||||
|
R.string.installed_,
|
||||||
|
extensionInstallDate(extension.pkgName).timeSpanFromNow
|
||||||
|
)
|
||||||
|
infoText.add("")
|
||||||
|
}
|
||||||
|
else -> binding.date.isVisible = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
binding.date.isVisible = false
|
||||||
|
}
|
||||||
|
binding.lang.isVisible = binding.date.isGone
|
||||||
|
|
||||||
|
binding.version.text = infoText.joinToString(" • ")
|
||||||
binding.lang.text = LocaleHelper.getDisplayName(extension.lang)
|
binding.lang.text = LocaleHelper.getDisplayName(extension.lang)
|
||||||
binding.warning.text = when {
|
binding.warning.text = when {
|
||||||
extension is Extension.Untrusted -> itemView.context.getString(R.string.untrusted)
|
extension is Extension.Untrusted -> itemView.context.getString(R.string.untrusted)
|
||||||
@ -113,4 +143,22 @@ class ExtensionHolder(view: View, val adapter: ExtensionAdapter) :
|
|||||||
setText(R.string.install)
|
setText(R.string.install)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun extensionInstallDate(pkgName: String): Long {
|
||||||
|
val context = itemView.context
|
||||||
|
return try {
|
||||||
|
context.packageManager.getPackageInfo(pkgName, 0).firstInstallTime
|
||||||
|
} catch (e: java.lang.Exception) {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun extensionUpdateDate(pkgName: String): Long {
|
||||||
|
val context = itemView.context
|
||||||
|
return try {
|
||||||
|
context.packageManager.getPackageInfo(pkgName, 0).lastUpdateTime
|
||||||
|
} catch (e: java.lang.Exception) {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
android:textColor="@color/accent_text_btn_color_selector"
|
android:textColor="@color/accent_text_btn_color_selector"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible"
|
tools:visibility="gone"
|
||||||
app:layout_constraintBaseline_toBaselineOf="@id/title"
|
app:layout_constraintBaseline_toBaselineOf="@id/title"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/title"
|
app:layout_constraintBottom_toBottomOf="@id/title"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
@ -43,6 +43,34 @@
|
|||||||
app:rippleColor="@color/fullRippleColor"
|
app:rippleColor="@color/fullRippleColor"
|
||||||
android:text="@string/update_all" />
|
android:text="@string/update_all" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/ext_sort"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="12dp"
|
||||||
|
android:background="@drawable/square_ripple"
|
||||||
|
android:clickable="true"
|
||||||
|
android:drawablePadding="6dp"
|
||||||
|
app:drawableTint="?android:textColorPrimary"
|
||||||
|
android:ellipsize="start"
|
||||||
|
android:focusable="true"
|
||||||
|
android:gravity="center|end"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:padding="6dp"
|
||||||
|
android:textAlignment="textEnd"
|
||||||
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="normal"
|
||||||
|
app:layout_constraintBaseline_toBaselineOf="@id/title"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/title"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="1.0"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/title"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/title"
|
||||||
|
tools:text="Recently Updated"
|
||||||
|
app:drawableEndCompat="@drawable/ic_sort_24dp" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:textAppearance="@style/TextAppearance.Regular.SubHeading"
|
android:textAppearance="@style/TextAppearance.Regular.SubHeading"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
app:layout_constraintBottom_toTopOf="@id/lang"
|
app:layout_constraintBottom_toTopOf="@id/version"
|
||||||
app:layout_constraintEnd_toStartOf="@id/button_layout"
|
app:layout_constraintEnd_toStartOf="@id/button_layout"
|
||||||
app:layout_constraintStart_toEndOf="@id/source_image"
|
app:layout_constraintStart_toEndOf="@id/source_image"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
@ -63,8 +63,13 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintVertical_bias="0.0"
|
||||||
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/source_image"
|
app:layout_constraintStart_toEndOf="@id/source_image"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/version"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/ext_title"
|
app:layout_constraintTop_toBottomOf="@+id/ext_title"
|
||||||
tools:text="English"
|
tools:text="English"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
@ -74,13 +79,28 @@
|
|||||||
style="@style/TextAppearance.Regular.Body1.Secondary"
|
style="@style/TextAppearance.Regular.Body1.Secondary"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
|
android:ellipsize="middle"
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
app:layout_constraintBaseline_toBaselineOf="@id/lang"
|
app:layout_constraintTop_toBottomOf="@+id/ext_title"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/lang"
|
app:layout_constraintStart_toEndOf="@id/lang"
|
||||||
tools:text="Version" />
|
app:layout_constraintEnd_toStartOf="@id/date"
|
||||||
|
tools:text="Version • " />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/date"
|
||||||
|
style="@style/TextAppearance.Regular.Body1.Secondary"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:ellipsize="start"
|
||||||
|
app:layout_constrainedWidth="true"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/ext_title"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/version"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/warning"
|
||||||
|
tools:text="Updated 5 days ago" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/warning"
|
android:id="@+id/warning"
|
||||||
@ -91,8 +111,11 @@
|
|||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:textColor="?attr/colorError"
|
android:textColor="?attr/colorError"
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
app:layout_constraintStart_toEndOf="@id/version"
|
android:layout_marginEnd="6dp"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/button_layout"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/ext_title"
|
app:layout_constraintTop_toBottomOf="@+id/ext_title"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/date"
|
||||||
tools:text="Warning" />
|
tools:text="Warning" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
@ -312,6 +312,7 @@
|
|||||||
<string name="version_">Version: %1$s</string>
|
<string name="version_">Version: %1$s</string>
|
||||||
<string name="language_">Language: %1$s</string>
|
<string name="language_">Language: %1$s</string>
|
||||||
<string name="nsfw_short">18+</string>
|
<string name="nsfw_short">18+</string>
|
||||||
|
<string name="installed_">Installed %1$s</string>
|
||||||
<string name="unofficial">Unofficial</string>
|
<string name="unofficial">Unofficial</string>
|
||||||
<string name="extensions_miui_warning">MIUI Optimization must be disabled to install extensions.</string>
|
<string name="extensions_miui_warning">MIUI Optimization must be disabled to install extensions.</string>
|
||||||
<string name="may_contain_nsfw">May contain NSFW (18+) content</string>
|
<string name="may_contain_nsfw">May contain NSFW (18+) content</string>
|
||||||
@ -963,6 +964,9 @@
|
|||||||
<string name="move_to_top">Move to top</string>
|
<string name="move_to_top">Move to top</string>
|
||||||
<string name="move_to_">Move to %1$s</string>
|
<string name="move_to_">Move to %1$s</string>
|
||||||
<string name="moved_to_">Moved to %1$s</string>
|
<string name="moved_to_">Moved to %1$s</string>
|
||||||
|
<string name="name">Name</string>
|
||||||
|
<string name="recently_updated">Recently updated</string>
|
||||||
|
<string name="recently_installed">Recently installed</string>
|
||||||
<string name="never">Never</string>
|
<string name="never">Never</string>
|
||||||
<string name="newest">Newest</string>
|
<string name="newest">Newest</string>
|
||||||
<string name="next">Next</string>
|
<string name="next">Next</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user