diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7c9fab506c..6f402b8b06 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -54,6 +54,16 @@ android:theme="@style/FilePickerTheme"> + + + + @@ -68,9 +78,9 @@ - - + + + () { val url = source.mangaDetailsRequest(presenter.manga).url().toString() val sharingIntent = Intent(Intent.ACTION_SEND).apply { type = "text/plain" - putExtra(android.content.Intent.EXTRA_SUBJECT, presenter.manga.title) putExtra(android.content.Intent.EXTRA_TEXT, resources.getString(R.string.share_text, presenter.manga.title, url)) } - startActivity(Intent.createChooser(sharingIntent, resources.getText(R.string.share_subject))) + startActivity(Intent.createChooser(sharingIntent, resources.getText(R.string.action_share))) } catch (e: Exception) { context.toast(e.message) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index 0b935c8735..4f8634b871 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -5,6 +5,7 @@ import android.content.Intent import android.content.pm.ActivityInfo import android.content.res.Configuration import android.graphics.Color +import android.net.Uri import android.os.Build import android.os.Build.VERSION_CODES.KITKAT import android.os.Bundle @@ -224,6 +225,20 @@ class ReaderActivity : BaseRxActivity() { toast(error.message) } + fun onLongPress(page: Page) { + MaterialDialog.Builder(this) + .title(getString(R.string.options)) + .items(R.array.reader_image_options) + .itemsIds(R.array.reader_image_options_values) + .itemsCallback { materialDialog, view, i, charSequence -> + when (i) { + 0 -> presenter.setCover(page) + 1 -> shareImage(page) + 2 -> presenter.savePage(page) + } + }.show() + } + fun onChapterAppendError() { // Ignore } @@ -455,6 +470,24 @@ class ReaderActivity : BaseRxActivity() { } } + /** + * Start a share intent that lets user share image + * + * @param page page object containing image information. + */ + fun shareImage(page: Page) { + if (page.status != Page.READY) + return + + 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" + } + startActivity(Intent.createChooser(shareIntent, resources.getText(R.string.action_share))) + } + /** * Sets the brightness of the screen. Range is [-75, 100]. * From -75 to -1 a semi-transparent black view is shown at the top with the minimum brightness. diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt index 69cd6dff15..3f94a3f629 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt @@ -1,7 +1,10 @@ package eu.kanade.tachiyomi.ui.reader import android.os.Bundle +import android.os.Environment +import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.cache.ChapterCache +import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.History @@ -15,8 +18,10 @@ import eu.kanade.tachiyomi.data.source.SourceManager import eu.kanade.tachiyomi.data.source.model.Page import eu.kanade.tachiyomi.data.source.online.OnlineSource import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter +import eu.kanade.tachiyomi.ui.reader.notification.ImageNotifier import eu.kanade.tachiyomi.util.RetryWithDelay import eu.kanade.tachiyomi.util.SharedData +import eu.kanade.tachiyomi.util.toast import rx.Observable import rx.Subscription import rx.android.schedulers.AndroidSchedulers @@ -24,13 +29,13 @@ import rx.schedulers.Schedulers import timber.log.Timber import uy.kohesive.injekt.injectLazy import java.io.File +import java.io.IOException import java.util.* /** * Presenter of [ReaderActivity]. */ class ReaderPresenter : BasePresenter() { - /** * Preferences. */ @@ -61,6 +66,11 @@ class ReaderPresenter : BasePresenter() { */ val chapterCache: ChapterCache by injectLazy() + /** + * Cover cache. + */ + val coverCache: CoverCache by injectLazy() + /** * Manga being read. */ @@ -88,6 +98,15 @@ class ReaderPresenter : BasePresenter() { */ private val source by lazy { sourceManager.get(manga.source)!! } + /** + * Directory of pictures + */ + private val pictureDirectory: String by lazy { + Environment.getExternalStorageDirectory().absolutePath + File.separator + + Environment.DIRECTORY_PICTURES + File.separator + + context.getString(R.string.app_name) + File.separator + } + /** * Chapter list for the active manga. It's retrieved lazily and should be accessed for the first * time in a background thread to avoid blocking the UI. @@ -364,11 +383,11 @@ class ReaderPresenter : BasePresenter() { if (chapter.read) { val removeAfterReadSlots = prefs.removeAfterReadSlots() when (removeAfterReadSlots) { - // Setting disabled + // Setting disabled -1 -> { /**Empty function**/ } - // Remove current read chapter + // Remove current read chapter 0 -> deleteChapter(chapter, manga) - // Remove previous chapter specified by user in settings. + // Remove previous chapter specified by user in settings. else -> getAdjacentChaptersStrategy(chapter, removeAfterReadSlots) .first?.let { deleteChapter(it, manga) } } @@ -384,8 +403,8 @@ class ReaderPresenter : BasePresenter() { Timber.e(error) } } - .subscribeOn(Schedulers.io()) - .subscribe() + .subscribeOn(Schedulers.io()) + .subscribe() } /** @@ -508,4 +527,65 @@ class ReaderPresenter : BasePresenter() { db.insertManga(manga).executeAsBlocking() } + /** + * Update cover with page file. + */ + internal fun setCover(page: Page) { + if (page.status != Page.READY) + return + + try { + if (manga.favorite) { + if (manga.thumbnail_url != null) { + coverCache.copyToCache(manga.thumbnail_url!!, File(page.imagePath).inputStream()) + context.toast(R.string.cover_updated) + } else { + throw Exception("Image url not found") + } + } else { + context.toast(R.string.notification_first_add_to_library) + } + } catch (error: Exception) { + context.toast(R.string.notification_cover_update_failed) + Timber.e(error) + } + } + + /** + * Save page to local storage + * @throws IOException + */ + @Throws(IOException::class) + internal fun savePage(page: Page) { + if (page.status != Page.READY) + return + + // Used to show image notification + val imageNotifier = ImageNotifier(context) + + // Location of image file. + val inputFile = File(page.imagePath) + + // File where the image will be saved. + val destFile = File(pictureDirectory, manga.title + " - " + chapter.name + + " - " + downloadManager.getImageFilename(page)) + + //Remove the notification if already exist (user feedback) + imageNotifier.onClear() + if (inputFile.exists()) { + // Copy file + Observable.fromCallable { inputFile.copyTo(destFile, true) } + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { + // Show notification + imageNotifier.onComplete(it) + }, + { error -> + Timber.e(error) + imageNotifier.onError(error.message) + }) + } + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/notification/ImageNotificationReceiver.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/notification/ImageNotificationReceiver.kt new file mode 100644 index 0000000000..2c2a83d4e3 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/notification/ImageNotificationReceiver.kt @@ -0,0 +1,109 @@ +package eu.kanade.tachiyomi.ui.reader.notification + +import android.app.PendingIntent +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.support.v4.content.FileProvider +import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.util.notificationManager +import java.io.File + +/** + * The BroadcastReceiver of [ImageNotifier] + * Intent calls should be made from this class. + */ +class ImageNotificationReceiver : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + when (intent.action) { + ACTION_SHARE_IMAGE -> { + shareImage(context, intent.getStringExtra(EXTRA_FILE_LOCATION)) + context.notificationManager.cancel(intent.getIntExtra(NOTIFICATION_ID, 5)) + } + ACTION_SHOW_IMAGE -> + showImage(context, intent.getStringExtra(EXTRA_FILE_LOCATION)) + ACTION_DELETE_IMAGE -> { + deleteImage(intent.getStringExtra(EXTRA_FILE_LOCATION)) + context.notificationManager.cancel(intent.getIntExtra(NOTIFICATION_ID, 5)) + } + } + } + + /** + * Called to delete image + * @param path path of file + */ + private fun deleteImage(path: String) { + val file = File(path) + if (file.exists()) file.delete() + } + + /** + * Called to start share intent to share image + * @param context context of application + * @param path path of file + */ + private fun shareImage(context: Context, path: String) { + val shareIntent = Intent().apply { + action = Intent.ACTION_SEND + putExtra(Intent.EXTRA_STREAM, Uri.parse(path)) + 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 }) + } + + /** + * Called to show image in gallery application + * @param context context of application + * @param path path of file + */ + private fun showImage(context: Context, path: String) { + val intent = Intent().apply { + action = Intent.ACTION_VIEW + flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION + val uri = FileProvider.getUriForFile(context,"eu.kanade.tachiyomi.provider",File(path)) + setDataAndType(uri, "image/*") + } + context.startActivity(intent) + } + + companion object { + private const val ACTION_SHARE_IMAGE = "eu.kanade.SHARE_IMAGE" + + private const val ACTION_SHOW_IMAGE = "eu.kanade.SHOW_IMAGE" + + private const val ACTION_DELETE_IMAGE = "eu.kanade.DELETE_IMAGE" + + private const val EXTRA_FILE_LOCATION = "file_location" + + private const val NOTIFICATION_ID = "notification_id" + + internal fun shareImageIntent(context: Context, path: String, notificationId: Int): PendingIntent { + val intent = Intent(context, ImageNotificationReceiver::class.java).apply { + action = ACTION_SHARE_IMAGE + putExtra(EXTRA_FILE_LOCATION, path) + putExtra(NOTIFICATION_ID, notificationId) + } + return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) + } + + internal fun showImageIntent(context: Context, path: String): PendingIntent { + val intent = Intent(context, ImageNotificationReceiver::class.java).apply { + action = ACTION_SHOW_IMAGE + putExtra(EXTRA_FILE_LOCATION, path) + } + return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) + } + + internal fun deleteImageIntent(context: Context, path: String, notificationId: Int): PendingIntent { + val intent = Intent(context, ImageNotificationReceiver::class.java).apply { + action = ACTION_DELETE_IMAGE + putExtra(EXTRA_FILE_LOCATION, path) + putExtra(NOTIFICATION_ID, notificationId) + } + return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) + } + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/notification/ImageNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/notification/ImageNotifier.kt new file mode 100644 index 0000000000..a4edfcb52e --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/notification/ImageNotifier.kt @@ -0,0 +1,104 @@ +package eu.kanade.tachiyomi.ui.reader.notification + +import android.content.Context +import android.graphics.Bitmap +import android.media.Image +import android.support.v4.app.NotificationCompat +import com.bumptech.glide.Glide +import com.bumptech.glide.load.engine.DiskCacheStrategy +import com.bumptech.glide.request.animation.GlideAnimation +import com.bumptech.glide.request.target.SimpleTarget +import eu.kanade.tachiyomi.Constants +import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.util.notificationManager +import java.io.File + +/** + * Class used to show BigPictureStyle notifications + */ +class ImageNotifier(private val context: Context) { + /** + * Notification builder. + */ + private val notificationBuilder = NotificationCompat.Builder(context) + + /** + * Id of the notification. + */ + private val notificationId: Int + get() = Constants.NOTIFICATION_DOWNLOAD_IMAGE_ID + + /** + * Called when image download/copy is complete + * @param file image file containing downloaded page image + */ + fun onComplete(file: File) { + + Glide.with(context).load(file).asBitmap().diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true).into(object : SimpleTarget(720, 1280) { + /** + * The method that will be called when the resource load has finished. + * @param resource the loaded resource. + */ + override fun onResourceReady(resource: Bitmap?, glideAnimation: GlideAnimation?) { + if (resource!= null){ + showCompleteNotification(file, resource) + }else{ + onError(null) + } + } + }) + } + + private fun showCompleteNotification(file: File, image: Bitmap) { + with(notificationBuilder) { + setContentTitle(context.getString(R.string.picture_saved)) + setSmallIcon(R.drawable.ic_insert_photo_white_24dp) + setStyle(NotificationCompat.BigPictureStyle().bigPicture(image)) + setLargeIcon(image) + setAutoCancel(true) + // Clear old actions if they exist + if (!mActions.isEmpty()) + mActions.clear() + + setContentIntent(ImageNotificationReceiver.showImageIntent(context, file.absolutePath)) + // Share action + addAction(R.drawable.ic_share_grey_24dp, + context.getString(R.string.action_share), + ImageNotificationReceiver.shareImageIntent(context, file.absolutePath, notificationId)) + // Delete action + addAction(R.drawable.ic_delete_grey_24dp, + context.getString(R.string.action_delete), + ImageNotificationReceiver.deleteImageIntent(context, file.absolutePath, notificationId)) + updateNotification() + + } + } + + /** + * Clears the notification message + */ + fun onClear() { + context.notificationManager.cancel(notificationId) + } + + private fun updateNotification() { + // Displays the progress bar on notification + context.notificationManager.notify(notificationId, notificationBuilder.build()) + } + + + /** + * Called on error while downloading image + * @param error string containing error information + */ + fun onError(error: String?) { + // Create notification + with(notificationBuilder) { + setContentTitle(context.getString(R.string.download_notifier_title_error)) + setContentText(error ?: context.getString(R.string.unknown_error)) + setSmallIcon(android.R.drawable.ic_menu_report_image) + } + updateNotification() + } + +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReader.kt index 6d9a4bb63d..18cf1501c3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReader.kt @@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.ui.reader.ReaderChapter import eu.kanade.tachiyomi.ui.reader.viewer.base.BaseReader import eu.kanade.tachiyomi.ui.reader.viewer.pager.horizontal.LeftToRightReader import eu.kanade.tachiyomi.ui.reader.viewer.pager.horizontal.RightToLeftReader +import eu.kanade.tachiyomi.util.toast import rx.subscriptions.CompositeSubscription /** @@ -185,6 +186,16 @@ abstract class PagerReader : BaseReader() { } return true } + + override fun onLongPress(e: MotionEvent?) { + if (isAdded) { + val page = adapter.pages.getOrNull(pager.currentItem) + if (page != null) + readerActivity.onLongPress(page) + else + context.toast(getString(R.string.unknown_error)) + } + } }) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonReader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonReader.kt index f08eecd551..41fb2ac0a9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonReader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonReader.kt @@ -6,9 +6,11 @@ import android.view.* import android.view.GestureDetector.SimpleOnGestureListener import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.ViewGroup.LayoutParams.WRAP_CONTENT +import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.source.model.Page import eu.kanade.tachiyomi.ui.reader.ReaderChapter import eu.kanade.tachiyomi.ui.reader.viewer.base.BaseReader +import eu.kanade.tachiyomi.util.toast import eu.kanade.tachiyomi.widget.PreCachingLayoutManager import rx.subscriptions.CompositeSubscription @@ -140,12 +142,23 @@ class WebtoonReader : BaseReader() { } return true } + + override fun onLongPress(e: MotionEvent) { + if (isAdded) { + val child = recycler.findChildViewUnder(e.rawX, e.rawY) + val position = recycler.getChildAdapterPosition(child) + val page = adapter.pages?.getOrNull(position) + if (page != null) + readerActivity.onLongPress(page) + else + context.toast(getString(R.string.unknown_error)) + } + } }) } /** * Called when a new chapter is set in [BaseReader]. - * * @param chapter the chapter set. * @param currentPage the initial page to display. */ @@ -160,7 +173,6 @@ class WebtoonReader : BaseReader() { /** * Called when a chapter is appended in [BaseReader]. - * * @param chapter the chapter appended. */ override fun onChapterAppended(chapter: ReaderChapter) { @@ -184,7 +196,6 @@ class WebtoonReader : BaseReader() { /** * Sets the active page. - * * @param pageNumber the index of the page from [pages]. */ override fun setActivePage(pageNumber: Int) { diff --git a/app/src/main/res/drawable-hdpi/ic_delete_grey_24dp.png b/app/src/main/res/drawable-hdpi/ic_delete_grey_24dp.png new file mode 100644 index 0000000000..13d2741f36 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_delete_grey_24dp.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_insert_photo_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_insert_photo_white_24dp.png new file mode 100644 index 0000000000..25a9576ddd Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_insert_photo_white_24dp.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_share_grey_24dp.png b/app/src/main/res/drawable-hdpi/ic_share_grey_24dp.png new file mode 100644 index 0000000000..c0b2a80e96 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_share_grey_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_delete_grey_24dp.png b/app/src/main/res/drawable-mdpi/ic_delete_grey_24dp.png new file mode 100644 index 0000000000..a0df896860 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_delete_grey_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_insert_photo_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_insert_photo_white_24dp.png new file mode 100644 index 0000000000..d474bd577d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_insert_photo_white_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_share_grey_24dp.png b/app/src/main/res/drawable-mdpi/ic_share_grey_24dp.png new file mode 100644 index 0000000000..e2814bdc98 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_share_grey_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_delete_grey_24dp.png b/app/src/main/res/drawable-xhdpi/ic_delete_grey_24dp.png new file mode 100644 index 0000000000..4ca7f7c9ad Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_delete_grey_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_insert_photo_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_insert_photo_white_24dp.png new file mode 100644 index 0000000000..2642b9e09e Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_insert_photo_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_share_grey_24dp.png b/app/src/main/res/drawable-xhdpi/ic_share_grey_24dp.png new file mode 100644 index 0000000000..f691067f71 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_share_grey_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_delete_grey_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_delete_grey_24dp.png new file mode 100644 index 0000000000..209e555eea Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_delete_grey_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_insert_photo_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_insert_photo_white_24dp.png new file mode 100644 index 0000000000..f9f1defa6d Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_insert_photo_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_share_grey_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_share_grey_24dp.png new file mode 100644 index 0000000000..9ed5b4d432 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_share_grey_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_delete_grey_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_delete_grey_24dp.png new file mode 100644 index 0000000000..a1b86d06e8 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_delete_grey_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_insert_photo_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_insert_photo_white_24dp.png new file mode 100644 index 0000000000..2ffdb55f26 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_insert_photo_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_share_grey_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_share_grey_24dp.png new file mode 100644 index 0000000000..35b1664aa7 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_share_grey_24dp.png differ diff --git a/app/src/main/res/drawable/ic_insert_photo_white_24dp.png b/app/src/main/res/drawable/ic_insert_photo_white_24dp.png new file mode 100644 index 0000000000..d474bd577d Binary files /dev/null and b/app/src/main/res/drawable/ic_insert_photo_white_24dp.png differ diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 100ebec7f6..6e644174da 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -176,4 +176,16 @@ 3 + + @string/set_as_cover + @string/action_share + @string/action_save + + + + 0 + 1 + 2 + + \ No newline at end of file diff --git a/app/src/main/res/values/keys.xml b/app/src/main/res/values/keys.xml index ad8de7baab..f3694dc7ad 100644 --- a/app/src/main/res/values/keys.xml +++ b/app/src/main/res/values/keys.xml @@ -48,7 +48,6 @@ pref_download_only_over_wifi_key pref_remove_after_marked_as_read_key pref_category_remove_after_read_key - last_used_category pref_source_languages diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b6e9bdb3a6..aff0608169 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -62,6 +62,7 @@ Sort Install Share + Save Deleting… @@ -224,7 +225,6 @@ Status Source Genres - Share… Check out %1$s! at %2$s Circular icon Rounded icon @@ -272,9 +272,16 @@ This will remove the read date of this chapter. Are you sure? Reset all chapters for this manga + + Picture saved + Saving picture + Options Custom filter + Set as cover + Cover updated + Page copied to %1$s Downloading… Downloaded %1$d%% Page: %1$d @@ -305,6 +312,7 @@ No new chapters found New chapters found for: Failed to update manga: + Failed to update cover Please add the manga to your library before doing this Sync canceled Not connected to AC power diff --git a/app/src/main/res/xml/provider_paths.xml b/app/src/main/res/xml/provider_paths.xml new file mode 100644 index 0000000000..5817df3bcb --- /dev/null +++ b/app/src/main/res/xml/provider_paths.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 5995e49e83..319ddb2e7d 100644 --- a/build.gradle +++ b/build.gradle @@ -18,4 +18,4 @@ allprojects { jcenter() maven { url "https://jitpack.io" } } -} \ No newline at end of file +}