Added code to prevent OutOfMemory error. Made notification optional. Can now save image on long press. Bug fixes
This commit is contained in:
parent
1210691fdd
commit
4975787afa
@ -47,6 +47,8 @@ class DownloadManager(
|
|||||||
private val threadsSubject = BehaviorSubject.create<Int>()
|
private val threadsSubject = BehaviorSubject.create<Int>()
|
||||||
private var threadsSubscription: Subscription? = null
|
private var threadsSubscription: Subscription? = null
|
||||||
|
|
||||||
|
private var notificationSubscription: Subscription? = null
|
||||||
|
|
||||||
val queue = DownloadQueue()
|
val queue = DownloadQueue()
|
||||||
|
|
||||||
val imageFilenameRegex = "[^\\sa-zA-Z0-9.-]".toRegex()
|
val imageFilenameRegex = "[^\\sa-zA-Z0-9.-]".toRegex()
|
||||||
@ -66,6 +68,12 @@ class DownloadManager(
|
|||||||
downloadNotifier.multipleDownloadThreads = it > 1
|
downloadNotifier.multipleDownloadThreads = it > 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
notificationSubscription = preferences.showMangaDownloadNotification().asObservable()
|
||||||
|
.subscribe {
|
||||||
|
downloadNotifier.onClear()
|
||||||
|
downloadNotifier.showNotification = it
|
||||||
|
}
|
||||||
|
|
||||||
downloadsSubscription = downloadsQueueSubject.flatMap { Observable.from(it) }
|
downloadsSubscription = downloadsQueueSubject.flatMap { Observable.from(it) }
|
||||||
.lift(DynamicConcurrentMergeOperator<Download, Download>({ downloadChapter(it) }, threadsSubject))
|
.lift(DynamicConcurrentMergeOperator<Download, Download>({ downloadChapter(it) }, threadsSubject))
|
||||||
.onBackpressureBuffer()
|
.onBackpressureBuffer()
|
||||||
@ -107,6 +115,10 @@ class DownloadManager(
|
|||||||
threadsSubscription?.unsubscribe()
|
threadsSubscription?.unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (notificationSubscription != null) {
|
||||||
|
notificationSubscription?.unsubscribe()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a download object for every chapter and add them to the downloads queue
|
// Create a download object for every chapter and add them to the downloads queue
|
||||||
@ -188,7 +200,7 @@ class DownloadManager(
|
|||||||
DiskUtils.createDirectory(download.directory)
|
DiskUtils.createDirectory(download.directory)
|
||||||
|
|
||||||
val pageListObservable: Observable<List<Page>> = if (download.pages == null)
|
val pageListObservable: Observable<List<Page>> = if (download.pages == null)
|
||||||
// Pull page list from network and add them to download object
|
// Pull page list from network and add them to download object
|
||||||
download.source.fetchPageListFromNetwork(download.chapter)
|
download.source.fetchPageListFromNetwork(download.chapter)
|
||||||
.doOnNext { pages ->
|
.doOnNext { pages ->
|
||||||
download.pages = pages
|
download.pages = pages
|
||||||
|
@ -7,6 +7,7 @@ import eu.kanade.tachiyomi.R
|
|||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.data.download.model.DownloadQueue
|
import eu.kanade.tachiyomi.data.download.model.DownloadQueue
|
||||||
import eu.kanade.tachiyomi.util.notificationManager
|
import eu.kanade.tachiyomi.util.notificationManager
|
||||||
|
import eu.kanade.tachiyomi.util.toast
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DownloadNotifier is used to show notifications when downloading one or multiple chapters.
|
* DownloadNotifier is used to show notifications when downloading one or multiple chapters.
|
||||||
@ -40,6 +41,11 @@ class DownloadNotifier(private val context: Context) {
|
|||||||
*/
|
*/
|
||||||
internal var multipleDownloadThreads = false
|
internal var multipleDownloadThreads = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value determining if notification should be shown
|
||||||
|
*/
|
||||||
|
internal var showNotification = true
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when download progress changes.
|
* Called when download progress changes.
|
||||||
* Note: Only accepted when multi download active.
|
* Note: Only accepted when multi download active.
|
||||||
@ -47,9 +53,8 @@ class DownloadNotifier(private val context: Context) {
|
|||||||
* @param queue the queue containing downloads.
|
* @param queue the queue containing downloads.
|
||||||
*/
|
*/
|
||||||
internal fun onProgressChange(queue: DownloadQueue) {
|
internal fun onProgressChange(queue: DownloadQueue) {
|
||||||
if (multipleDownloadThreads) {
|
if (multipleDownloadThreads && showNotification)
|
||||||
doOnProgressChange(null, queue)
|
doOnProgressChange(null, queue)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,9 +65,8 @@ class DownloadNotifier(private val context: Context) {
|
|||||||
* @param queue the queue containing downloads
|
* @param queue the queue containing downloads
|
||||||
*/
|
*/
|
||||||
internal fun onProgressChange(download: Download, queue: DownloadQueue) {
|
internal fun onProgressChange(download: Download, queue: DownloadQueue) {
|
||||||
if (!multipleDownloadThreads) {
|
if (!multipleDownloadThreads && showNotification)
|
||||||
doOnProgressChange(download, queue)
|
doOnProgressChange(download, queue)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,7 +90,7 @@ class DownloadNotifier(private val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create notification
|
// Create notification
|
||||||
with (notificationBuilder) {
|
with(notificationBuilder) {
|
||||||
// Check if icon needs refresh
|
// Check if icon needs refresh
|
||||||
if (!isDownloading) {
|
if (!isDownloading) {
|
||||||
setSmallIcon(android.R.drawable.stat_sys_download)
|
setSmallIcon(android.R.drawable.stat_sys_download)
|
||||||
@ -127,17 +131,18 @@ class DownloadNotifier(private val context: Context) {
|
|||||||
* @param download download object containing download information
|
* @param download download object containing download information
|
||||||
*/
|
*/
|
||||||
private fun onComplete(download: Download?) {
|
private fun onComplete(download: Download?) {
|
||||||
// Create notification.
|
if (showNotification) {
|
||||||
with(notificationBuilder) {
|
// Create notification.
|
||||||
setContentTitle(download?.chapter?.name ?: context.getString(R.string.app_name))
|
with(notificationBuilder) {
|
||||||
setContentText(context.getString(R.string.update_check_notification_download_complete))
|
setContentTitle(download?.chapter?.name ?: context.getString(R.string.app_name))
|
||||||
setSmallIcon(android.R.drawable.stat_sys_download_done)
|
setContentText(context.getString(R.string.update_check_notification_download_complete))
|
||||||
setProgress(0, 0, false)
|
setSmallIcon(android.R.drawable.stat_sys_download_done)
|
||||||
|
setProgress(0, 0, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show notification.
|
||||||
|
context.notificationManager.notify(notificationId, notificationBuilder.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show notification.
|
|
||||||
context.notificationManager.notify(notificationId, notificationBuilder.build())
|
|
||||||
|
|
||||||
// Reset initial values
|
// Reset initial values
|
||||||
isDownloading = false
|
isDownloading = false
|
||||||
initialQueueSize = 0
|
initialQueueSize = 0
|
||||||
@ -158,14 +163,17 @@ class DownloadNotifier(private val context: Context) {
|
|||||||
*/
|
*/
|
||||||
internal fun onError(error: String? = null, chapter: String? = null) {
|
internal fun onError(error: String? = null, chapter: String? = null) {
|
||||||
// Create notification
|
// Create notification
|
||||||
with(notificationBuilder) {
|
if (showNotification) {
|
||||||
setContentTitle(chapter ?: context.getString(R.string.download_notifier_title_error))
|
with(notificationBuilder) {
|
||||||
setContentText(error ?: context.getString(R.string.download_notifier_unkown_error))
|
setContentTitle(chapter ?: context.getString(R.string.download_notifier_title_error))
|
||||||
setSmallIcon(android.R.drawable.stat_sys_warning)
|
setContentText(error ?: context.getString(R.string.download_notifier_unkown_error))
|
||||||
setProgress(0, 0, false)
|
setSmallIcon(android.R.drawable.stat_sys_warning)
|
||||||
|
setProgress(0, 0, false)
|
||||||
|
}
|
||||||
|
context.notificationManager.notify(Constants.NOTIFICATION_DOWNLOAD_CHAPTER_ERROR_ID, notificationBuilder.build())
|
||||||
|
} else {
|
||||||
|
context.toast(error ?: context.getString(R.string.download_notifier_unkown_error))
|
||||||
}
|
}
|
||||||
context.notificationManager.notify(Constants.NOTIFICATION_DOWNLOAD_CHAPTER_ERROR_ID, notificationBuilder.build())
|
|
||||||
|
|
||||||
// Reset download information
|
// Reset download information
|
||||||
onClear()
|
onClear()
|
||||||
isDownloading = false
|
isDownloading = false
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package eu.kanade.tachiyomi.data.download
|
package eu.kanade.tachiyomi.data.download
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.support.v4.app.NotificationCompat
|
import android.support.v4.app.NotificationCompat
|
||||||
import eu.kanade.tachiyomi.Constants
|
import eu.kanade.tachiyomi.Constants
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.util.decodeSampledBitmap
|
||||||
import eu.kanade.tachiyomi.util.notificationManager
|
import eu.kanade.tachiyomi.util.notificationManager
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@ -52,9 +51,9 @@ class ImageNotifier(private val context: Context) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when image download is complete
|
* Called when image download is complete
|
||||||
* @param bitmap image file containing downloaded page image
|
* @param file image file containing downloaded page image
|
||||||
*/
|
*/
|
||||||
fun onComplete(bitmap: Bitmap, file: File) {
|
fun onComplete(file: File) {
|
||||||
with(notificationBuilder) {
|
with(notificationBuilder) {
|
||||||
if (isDownloading) {
|
if (isDownloading) {
|
||||||
setProgress(0, 0, false)
|
setProgress(0, 0, false)
|
||||||
@ -62,8 +61,8 @@ class ImageNotifier(private val context: Context) {
|
|||||||
}
|
}
|
||||||
setContentTitle(context.getString(R.string.picture_saved))
|
setContentTitle(context.getString(R.string.picture_saved))
|
||||||
setSmallIcon(R.drawable.ic_insert_photo_black_24dp)
|
setSmallIcon(R.drawable.ic_insert_photo_black_24dp)
|
||||||
setLargeIcon(bitmap)
|
setLargeIcon(file.decodeSampledBitmap(100, 100))
|
||||||
setStyle(NotificationCompat.BigPictureStyle().bigPicture(bitmap))
|
setStyle(NotificationCompat.BigPictureStyle().bigPicture(file.decodeSampledBitmap(1024, 1024)))
|
||||||
setAutoCancel(true)
|
setAutoCancel(true)
|
||||||
|
|
||||||
// Clear old actions if they exist
|
// Clear old actions if they exist
|
||||||
@ -84,10 +83,6 @@ class ImageNotifier(private val context: Context) {
|
|||||||
context.notificationManager.notify(notificationId, notificationBuilder.build())
|
context.notificationManager.notify(notificationId, notificationBuilder.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onComplete(file: File) {
|
|
||||||
onComplete(convertToBitmap(file), file)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the notification message
|
* Clears the notification message
|
||||||
*/
|
*/
|
||||||
@ -112,13 +107,4 @@ class ImageNotifier(private val context: Context) {
|
|||||||
isDownloading = false
|
isDownloading = false
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts file to bitmap
|
|
||||||
*/
|
|
||||||
fun convertToBitmap(image: File): Bitmap {
|
|
||||||
val options = BitmapFactory.Options()
|
|
||||||
options.inPreferredConfig = Bitmap.Config.ARGB_8888
|
|
||||||
return BitmapFactory.decodeFile(image.absolutePath, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -72,6 +72,10 @@ class PreferenceKeys(context: Context) {
|
|||||||
|
|
||||||
val removeAfterMarkedAsRead = context.getString(R.string.pref_remove_after_marked_as_read_key)
|
val removeAfterMarkedAsRead = context.getString(R.string.pref_remove_after_marked_as_read_key)
|
||||||
|
|
||||||
|
val showMangaDownloadNotification = context.getString(R.string.pref_notifications_manga_download_key)
|
||||||
|
|
||||||
|
val showSavePageNotification = context.getString(R.string.pref_notifications_single_page_key)
|
||||||
|
|
||||||
val libraryUpdateInterval = context.getString(R.string.pref_library_update_interval_key)
|
val libraryUpdateInterval = context.getString(R.string.pref_library_update_interval_key)
|
||||||
|
|
||||||
val libraryUpdateRestriction = context.getString(R.string.pref_library_update_restriction_key)
|
val libraryUpdateRestriction = context.getString(R.string.pref_library_update_restriction_key)
|
||||||
|
@ -122,6 +122,10 @@ class PreferencesHelper(context: Context) {
|
|||||||
|
|
||||||
fun removeAfterMarkedAsRead() = prefs.getBoolean(keys.removeAfterMarkedAsRead, false)
|
fun removeAfterMarkedAsRead() = prefs.getBoolean(keys.removeAfterMarkedAsRead, false)
|
||||||
|
|
||||||
|
fun showMangaDownloadNotification() = rxPrefs.getBoolean(keys.showMangaDownloadNotification, true)
|
||||||
|
|
||||||
|
fun showSavePageNotification() = prefs.getBoolean(keys.showSavePageNotification, false)
|
||||||
|
|
||||||
fun libraryUpdateInterval() = rxPrefs.getInteger(keys.libraryUpdateInterval, 0)
|
fun libraryUpdateInterval() = rxPrefs.getInteger(keys.libraryUpdateInterval, 0)
|
||||||
|
|
||||||
fun libraryUpdateRestriction() = prefs.getStringSet(keys.libraryUpdateRestriction, emptySet())
|
fun libraryUpdateRestriction() = prefs.getStringSet(keys.libraryUpdateRestriction, emptySet())
|
||||||
|
@ -145,8 +145,6 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
|
|||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_settings -> ReaderSettingsDialog().show(supportFragmentManager, "settings")
|
R.id.action_settings -> ReaderSettingsDialog().show(supportFragmentManager, "settings")
|
||||||
R.id.action_custom_filter -> ReaderCustomFilterDialog().show(supportFragmentManager, "filter")
|
R.id.action_custom_filter -> ReaderCustomFilterDialog().show(supportFragmentManager, "filter")
|
||||||
R.id.action_save_page -> presenter.savePage()
|
|
||||||
R.id.action_set_as_cover -> presenter.setCover()
|
|
||||||
else -> return super.onOptionsItemSelected(item)
|
else -> return super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -230,6 +228,22 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
|
|||||||
// Ignore
|
// Ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onLongPress() {
|
||||||
|
MaterialDialog.Builder(this).apply {
|
||||||
|
title = "Choose"
|
||||||
|
items(R.array.reader_image_options)
|
||||||
|
.itemsIds(R.array.reader_image_options_values)
|
||||||
|
itemsCallback { materialDialog, view, i, charSequence ->
|
||||||
|
when (i) {
|
||||||
|
0 -> presenter.setCover()
|
||||||
|
1 -> presenter.shareImage()
|
||||||
|
2 -> presenter.savePage()
|
||||||
|
}
|
||||||
|
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from the presenter at startup, allowing to prepare the selected reader.
|
* Called from the presenter at startup, allowing to prepare the selected reader.
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package eu.kanade.tachiyomi.ui.reader
|
package eu.kanade.tachiyomi.ui.reader
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
@ -576,6 +578,19 @@ class ReaderPresenter : BasePresenter<ReaderActivity>() {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun shareImage() {
|
||||||
|
chapter.pages?.get(chapter.last_page_read)?.let { page ->
|
||||||
|
val shareIntent = Intent().apply {
|
||||||
|
action = Intent.ACTION_SEND
|
||||||
|
putExtra(Intent.EXTRA_STREAM, Uri.parse(page.imagePath))
|
||||||
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
type = "image/jpeg"
|
||||||
|
}
|
||||||
|
context.startActivity(Intent.createChooser(shareIntent, context.resources.getText(R.string.action_share))
|
||||||
|
.apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save page to local storage
|
* Save page to local storage
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
@ -595,7 +610,10 @@ class ReaderPresenter : BasePresenter<ReaderActivity>() {
|
|||||||
|
|
||||||
//Check if file doesn't already exist
|
//Check if file doesn't already exist
|
||||||
if (destFile.exists()) {
|
if (destFile.exists()) {
|
||||||
imageNotifier.onComplete(destFile)
|
if (prefs.showSavePageNotification())
|
||||||
|
imageNotifier.onComplete(destFile)
|
||||||
|
else
|
||||||
|
context.toast(context.getString(R.string.page_downloaded, destFile.path))
|
||||||
} else {
|
} else {
|
||||||
if (inputFile.exists()) {
|
if (inputFile.exists()) {
|
||||||
// Copy file
|
// Copy file
|
||||||
@ -606,7 +624,10 @@ class ReaderPresenter : BasePresenter<ReaderActivity>() {
|
|||||||
{ imageNotifier.onComplete(it) },
|
{ imageNotifier.onComplete(it) },
|
||||||
{ error ->
|
{ error ->
|
||||||
Timber.e(error.message)
|
Timber.e(error.message)
|
||||||
imageNotifier.onError(error.message)
|
if (prefs.showSavePageNotification())
|
||||||
|
imageNotifier.onError(error.message)
|
||||||
|
else
|
||||||
|
context.toast(error.message)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,6 +185,11 @@ abstract class PagerReader : BaseReader() {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onLongPress(e: MotionEvent?) {
|
||||||
|
super.onLongPress(e)
|
||||||
|
readerActivity.onLongPress()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,6 +140,11 @@ class WebtoonReader : BaseReader() {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onLongPress(e: MotionEvent?) {
|
||||||
|
super.onLongPress(e)
|
||||||
|
readerActivity.onLongPress()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
40
app/src/main/java/eu/kanade/tachiyomi/util/FileExtensions.kt
Normal file
40
app/src/main/java/eu/kanade/tachiyomi/util/FileExtensions.kt
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package eu.kanade.tachiyomi.util
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
fun File.decodeSampledBitmap(reqWidth: Int, reqHeight: Int): Bitmap {
|
||||||
|
// First decode with inJustDecodeBounds=true to check dimensions
|
||||||
|
val options = BitmapFactory.Options()
|
||||||
|
options.inJustDecodeBounds = true
|
||||||
|
BitmapFactory.decodeFile(this.absolutePath, options)
|
||||||
|
|
||||||
|
// Calculate inSampleSize
|
||||||
|
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight)
|
||||||
|
|
||||||
|
// Decode bitmap with inSampleSize set
|
||||||
|
options.inJustDecodeBounds = false;
|
||||||
|
return BitmapFactory.decodeFile(this.absolutePath, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
|
||||||
|
// Raw height and width of image
|
||||||
|
val height = options.outHeight
|
||||||
|
val width = options.outWidth
|
||||||
|
var inSampleSize = 1
|
||||||
|
|
||||||
|
if (height > reqHeight || width > reqWidth) {
|
||||||
|
|
||||||
|
val halfHeight = height / 2
|
||||||
|
val halfWidth = width / 2
|
||||||
|
|
||||||
|
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
|
||||||
|
// height and width larger than the requested height and width.
|
||||||
|
while (halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth) {
|
||||||
|
inSampleSize *= 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return inSampleSize
|
||||||
|
}
|
@ -174,4 +174,16 @@
|
|||||||
<item>3</item>
|
<item>3</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="reader_image_options">
|
||||||
|
<item>@string/set_as_cover</item>
|
||||||
|
<item>@string/share_image</item>
|
||||||
|
<item>@string/save_image</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="reader_image_options_values">
|
||||||
|
<item>0</item>
|
||||||
|
<item>1</item>
|
||||||
|
<item>2</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -48,7 +48,8 @@
|
|||||||
<string name="pref_download_only_over_wifi_key">pref_download_only_over_wifi_key</string>
|
<string name="pref_download_only_over_wifi_key">pref_download_only_over_wifi_key</string>
|
||||||
<string name="pref_remove_after_marked_as_read_key">pref_remove_after_marked_as_read_key</string>
|
<string name="pref_remove_after_marked_as_read_key">pref_remove_after_marked_as_read_key</string>
|
||||||
<string name="pref_category_remove_after_read_key">pref_category_remove_after_read_key</string>
|
<string name="pref_category_remove_after_read_key">pref_category_remove_after_read_key</string>
|
||||||
|
<string name="pref_notifications_single_page_key">notifications_single_page</string>
|
||||||
|
<string name="pref_notifications_manga_download_key">notifications_manga_download</string>
|
||||||
<string name="pref_last_used_category_key">last_used_category</string>
|
<string name="pref_last_used_category_key">last_used_category</string>
|
||||||
|
|
||||||
<string name="pref_source_languages">pref_source_languages</string>
|
<string name="pref_source_languages">pref_source_languages</string>
|
||||||
|
@ -281,6 +281,11 @@
|
|||||||
|
|
||||||
<!-- Reader activity -->
|
<!-- Reader activity -->
|
||||||
<string name="custom_filter">Custom filter</string>
|
<string name="custom_filter">Custom filter</string>
|
||||||
|
<string name="set_as_cover">Set as cover</string>
|
||||||
|
<string name="share_image">Share image</string>
|
||||||
|
<string name="save_image">Save image</string>
|
||||||
|
<string name="cover_updated">Cover updated</string>
|
||||||
|
<string name="page_downloaded">Page copied to %1$s</string>
|
||||||
<string name="downloading">Downloading…</string>
|
<string name="downloading">Downloading…</string>
|
||||||
<string name="download_progress">Downloaded %1$d%%</string>
|
<string name="download_progress">Downloaded %1$d%%</string>
|
||||||
<string name="chapter_progress">Page: %1$d</string>
|
<string name="chapter_progress">Page: %1$d</string>
|
||||||
|
@ -40,6 +40,21 @@
|
|||||||
android:summary="%s"
|
android:summary="%s"
|
||||||
android:title="@string/pref_remove_after_read" />
|
android:title="@string/pref_remove_after_read" />
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:persistent="false"
|
||||||
|
android:title="@string/pref_notifications" />
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:key="@string/pref_notifications_manga_download_key"
|
||||||
|
android:title="@string/pref_notifications_manga_download" />
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="@string/pref_notifications_single_page_key"
|
||||||
|
android:title="@string/pref_notifications_single_page" />
|
||||||
|
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
Loading…
Reference in New Issue
Block a user