Auto check for extension updates
Setting lives in Extensions -> Overflow menu Checks every day
This commit is contained in:
parent
1f25030197
commit
3ac6f5829c
18 changed files with 274 additions and 24 deletions
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<PreferencesHelper>()
|
||||
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()
|
||||
|
|
|
@ -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<PreferencesHelper>()
|
||||
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)
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<ExtensionPresenter>(),
|
|||
.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<ExtensionPresenter>(),
|
|||
|
||||
// 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 {
|
||||
|
|
|
@ -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"
|
||||
|
|
BIN
app/src/main/res/drawable-hdpi/ic_extension_update.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_extension_update.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 404 B |
BIN
app/src/main/res/drawable-mdpi/ic_extension_update.png
Normal file
BIN
app/src/main/res/drawable-mdpi/ic_extension_update.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 284 B |
BIN
app/src/main/res/drawable-xhdpi/ic_extension_update.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_extension_update.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 516 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_extension_update.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/ic_extension_update.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 784 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_extension_update.png
Normal file
BIN
app/src/main/res/drawable-xxxhdpi/ic_extension_update.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
|
@ -14,4 +14,11 @@
|
|||
android:icon="@drawable/ic_filter_list_white_24dp"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_auto_check"
|
||||
android:title="@string/action_auto_check_extensions"
|
||||
android:icon="@drawable/ic_filter_list_white_24dp"
|
||||
android:checkable="true"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
</menu>
|
||||
|
|
|
@ -103,6 +103,7 @@
|
|||
<string name="action_login">Log in</string>
|
||||
<string name="action_webview_back">Back</string>
|
||||
<string name="action_webview_forward">Forward</string>
|
||||
<string name="action_auto_check_extensions">Auto-check for updates</string>
|
||||
|
||||
<!-- Operations -->
|
||||
<string name="deleting">Deleting…</string>
|
||||
|
@ -515,6 +516,7 @@
|
|||
<string name="update_check_notification_download_complete">Download complete</string>
|
||||
<string name="update_check_notification_download_error">Download error</string>
|
||||
<string name="update_check_notification_update_available">Update available</string>
|
||||
<string name="update_check_notification_ext_updates">%1$d extension updates available</string>
|
||||
|
||||
<!--Content Description-->
|
||||
<string name="description_backdrop">Backdrop image of manga</string>
|
||||
|
@ -541,6 +543,7 @@
|
|||
<string name="channel_common">Common</string>
|
||||
<string name="channel_library">Library</string>
|
||||
<string name="channel_downloader">Downloader</string>
|
||||
<string name="channel_ext_updates">Extension Updates</string>
|
||||
<string name="channel_library_updates">Updating Library</string>
|
||||
<string name="channel_new_chapters">New Chapters</string>
|
||||
|
||||
|
|
Reference in a new issue