diff --git a/app/src/main/java/eu/kanade/tachiyomi/App.kt b/app/src/main/java/eu/kanade/tachiyomi/App.kt index 3a1373558a..435780ffff 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/App.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/App.kt @@ -15,6 +15,7 @@ import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.updater.UpdaterJob +import eu.kanade.tachiyomi.extension.ExtensionUpdateJob import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.util.LocaleHelper import org.acra.ACRA @@ -79,6 +80,7 @@ open class App : Application(), LifecycleObserver { LibraryUpdateJob.TAG -> LibraryUpdateJob() UpdaterJob.TAG -> UpdaterJob() BackupCreatorJob.TAG -> BackupCreatorJob() + ExtensionUpdateJob.TAG -> ExtensionUpdateJob() else -> null } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreatorJob.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreatorJob.kt index a1f5aca922..f18340ac52 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreatorJob.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreatorJob.kt @@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get +import java.util.concurrent.TimeUnit class BackupCreatorJob : Job() { @@ -25,10 +26,11 @@ class BackupCreatorJob : Job() { fun setupTask(prefInterval: Int? = null) { val preferences = Injekt.get() - val interval = prefInterval ?: preferences.backupInterval().getOrDefault() + val interval = (prefInterval ?: preferences.backupInterval().getOrDefault()).toLong() if (interval > 0) { JobRequest.Builder(TAG) - .setPeriodic(interval * 60 * 60 * 1000L, 10 * 60 * 1000) + .setPeriodic(TimeUnit.HOURS.toMillis(interval), TimeUnit.MINUTES.toMillis + (10)) .setUpdateCurrent(true) .build() .schedule() diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt index 2fb2e5d83a..3cad6a2206 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt @@ -7,6 +7,7 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get +import java.util.concurrent.TimeUnit class LibraryUpdateJob : Job() { @@ -20,7 +21,8 @@ class LibraryUpdateJob : Job() { fun setupTask(prefInterval: Int? = null) { val preferences = Injekt.get() - val interval = prefInterval ?: preferences.libraryUpdateInterval().getOrDefault() + val interval = (prefInterval ?: preferences.libraryUpdateInterval().getOrDefault()) + .toLong() if (interval > 0) { val restrictions = preferences.libraryUpdateRestriction()!! val acRestriction = "ac" in restrictions @@ -30,7 +32,9 @@ class LibraryUpdateJob : Job() { JobRequest.NetworkType.CONNECTED JobRequest.Builder(TAG) - .setPeriodic(interval * 60 * 60 * 1000L, 10 * 60 * 1000) + .setPeriodic( + TimeUnit.HOURS.toMillis(interval), TimeUnit.MINUTES.toMillis + (10)) .setRequiredNetworkType(wifiRestriction) .setRequiresCharging(acRestriction) .setRequirementsEnforced(true) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt index 84e49f19b1..b067006710 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt @@ -395,6 +395,21 @@ class NotificationReceiver : BroadcastReceiver() { ) } + /** + * Returns [PendingIntent] that opens the extensions controller, + * + * @param context context of application + * @param manga manga of chapter + */ + internal fun openExtensionsPendingActivity(context: Context): PendingIntent { + val newIntent = + Intent(context, MainActivity::class.java).setAction(MainActivity.SHORTCUT_EXTENSIONS) + .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + return PendingIntent.getActivity( + context, 0, newIntent, PendingIntent.FLAG_UPDATE_CURRENT + ) + } + /** * Returns [PendingIntent] that marks a chapter as read and deletes it if preferred * diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt index b99c44cadd..03555be83b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt @@ -38,6 +38,11 @@ object Notifications { const val CHANNEL_NEW_CHAPTERS = "new_chapters_channel" const val ID_NEW_CHAPTERS = -301 const val GROUP_NEW_CHAPTERS = "eu.kanade.tachiyomi.NEW_CHAPTERS" + /** + * Notification channel and ids used by the library updater. + */ + const val CHANNEL_UPDATES_TO_EXTS = "updates_ext_channel" + const val ID_UPDATES_TO_EXTS = -401 /** * Creates the notification channels introduced in Android Oreo. @@ -48,18 +53,31 @@ object Notifications { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return val channels = listOf( - NotificationChannel(CHANNEL_COMMON, context.getString(R.string.channel_common), - NotificationManager.IMPORTANCE_LOW), - NotificationChannel(CHANNEL_LIBRARY, context.getString(R.string.channel_library_updates), - NotificationManager.IMPORTANCE_LOW).apply { - setShowBadge(false) - }, - NotificationChannel(CHANNEL_DOWNLOADER, context.getString(R.string.channel_downloader), - NotificationManager.IMPORTANCE_LOW).apply { - setShowBadge(false) - }, - NotificationChannel(CHANNEL_NEW_CHAPTERS, context.getString(R.string.channel_new_chapters), - NotificationManager.IMPORTANCE_DEFAULT) + NotificationChannel( + CHANNEL_COMMON, + context.getString(R.string.channel_common), + NotificationManager.IMPORTANCE_LOW + ), NotificationChannel( + CHANNEL_LIBRARY, + context.getString(R.string.channel_library_updates), + NotificationManager.IMPORTANCE_LOW + ).apply { + setShowBadge(false) + }, NotificationChannel( + CHANNEL_DOWNLOADER, + context.getString(R.string.channel_downloader), + NotificationManager.IMPORTANCE_LOW + ).apply { + setShowBadge(false) + }, NotificationChannel( + CHANNEL_UPDATES_TO_EXTS, + context.getString(R.string.channel_ext_updates), + NotificationManager.IMPORTANCE_DEFAULT + ), NotificationChannel( + CHANNEL_NEW_CHAPTERS, + context.getString(R.string.channel_new_chapters), + NotificationManager.IMPORTANCE_DEFAULT + ) ) context.notificationManager.createNotificationChannels(channels) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index 4668ac1972..63ffd7898e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -101,6 +101,8 @@ object PreferenceKeys { const val automaticUpdates = "automatic_updates" + const val automaticExtUpdates = "automatic_ext_updates" + const val startScreen = "start_screen" const val downloadNew = "download_new" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index fe1269c6f9..63e99e6377 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -164,6 +164,8 @@ class PreferencesHelper(val context: Context) { fun automaticUpdates() = prefs.getBoolean(Keys.automaticUpdates, false) + fun automaticExtUpdates() = rxPrefs.getBoolean(Keys.automaticExtUpdates, false) + fun hiddenCatalogues() = rxPrefs.getStringSet("hidden_catalogues", mutableSetOf()) fun downloadNew() = rxPrefs.getBoolean(Keys.downloadNew, false) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdaterJob.kt b/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdaterJob.kt index deda43a7a9..40ae3ebe9f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdaterJob.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdaterJob.kt @@ -9,8 +9,8 @@ import com.evernote.android.job.JobManager import com.evernote.android.job.JobRequest import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.notification.Notifications -import eu.kanade.tachiyomi.util.getResourceColor import eu.kanade.tachiyomi.util.notificationManager +import java.util.concurrent.TimeUnit class UpdaterJob : Job() { @@ -54,7 +54,7 @@ class UpdaterJob : Job() { fun setupTask() { JobRequest.Builder(TAG) - .setPeriodic(24 * 60 * 60 * 1000, 60 * 60 * 1000) + .setPeriodic(TimeUnit.DAYS.toMillis(1), TimeUnit.HOURS.toMillis(1)) .setRequiredNetworkType(JobRequest.NetworkType.CONNECTED) .setRequirementsEnforced(true) .setUpdateCurrent(true) diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionUpdateJob.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionUpdateJob.kt new file mode 100644 index 0000000000..9f506fea53 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionUpdateJob.kt @@ -0,0 +1,164 @@ +package eu.kanade.tachiyomi.extension + + +import androidx.core.app.NotificationManagerCompat +import androidx.core.content.ContextCompat +import com.evernote.android.job.Job +import com.evernote.android.job.JobManager +import com.evernote.android.job.JobRequest +import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.notification.NotificationReceiver +import eu.kanade.tachiyomi.data.notification.Notifications +import eu.kanade.tachiyomi.util.notification +import rx.Observable +import rx.schedulers.Schedulers +import timber.log.Timber +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get +import java.util.concurrent.TimeUnit + +class ExtensionUpdateJob : Job() { + + override fun onRunJob(params: Params): Result { + val extensionManager: ExtensionManager = Injekt.get() + extensionManager.findAvailableExtensions() + /*return extensionManager.getInstalledExtensionsObservable() + .map { list -> + val pendingUpdates = list.filter { it.hasUpdate } + if (pendingUpdates.isNotEmpty()) { + val names = pendingUpdates.map { it.name } + + NotificationManagerCompat.from(context).apply { + notify(Notifications.ID_UPDATES_TO_EXTS, + context.notification(Notifications.CHANNEL_UPDATES_TO_EXTS) { + setContentTitle( + context.getString( + R.string.update_check_notification_ext_updates, names.size + ) + ) + val extNames = if (names.size > 5) { + "${names.take(4).joinToString(", ")}, " + context.getString( + R.string.notification_and_n_more, (names.size - 4) + ) + } else names.joinToString(", ") + setContentText(extNames) + setSmallIcon(R.drawable.ic_extension_update) + color = ContextCompat.getColor(context, R.color.colorAccentLight) + setContentIntent( + NotificationReceiver.openExtensionsPendingActivity( + context + ) + ) + setAutoCancel(true) + }) + } + } + Result.SUCCESS + } + .onErrorReturn { Result.FAILURE } + // Sadly, the task needs to be synchronous. + .toBlocking() + .single()*/ + Observable.defer { + extensionManager.getInstalledExtensionsObservable().map { list -> + val pendingUpdates = list.filter { it.hasUpdate } + if (pendingUpdates.isNotEmpty()) { + val names = pendingUpdates.map { it.name } + NotificationManagerCompat.from(context).apply { + notify(Notifications.ID_UPDATES_TO_EXTS, + context.notification(Notifications.CHANNEL_UPDATES_TO_EXTS) { + setContentTitle( + context.getString( + R.string.update_check_notification_ext_updates, names.size + ) + ) + val extNames = if (names.size > 5) { + "${names.take(4).joinToString(", ")}, " + context.getString( + R.string.notification_and_n_more, (names.size - 4) + ) + } else names.joinToString(", ") + setContentText(extNames) + setSmallIcon(R.drawable.ic_extension_update) + color = ContextCompat.getColor(context, R.color.colorAccentLight) + setContentIntent( + NotificationReceiver.openExtensionsPendingActivity( + context + ) + ) + setAutoCancel(true) + }) + } + } + Result.SUCCESS + }.onErrorReturn { Result.FAILURE } + }.subscribeOn(Schedulers.io()) + .subscribe({ + }, { + Timber.e(it) + }, { + }) + return Result.SUCCESS + } + + /*fun runStuff(context: Context) { + val extensionManager: ExtensionManager = Injekt.get() + extensionManager.findAvailableExtensions() + Observable.defer { + extensionManager.getInstalledExtensionsObservable().map { list -> + val pendingUpdates = list.filter { it.hasUpdate } + if (pendingUpdates.isNotEmpty()) { + val names = pendingUpdates.map { it.name } + NotificationManagerCompat.from(context).apply { + notify(Notifications.ID_UPDATES_TO_EXTS, + context.notification(Notifications.CHANNEL_UPDATES_TO_EXTS) { + setContentTitle( + context.getString( + R.string.update_check_notification_ext_updates, names.size + ) + ) + val extNames = if (names.size > 5) { + "${names.take(4).joinToString(", ")}, " + context.getString( + R.string.notification_and_n_more, (names.size - 4) + ) + } else names.joinToString(", ") + setContentText(extNames) + setSmallIcon(R.drawable.ic_extension_update) + color = ContextCompat.getColor(context, R.color.colorAccentLight) + setContentIntent( + NotificationReceiver.openExtensionsPendingActivity( + context + ) + ) + setAutoCancel(true) + }) + } + } + Result.SUCCESS + }.onErrorReturn { Result.FAILURE } + }.subscribeOn(Schedulers.io()) + .subscribe({ + }, { + Timber.e(it) + }, { + }) + }*/ + + + + companion object { + const val TAG = "ExtensionUpdate" + + fun setupTask() { + JobRequest.Builder(TAG).setPeriodic(TimeUnit.DAYS.toMillis(1), + TimeUnit.HOURS.toMillis(1)) + .setRequiredNetworkType(JobRequest.NetworkType.CONNECTED) + .setRequirementsEnforced(true) + .setUpdateCurrent(true) + .build().schedule() + } + + fun cancelTask() { + JobManager.instance().cancelAllForTag(TAG) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt index cb9c5dbb28..3cd347c5d0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt @@ -16,12 +16,16 @@ import com.jakewharton.rxbinding.support.v7.widget.queryTextChanges import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.items.IFlexible import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.data.preference.getOrDefault +import eu.kanade.tachiyomi.extension.ExtensionUpdateJob import eu.kanade.tachiyomi.extension.model.Extension import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.util.RecyclerWindowInsetsListener import kotlinx.android.synthetic.main.extension_controller.* - +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get /** * Controller to manage the catalogues available in the app. @@ -86,6 +90,16 @@ open class ExtensionController : NucleusController(), .popChangeHandler(SettingsExtensionsFadeChangeHandler()) .pushChangeHandler(FadeChangeHandler())) } + R.id.action_auto_check -> { + item.isChecked = !item.isChecked + val preferences:PreferencesHelper = Injekt.get() + preferences.automaticExtUpdates().set(item.isChecked) + + if (item.isChecked) + ExtensionUpdateJob.setupTask() + else + ExtensionUpdateJob.cancelTask() + } else -> return super.onOptionsItemSelected(item) } return true @@ -139,6 +153,10 @@ open class ExtensionController : NucleusController(), // Fixes problem with the overflow icon showing up in lieu of search searchItem.fixExpand() + + val autoItem = menu.findItem(R.id.action_auto_check) + val preferences:PreferencesHelper = Injekt.get() + autoItem.isChecked = preferences.automaticExtUpdates().getOrDefault() } override fun onItemClick(view: View?, position: Int): Boolean { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 95c4e10647..b787a69d3c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -9,16 +9,23 @@ import android.graphics.Rect import android.os.Build import android.os.Bundle import android.view.MotionEvent -import androidx.core.view.GravityCompat -import androidx.appcompat.app.AppCompatDelegate.* -import androidx.appcompat.graphics.drawable.DrawerArrowDrawable import android.view.View import android.view.ViewGroup import android.widget.FrameLayout import android.widget.LinearLayout +import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM +import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO +import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES +import androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode +import androidx.appcompat.graphics.drawable.DrawerArrowDrawable import androidx.biometric.BiometricManager import androidx.core.graphics.ColorUtils -import com.bluelinelabs.conductor.* +import androidx.core.view.GravityCompat +import com.bluelinelabs.conductor.Conductor +import com.bluelinelabs.conductor.Controller +import com.bluelinelabs.conductor.ControllerChangeHandler +import com.bluelinelabs.conductor.Router +import com.bluelinelabs.conductor.RouterTransaction import com.google.android.material.snackbar.Snackbar import eu.kanade.tachiyomi.Migrations import eu.kanade.tachiyomi.R @@ -26,7 +33,11 @@ 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.ui.base.activity.BaseActivity -import eu.kanade.tachiyomi.ui.base.controller.* +import eu.kanade.tachiyomi.ui.base.controller.DialogController +import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController +import eu.kanade.tachiyomi.ui.base.controller.SecondaryDrawerController +import eu.kanade.tachiyomi.ui.base.controller.TabbedController +import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.catalogue.CatalogueController import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController import eu.kanade.tachiyomi.ui.download.DownloadController @@ -282,6 +293,7 @@ class MainActivity : BaseActivity() { SHORTCUT_RECENTLY_UPDATED -> setSelectedDrawerItem(R.id.nav_drawer_recent_updates) SHORTCUT_RECENTLY_READ -> setSelectedDrawerItem(R.id.nav_drawer_recently_read) SHORTCUT_CATALOGUES -> setSelectedDrawerItem(R.id.nav_drawer_catalogues) + SHORTCUT_EXTENSIONS -> setSelectedDrawerItem(R.id.nav_drawer_extensions) SHORTCUT_MANGA -> { val extras = intent.extras ?: return false router.setRoot(RouterTransaction.with(MangaController(extras))) @@ -425,6 +437,7 @@ class MainActivity : BaseActivity() { const val SHORTCUT_CATALOGUES = "eu.kanade.tachiyomi.SHOW_CATALOGUES" const val SHORTCUT_DOWNLOADS = "eu.kanade.tachiyomi.SHOW_DOWNLOADS" const val SHORTCUT_MANGA = "eu.kanade.tachiyomi.SHOW_MANGA" + const val SHORTCUT_EXTENSIONS = "eu.kanade.tachiyomi.EXTENSIONS" const val INTENT_SEARCH = "eu.kanade.tachiyomi.SEARCH" const val INTENT_SEARCH_QUERY = "query" diff --git a/app/src/main/res/drawable-hdpi/ic_extension_update.png b/app/src/main/res/drawable-hdpi/ic_extension_update.png new file mode 100644 index 0000000000..add124edac Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_extension_update.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_extension_update.png b/app/src/main/res/drawable-mdpi/ic_extension_update.png new file mode 100644 index 0000000000..9956eebfc0 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_extension_update.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_extension_update.png b/app/src/main/res/drawable-xhdpi/ic_extension_update.png new file mode 100644 index 0000000000..0ebd6ca1db Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_extension_update.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_extension_update.png b/app/src/main/res/drawable-xxhdpi/ic_extension_update.png new file mode 100644 index 0000000000..82901bd47d Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_extension_update.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_extension_update.png b/app/src/main/res/drawable-xxxhdpi/ic_extension_update.png new file mode 100644 index 0000000000..c1366de978 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_extension_update.png differ diff --git a/app/src/main/res/menu/extension_main.xml b/app/src/main/res/menu/extension_main.xml index f64ef97801..bee5c2a555 100644 --- a/app/src/main/res/menu/extension_main.xml +++ b/app/src/main/res/menu/extension_main.xml @@ -14,4 +14,11 @@ android:icon="@drawable/ic_filter_list_white_24dp" app:showAsAction="always"/> + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ce9c5a058b..1eef24d258 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -103,6 +103,7 @@ Log in Back Forward + Auto-check for updates Deleting… @@ -515,6 +516,7 @@ Download complete Download error Update available + %1$d extension updates available Backdrop image of manga @@ -541,6 +543,7 @@ Common Library Downloader + Extension Updates Updating Library New Chapters