mirror of
https://github.com/aniyomiorg/aniyomi.git
synced 2024-11-28 09:15:12 +03:00
Indicate obsolete extensions (#2494)
* Indicate obsolete extensions * Make obsolete indicators red * Move obsolete extensions up the list * Add base button theme for holder * Use red button color state instead of explicit text color
This commit is contained in:
parent
6b5742c1ff
commit
f3e228e8a4
8 changed files with 87 additions and 15 deletions
|
@ -71,7 +71,7 @@ class ExtensionManager(
|
|||
private set(value) {
|
||||
field = value
|
||||
availableExtensionsRelay.call(value)
|
||||
setUpdateFieldOfInstalledExtensions(value)
|
||||
updatedInstalledExtensionsStatuses(value)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -158,18 +158,25 @@ class ExtensionManager(
|
|||
*
|
||||
* @param availableExtensions The list of extensions given by the [api].
|
||||
*/
|
||||
private fun setUpdateFieldOfInstalledExtensions(availableExtensions: List<Extension.Available>) {
|
||||
private fun updatedInstalledExtensionsStatuses(availableExtensions: List<Extension.Available>) {
|
||||
val mutInstalledExtensions = installedExtensions.toMutableList()
|
||||
var changed = false
|
||||
|
||||
for ((index, installedExt) in mutInstalledExtensions.withIndex()) {
|
||||
val pkgName = installedExt.pkgName
|
||||
val availableExt = availableExtensions.find { it.pkgName == pkgName } ?: continue
|
||||
val availableExt = availableExtensions.find { it.pkgName == pkgName }
|
||||
|
||||
val hasUpdate = availableExt.versionCode > installedExt.versionCode
|
||||
if (installedExt.hasUpdate != hasUpdate) {
|
||||
mutInstalledExtensions[index] = installedExt.copy(hasUpdate = hasUpdate)
|
||||
changed = true
|
||||
if (availableExt == null) {
|
||||
if (!installedExt.isObsolete) {
|
||||
mutInstalledExtensions[index] = installedExt.copy(isObsolete = true)
|
||||
changed = true
|
||||
}
|
||||
} else {
|
||||
val hasUpdate = availableExt.versionCode > installedExt.versionCode
|
||||
if (installedExt.hasUpdate != hasUpdate) {
|
||||
mutInstalledExtensions[index] = installedExt.copy(hasUpdate = hasUpdate)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
|
|
|
@ -16,7 +16,8 @@ sealed class Extension {
|
|||
override val versionCode: Int,
|
||||
val sources: List<Source>,
|
||||
override val lang: String,
|
||||
val hasUpdate: Boolean = false) : Extension()
|
||||
val hasUpdate: Boolean = false,
|
||||
val isObsolete: Boolean = false) : Extension()
|
||||
|
||||
data class Available(override val name: String,
|
||||
override val pkgName: String,
|
||||
|
|
|
@ -69,6 +69,10 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
|
|||
presenter.uninstallExtension()
|
||||
}
|
||||
|
||||
if (extension.isObsolete) {
|
||||
extension_obsolete.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
val themedContext by lazy { getPreferenceThemeContext() }
|
||||
val manager = PreferenceManager(themedContext)
|
||||
manager.preferenceDataStore = EmptyPreferenceDataStore()
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package eu.kanade.tachiyomi.ui.extension
|
||||
|
||||
import android.view.View
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.glide.GlideApp
|
||||
import eu.kanade.tachiyomi.extension.model.Extension
|
||||
|
@ -52,11 +54,15 @@ class ExtensionHolder(view: View, override val adapter: ExtensionAdapter) :
|
|||
bindButton(item)
|
||||
}
|
||||
|
||||
@Suppress("ResourceType")
|
||||
fun bindButton(item: ExtensionItem) = with(ext_button) {
|
||||
isEnabled = true
|
||||
isClickable = true
|
||||
isActivated = false
|
||||
|
||||
background = VectorDrawableCompat.create(resources!!, R.drawable.button_bg_transparent, null)
|
||||
setTextColor(ContextCompat.getColorStateList(context, R.drawable.button_bg_transparent))
|
||||
|
||||
val extension = item.extension
|
||||
|
||||
val installStep = item.installStep
|
||||
|
@ -73,11 +79,21 @@ class ExtensionHolder(view: View, override val adapter: ExtensionAdapter) :
|
|||
isClickable = false
|
||||
}
|
||||
} else if (extension is Extension.Installed) {
|
||||
if (extension.hasUpdate) {
|
||||
isActivated = true
|
||||
setText(R.string.ext_update)
|
||||
} else {
|
||||
setText(R.string.ext_details)
|
||||
when {
|
||||
extension.hasUpdate -> {
|
||||
isActivated = true
|
||||
setText(R.string.ext_update)
|
||||
}
|
||||
extension.isObsolete -> {
|
||||
// Red outline
|
||||
background = VectorDrawableCompat.create(resources, R.drawable.button_bg_error, null)
|
||||
setTextColor(ContextCompat.getColorStateList(context, R.drawable.button_bg_error))
|
||||
|
||||
setText(R.string.ext_obsolete)
|
||||
}
|
||||
else -> {
|
||||
setText(R.string.ext_details)
|
||||
}
|
||||
}
|
||||
} else if (extension is Extension.Untrusted) {
|
||||
setText(R.string.ext_trust)
|
||||
|
|
|
@ -62,7 +62,7 @@ open class ExtensionPresenter(
|
|||
|
||||
val items = mutableListOf<ExtensionItem>()
|
||||
|
||||
val installedSorted = installed.sortedWith(compareBy({ !it.hasUpdate }, { it.pkgName }))
|
||||
val installedSorted = installed.sortedWith(compareBy({ !it.hasUpdate }, { !it.isObsolete }, { it.pkgName }))
|
||||
val untrustedSorted = untrusted.sortedBy { it.pkgName }
|
||||
val availableSorted = available
|
||||
// Filter out already installed extensions and disabled languages
|
||||
|
|
26
app/src/main/res/drawable/button_bg_error.xml
Normal file
26
app/src/main/res/drawable/button_bg_error.xml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_activated="true" android:color="@color/md_white_1000">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:radius="2dp" />
|
||||
<solid android:color="@color/red_error" />
|
||||
<padding android:left="8dp" android:right="8dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item android:state_enabled="false" android:color="@color/textColorHintLight">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:radius="2dp" />
|
||||
<solid android:color="@android:color/transparent" />
|
||||
<stroke android:width="1dp" android:color="@color/textColorHintLight" />
|
||||
<padding android:left="8dp" android:right="8dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item android:color="@color/red_error">
|
||||
<shape android:color="@color/red_error" android:shape="rectangle">
|
||||
<corners android:radius="2dp" />
|
||||
<solid android:color="@android:color/transparent" />
|
||||
<stroke android:width="1dp" android:color="@color/red_error" />
|
||||
<padding android:left="8dp" android:right="8dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
|
@ -60,6 +60,22 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:text="eu.kanade.tachiyomi.extension.en.myext"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/extension_obsolete"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="@color/red_error"
|
||||
android:gravity="center"
|
||||
android:padding="16dp"
|
||||
android:text="@string/obsolete_extension_message"
|
||||
android:textColor="@android:color/white"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/extension_pkg" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/extension_uninstall_button"
|
||||
android:layout_width="0dp"
|
||||
|
@ -71,7 +87,7 @@
|
|||
style="@style/Theme.Widget.Button.Colored"
|
||||
app:layout_constraintStart_toStartOf="@id/guideline"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/extension_pkg" />
|
||||
app:layout_constraintTop_toBottomOf="@id/extension_obsolete" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/extension_prefs_recycler"
|
||||
|
|
|
@ -161,6 +161,7 @@
|
|||
<string name="all_lang">All</string>
|
||||
<string name="ext_details">Details</string>
|
||||
<string name="ext_update">Update</string>
|
||||
<string name="ext_obsolete">Obsolete</string>
|
||||
<string name="ext_install">Install</string>
|
||||
<string name="ext_pending">Pending</string>
|
||||
<string name="ext_downloading">Downloading</string>
|
||||
|
@ -173,6 +174,7 @@
|
|||
<string name="ext_available">Available</string>
|
||||
<string name="untrusted_extension">Untrusted extension</string>
|
||||
<string name="untrusted_extension_message">This extension was signed with an untrusted certificate and wasn\'t activated.\n\nA malicious extension could read any login credentials stored in Tachiyomi or execute arbitrary code.\n\nBy trusting this certificate you accept these risks.</string>
|
||||
<string name="obsolete_extension_message">This extension is no longer available.</string>
|
||||
<string name="ext_version_info">Version: %1$s</string>
|
||||
<string name="ext_language_info">Language: %1$s</string>
|
||||
<string name="ext_empty_preferences">No preferences to edit for this extension</string>
|
||||
|
|
Loading…
Reference in a new issue