Minor extension update cleanup, default to on

This commit is contained in:
arkon 2020-03-20 22:53:24 -04:00
parent 9585f9a1a6
commit 6da350aee6
19 changed files with 146 additions and 133 deletions

View file

@ -5,6 +5,7 @@ import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.data.updater.UpdaterJob import eu.kanade.tachiyomi.data.updater.UpdaterJob
import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
import java.io.File import java.io.File
object Migrations { object Migrations {
@ -27,6 +28,9 @@ object Migrations {
if (BuildConfig.INCLUDE_UPDATER && preferences.automaticUpdates()) { if (BuildConfig.INCLUDE_UPDATER && preferences.automaticUpdates()) {
UpdaterJob.setupTask(context) UpdaterJob.setupTask(context)
} }
if (preferences.automaticExtUpdates().getOrDefault()) {
ExtensionUpdateJob.setupTask(context)
}
return false return false
} }

View file

@ -26,7 +26,7 @@ class BackupCreatorJob(private val context: Context, workerParams: WorkerParamet
} }
companion object { companion object {
const val TAG = "BackupCreator" private const val TAG = "BackupCreator"
fun setupTask(context: Context, prefInterval: Int? = null) { fun setupTask(context: Context, prefInterval: Int? = null) {
val preferences = Injekt.get<PreferencesHelper>() val preferences = Injekt.get<PreferencesHelper>()

View file

@ -23,7 +23,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
} }
companion object { companion object {
const val TAG = "LibraryUpdate" private const val TAG = "LibraryUpdate"
fun setupTask(context: Context, prefInterval: Int? = null) { fun setupTask(context: Context, prefInterval: Int? = null) {
val preferences = Injekt.get<PreferencesHelper>() val preferences = Injekt.get<PreferencesHelper>()

View file

@ -410,11 +410,9 @@ class NotificationReceiver : BroadcastReceiver() {
internal fun markAsReadPendingBroadcast( internal fun markAsReadPendingBroadcast(
context: Context, context: Context,
manga: Manga, manga: Manga,
chapters: chapters: Array<Chapter>,
Array<Chapter>,
groupId: Int groupId: Int
): ): PendingIntent {
PendingIntent {
val newIntent = Intent(context, NotificationReceiver::class.java).apply { val newIntent = Intent(context, NotificationReceiver::class.java).apply {
action = ACTION_MARK_AS_READ action = ACTION_MARK_AS_READ
putExtra(EXTRA_CHAPTER_URL, chapters.map { it.url }.toTypedArray()) putExtra(EXTRA_CHAPTER_URL, chapters.map { it.url }.toTypedArray())
@ -442,14 +440,14 @@ class NotificationReceiver : BroadcastReceiver() {
* Returns [PendingIntent] that opens the extensions controller. * Returns [PendingIntent] that opens the extensions controller.
* *
* @param context context of application * @param context context of application
* @return [PendingIntent]
*/ */
internal fun openExtensionsPendingActivity(context: Context): PendingIntent { internal fun openExtensionsPendingActivity(context: Context): PendingIntent {
val newIntent = val intent = Intent(context, MainActivity::class.java).apply {
Intent(context, MainActivity::class.java).setAction(MainActivity.SHORTCUT_EXTENSIONS) action = MainActivity.SHORTCUT_EXTENSIONS
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
return PendingIntent.getActivity( }
context, 0, newIntent, PendingIntent.FLAG_UPDATE_CURRENT return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
)
} }
} }
} }

View file

@ -190,7 +190,7 @@ class PreferencesHelper(val context: Context) {
fun automaticUpdates() = prefs.getBoolean(Keys.automaticUpdates, true) fun automaticUpdates() = prefs.getBoolean(Keys.automaticUpdates, true)
fun automaticExtUpdates() = rxPrefs.getBoolean(Keys.automaticExtUpdates, false) fun automaticExtUpdates() = rxPrefs.getBoolean(Keys.automaticExtUpdates, true)
fun extensionUpdatesCount() = rxPrefs.getInteger("ext_updates_count", 0) fun extensionUpdatesCount() = rxPrefs.getInteger("ext_updates_count", 0)

View file

@ -55,7 +55,7 @@ class UpdaterJob(private val context: Context, workerParams: WorkerParameters) :
} }
companion object { companion object {
const val TAG = "UpdateChecker" private const val TAG = "UpdateChecker"
fun setupTask(context: Context) { fun setupTask(context: Context) {
val constraints = Constraints.Builder() val constraints = Constraints.Builder()

View file

@ -187,7 +187,7 @@ class ExtensionManager(
if (changed) { if (changed) {
installedExtensions = mutInstalledExtensions installedExtensions = mutInstalledExtensions
} }
preferences.extensionUpdatesCount().set(installedExtensions.count { it.hasUpdate }) updatePendingUpdatesCount()
} }
/** /**
@ -318,12 +318,12 @@ class ExtensionManager(
override fun onExtensionInstalled(extension: Extension.Installed) { override fun onExtensionInstalled(extension: Extension.Installed) {
registerNewExtension(extension.withUpdateCheck()) registerNewExtension(extension.withUpdateCheck())
preferences.extensionUpdatesCount().set(installedExtensions.count { it.hasUpdate }) updatePendingUpdatesCount()
} }
override fun onExtensionUpdated(extension: Extension.Installed) { override fun onExtensionUpdated(extension: Extension.Installed) {
registerUpdatedExtension(extension.withUpdateCheck()) registerUpdatedExtension(extension.withUpdateCheck())
preferences.extensionUpdatesCount().set(installedExtensions.count { it.hasUpdate }) updatePendingUpdatesCount()
} }
override fun onExtensionUntrusted(extension: Extension.Untrusted) { override fun onExtensionUntrusted(extension: Extension.Untrusted) {
@ -332,7 +332,7 @@ class ExtensionManager(
override fun onPackageUninstalled(pkgName: String) { override fun onPackageUninstalled(pkgName: String) {
unregisterExtension(pkgName) unregisterExtension(pkgName)
preferences.extensionUpdatesCount().set(installedExtensions.count { it.hasUpdate }) updatePendingUpdatesCount()
} }
} }
@ -346,4 +346,8 @@ class ExtensionManager(
} }
return this return this
} }
private fun updatePendingUpdatesCount() {
preferences.extensionUpdatesCount().set(installedExtensions.count { it.hasUpdate })
}
} }

View file

@ -31,36 +31,37 @@ class ExtensionUpdateJob(private val context: Context, workerParams: WorkerParam
} catch (e: Exception) { } catch (e: Exception) {
return@coroutineScope Result.failure() return@coroutineScope Result.failure()
} }
if (pendingUpdates.isNotEmpty()) { if (pendingUpdates.isNotEmpty()) {
val names = pendingUpdates.map { it.name } createUpdateNotification(pendingUpdates.map { it.name })
NotificationManagerCompat.from(context).apply {
notify(Notifications.ID_UPDATES_TO_EXTS,
context.notification(Notifications.CHANNEL_UPDATES_TO_EXTS) {
setContentTitle(
context.resources.getQuantityString(
R.plurals.update_check_notification_ext_updates,
names.size,
names.size
)
)
val extNames = names.joinToString(", ")
setContentText(extNames)
setStyle(NotificationCompat.BigTextStyle().bigText(extNames))
setSmallIcon(R.drawable.ic_extension_24dp)
setContentIntent(
NotificationReceiver.openExtensionsPendingActivity(
context
)
)
setAutoCancel(true)
})
}
} }
Result.success() Result.success()
} }
private fun createUpdateNotification(names: List<String>) {
NotificationManagerCompat.from(context).apply {
notify(Notifications.ID_UPDATES_TO_EXTS,
context.notification(Notifications.CHANNEL_UPDATES_TO_EXTS) {
setContentTitle(
context.resources.getQuantityString(
R.plurals.update_check_notification_ext_updates,
names.size,
names.size
)
)
val extNames = names.joinToString(", ")
setContentText(extNames)
setStyle(NotificationCompat.BigTextStyle().bigText(extNames))
setSmallIcon(R.drawable.ic_extension_24dp)
setContentIntent(NotificationReceiver.openExtensionsPendingActivity(context))
setAutoCancel(true)
})
}
}
companion object { companion object {
const val TAG = "ExtensionUpdate" private const val TAG = "ExtensionUpdate"
fun setupTask(context: Context, forceAutoUpdateJob: Boolean? = null) { fun setupTask(context: Context, forceAutoUpdateJob: Boolean? = null) {
val preferences = Injekt.get<PreferencesHelper>() val preferences = Injekt.get<PreferencesHelper>()

View file

@ -7,12 +7,14 @@ import com.github.salomonbrys.kotson.int
import com.github.salomonbrys.kotson.string import com.github.salomonbrys.kotson.string
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.JsonArray import com.google.gson.JsonArray
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.extension.model.Extension import eu.kanade.tachiyomi.extension.model.Extension
import eu.kanade.tachiyomi.extension.model.LoadResult import eu.kanade.tachiyomi.extension.model.LoadResult
import eu.kanade.tachiyomi.extension.util.ExtensionLoader import eu.kanade.tachiyomi.extension.util.ExtensionLoader
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.await
import java.util.Date
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import okhttp3.Response import okhttp3.Response
@ -21,6 +23,7 @@ import uy.kohesive.injekt.injectLazy
internal class ExtensionGithubApi { internal class ExtensionGithubApi {
private val network: NetworkHelper by injectLazy() private val network: NetworkHelper by injectLazy()
private val preferences: PreferencesHelper by injectLazy()
private val gson: Gson by injectLazy() private val gson: Gson by injectLazy()
@ -33,23 +36,29 @@ internal class ExtensionGithubApi {
} }
suspend fun checkForUpdates(context: Context): List<Extension.Installed> { suspend fun checkForUpdates(context: Context): List<Extension.Installed> {
val call = GET(EXT_URL)
return withContext(Dispatchers.IO) { return withContext(Dispatchers.IO) {
val call = GET(EXT_URL)
val response = network.client.newCall(call).await() val response = network.client.newCall(call).await()
preferences.lastExtCheck().set(Date().time)
if (response.isSuccessful) { if (response.isSuccessful) {
val extensions = parseResponse(response) val extensions = parseResponse(response)
val extensionsWithUpdate = mutableListOf<Extension.Installed>()
val installedExtensions = ExtensionLoader.loadExtensions(context) val installedExtensions = ExtensionLoader.loadExtensions(context)
.filterIsInstance<LoadResult.Success>() .filterIsInstance<LoadResult.Success>()
.map { it.extension } .map { it.extension }
val extensionsWithUpdate = mutableListOf<Extension.Installed>()
for (installedExt in installedExtensions) { for (installedExt in installedExtensions) {
val pkgName = installedExt.pkgName val pkgName = installedExt.pkgName
val availableExt = extensions.find { it.pkgName == pkgName } ?: continue val availableExt = extensions.find { it.pkgName == pkgName } ?: continue
val hasUpdate = availableExt.versionCode > installedExt.versionCode val hasUpdate = availableExt.versionCode > installedExt.versionCode
if (hasUpdate) extensionsWithUpdate.add(installedExt) if (hasUpdate) {
extensionsWithUpdate.add(installedExt)
}
} }
extensionsWithUpdate extensionsWithUpdate

View file

@ -36,6 +36,8 @@ open class ExtensionController : NucleusController<ExtensionPresenter>(),
FlexibleAdapter.OnItemLongClickListener, FlexibleAdapter.OnItemLongClickListener,
ExtensionTrustDialog.Listener { ExtensionTrustDialog.Listener {
private val preferences: PreferencesHelper = Injekt.get()
/** /**
* Adapter containing the list of manga from the catalogue. * Adapter containing the list of manga from the catalogue.
*/ */
@ -92,7 +94,6 @@ open class ExtensionController : NucleusController<ExtensionPresenter>(),
} }
R.id.action_auto_check -> { R.id.action_auto_check -> {
item.isChecked = !item.isChecked item.isChecked = !item.isChecked
val preferences: PreferencesHelper = Injekt.get()
preferences.automaticExtUpdates().set(item.isChecked) preferences.automaticExtUpdates().set(item.isChecked)
ExtensionUpdateJob.setupTask(activity!!, item.isChecked) ExtensionUpdateJob.setupTask(activity!!, item.isChecked)
} }
@ -150,9 +151,7 @@ open class ExtensionController : NucleusController<ExtensionPresenter>(),
// Fixes problem with the overflow icon showing up in lieu of search // Fixes problem with the overflow icon showing up in lieu of search
searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() }) searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() })
val autoItem = menu.findItem(R.id.action_auto_check) menu.findItem(R.id.action_auto_check).isChecked = preferences.automaticExtUpdates().getOrDefault()
val preferences: PreferencesHelper = Injekt.get()
autoItem.isChecked = preferences.automaticExtUpdates().getOrDefault()
} }
override fun onItemClick(view: View, position: Int): Boolean { override fun onItemClick(view: View, position: Int): Boolean {

View file

@ -13,7 +13,6 @@ import com.bluelinelabs.conductor.RouterTransaction
import eu.kanade.tachiyomi.Migrations import eu.kanade.tachiyomi.Migrations
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.notification.NotificationReceiver import eu.kanade.tachiyomi.data.notification.NotificationReceiver
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.extension.api.ExtensionGithubApi import eu.kanade.tachiyomi.extension.api.ExtensionGithubApi
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
@ -39,7 +38,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import uy.kohesive.injekt.injectLazy
class MainActivity : BaseActivity() { class MainActivity : BaseActivity() {
@ -152,33 +150,33 @@ class MainActivity : BaseActivity() {
} }
} }
private fun setExtensionsBadge() {
val updates = preferences.extensionUpdatesCount().getOrDefault()
if (updates > 0) {
val badge = bottom_nav.getOrCreateBadge(R.id.nav_more)
badge.number = updates
} else {
bottom_nav.removeBadge(R.id.nav_more)
}
}
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
getExtensionUpdates() getExtensionUpdates()
} }
private fun setExtensionsBadge() {
val updates = preferences.extensionUpdatesCount().getOrDefault()
if (updates > 0) {
bottom_nav.getOrCreateBadge(R.id.nav_more).number = updates
} else {
bottom_nav.removeBadge(R.id.nav_more)
}
}
private fun getExtensionUpdates() { private fun getExtensionUpdates() {
if (Date().time >= preferences.lastExtCheck().getOrDefault() + // Limit checks to once every 2 hours at most
TimeUnit.HOURS.toMillis(2)) { val now = Date().time
GlobalScope.launch(Dispatchers.IO) { if (now < preferences.lastExtCheck().getOrDefault() + TimeUnit.HOURS.toMillis(2)) {
val preferences: PreferencesHelper by injectLazy() return
try { }
val pendingUpdates = ExtensionGithubApi().checkForUpdates(this@MainActivity)
preferences.extensionUpdatesCount().set(pendingUpdates.size) GlobalScope.launch(Dispatchers.IO) {
preferences.lastExtCheck().set(Date().time) try {
} catch (e: java.lang.Exception) { val pendingUpdates = ExtensionGithubApi().checkForUpdates(this@MainActivity)
Timber.e(e) preferences.extensionUpdatesCount().set(pendingUpdates.size)
} } catch (e: Exception) {
Timber.e(e)
} }
} }
} }

View file

@ -2,6 +2,8 @@ package eu.kanade.tachiyomi.ui.more
import androidx.preference.PreferenceScreen import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.ui.base.controller.RootController import eu.kanade.tachiyomi.ui.base.controller.RootController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.download.DownloadController import eu.kanade.tachiyomi.ui.download.DownloadController
@ -9,7 +11,7 @@ import eu.kanade.tachiyomi.ui.extension.ExtensionController
import eu.kanade.tachiyomi.ui.migration.MigrationController import eu.kanade.tachiyomi.ui.migration.MigrationController
import eu.kanade.tachiyomi.ui.setting.SettingsController import eu.kanade.tachiyomi.ui.setting.SettingsController
import eu.kanade.tachiyomi.ui.setting.SettingsMainController import eu.kanade.tachiyomi.ui.setting.SettingsMainController
import eu.kanade.tachiyomi.util.preference.extensionPreference import eu.kanade.tachiyomi.util.preference.badgePreference
import eu.kanade.tachiyomi.util.preference.iconRes import eu.kanade.tachiyomi.util.preference.iconRes
import eu.kanade.tachiyomi.util.preference.iconTint import eu.kanade.tachiyomi.util.preference.iconTint
import eu.kanade.tachiyomi.util.preference.onClick import eu.kanade.tachiyomi.util.preference.onClick
@ -18,6 +20,8 @@ import eu.kanade.tachiyomi.util.preference.preferenceCategory
import eu.kanade.tachiyomi.util.preference.titleRes import eu.kanade.tachiyomi.util.preference.titleRes
import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.openInBrowser import eu.kanade.tachiyomi.util.system.openInBrowser
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class MoreController : SettingsController(), RootController { class MoreController : SettingsController(), RootController {
@ -26,10 +30,11 @@ class MoreController : SettingsController(), RootController {
val tintColor = context.getResourceColor(R.attr.colorAccent) val tintColor = context.getResourceColor(R.attr.colorAccent)
extensionPreference { badgePreference {
titleRes = R.string.label_extensions titleRes = R.string.label_extensions
iconRes = R.drawable.ic_extension_24dp iconRes = R.drawable.ic_extension_24dp
iconTint = tintColor iconTint = tintColor
setBadge(Injekt.get<PreferencesHelper>().extensionUpdatesCount().getOrDefault())
onClick { onClick {
router.pushController(ExtensionController().withFadeTransaction()) router.pushController(ExtensionController().withFadeTransaction())
} }

View file

@ -13,7 +13,7 @@ import androidx.preference.PreferenceManager
import androidx.preference.PreferenceScreen import androidx.preference.PreferenceScreen
import androidx.preference.SwitchPreferenceCompat import androidx.preference.SwitchPreferenceCompat
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
import eu.kanade.tachiyomi.widget.preference.ExtensionPreference import eu.kanade.tachiyomi.widget.preference.BadgePreference
import eu.kanade.tachiyomi.widget.preference.IntListPreference import eu.kanade.tachiyomi.widget.preference.IntListPreference
import eu.kanade.tachiyomi.widget.preference.SwitchPreferenceCategory import eu.kanade.tachiyomi.widget.preference.SwitchPreferenceCategory
@ -57,8 +57,8 @@ inline fun PreferenceGroup.multiSelectListPreference(block: (@DSL MultiSelectLis
return initThenAdd(MultiSelectListPreference(context), block).also(::initDialog) return initThenAdd(MultiSelectListPreference(context), block).also(::initDialog)
} }
inline fun PreferenceGroup.extensionPreference(block: (@DSL Preference).() -> Unit): ExtensionPreference { inline fun PreferenceGroup.badgePreference(block: (@DSL BadgePreference).() -> Unit): BadgePreference {
return initThenAdd(ExtensionPreference(context), block) return initThenAdd(BadgePreference(context), block)
} }
inline fun PreferenceScreen.preferenceCategory(block: (@DSL PreferenceCategory).() -> Unit): PreferenceCategory { inline fun PreferenceScreen.preferenceCategory(block: (@DSL PreferenceCategory).() -> Unit): PreferenceCategory {

View file

@ -0,0 +1,37 @@
package eu.kanade.tachiyomi.widget.preference
import android.content.Context
import android.util.AttributeSet
import androidx.preference.Preference
import androidx.preference.PreferenceViewHolder
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.visible
import kotlinx.android.synthetic.main.pref_badge.view.badge
class BadgePreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
Preference(context, attrs) {
private var badgeNumber: Int = 0
init {
widgetLayoutResource = R.layout.pref_badge
}
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
if (badgeNumber > 0) {
holder.itemView.badge.text = badgeNumber.toString()
holder.itemView.badge.visible()
} else {
holder.itemView.badge.text = null
holder.itemView.badge.gone()
}
}
fun setBadge(number: Int) {
this.badgeNumber = number
notifyChanged()
}
}

View file

@ -1,37 +0,0 @@
package eu.kanade.tachiyomi.widget.preference
import android.content.Context
import android.util.AttributeSet
import androidx.preference.Preference
import androidx.preference.PreferenceViewHolder
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.visible
import kotlinx.android.synthetic.main.preference_update_text.view.*
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class ExtensionPreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
Preference(context, attrs) {
init {
widgetLayoutResource = R.layout.preference_update_text
}
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
val extUpdateText = holder.itemView.textView
val updates = Injekt.get<PreferencesHelper>().extensionUpdatesCount().getOrDefault()
if (updates > 0) {
extUpdateText.text = updates.toString()
extUpdateText.visible()
} else {
extUpdateText.text = null
extUpdateText.gone()
}
}
}

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" <shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"> android:shape="rectangle">
<corners android:radius="13dp"/> <corners android:radius="13dp" />
<size <size
android:height="25dp" android:width="25dp"
android:width="25dp" /> android:height="25dp" />
<solid android:color="@color/material_red_900"/> <solid android:color="?attr/colorError" />
</shape> </shape>

View file

@ -1,17 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android" <TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/textView" android:id="@+id/badge"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center"
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
android:background="@drawable/round_textview_background" android:background="@drawable/round_textview_background"
android:textColor="#FFFFFF" android:gravity="center"
android:layout_marginTop="12dp" android:padding="3dp"
android:layout_marginBottom="12dp" android:textAppearance="@style/TextAppearance.MaterialComponents.Badge"
android:textStyle="bold" android:textStyle="bold"
tools:text="3" tools:text="3" />
android:layout_marginStart="12dp"
android:paddingStart="3dp"
android:paddingEnd="3dp"/>

View file

@ -18,8 +18,8 @@
<item <item
android:id="@+id/action_auto_check" android:id="@+id/action_auto_check"
android:title="@string/action_auto_check_extensions"
android:checkable="true" android:checkable="true"
app:showAsAction="never"/> android:title="@string/pref_enable_automatic_extension_updates"
app:showAsAction="never" />
</menu> </menu>

View file

@ -211,7 +211,7 @@
<string name="ext_version_info">Version: %1$s</string> <string name="ext_version_info">Version: %1$s</string>
<string name="ext_language_info">Language: %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> <string name="ext_empty_preferences">No preferences to edit for this extension</string>
<string name="action_auto_check_extensions">Auto-check for updates</string> <string name="pref_enable_automatic_extension_updates">Check for extension updates</string>
<!-- Reader section --> <!-- Reader section -->
<string name="pref_fullscreen">Fullscreen</string> <string name="pref_fullscreen">Fullscreen</string>
@ -601,6 +601,6 @@
<string name="channel_library">Library</string> <string name="channel_library">Library</string>
<string name="channel_downloader">Downloader</string> <string name="channel_downloader">Downloader</string>
<string name="channel_new_chapters">Chapter updates</string> <string name="channel_new_chapters">Chapter updates</string>
<string name="channel_ext_updates">Extension Updates</string> <string name="channel_ext_updates">Extension updates</string>
</resources> </resources>