Reader seekbar back to ignoring gestures

Sharesheet update:
Now shows a preview of images shared, a preview of the manga you're sharing on android 10
Sharing via the saved image notification now shows the share sheet
This commit is contained in:
Jay 2019-11-02 21:43:15 -07:00
parent fee4328ad0
commit d263f03cc7
5 changed files with 100 additions and 23 deletions

View File

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.data.notification
import android.app.Notification
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.ClipData
import android.content.Context
import android.content.Intent
import android.os.Handler
@ -86,12 +87,16 @@ class NotificationReceiver : BroadcastReceiver() {
val uri = File(path).getUriCompat(context)
putExtra(Intent.EXTRA_STREAM, uri)
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
clipData = ClipData.newRawUri(null, uri)
type = "image/*"
}
// Dismiss notification
dismissNotification(context, notificationId)
// Close Navigation Shade
context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
// Launch share activity
context.startActivity(intent)
val shareIntent = Intent.createChooser(intent, context.getString(R.string
.action_share))
shareIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
context.startActivity(shareIntent)
}
/**
@ -106,8 +111,7 @@ class NotificationReceiver : BroadcastReceiver() {
val db = DatabaseHelper(context)
val manga = db.getManga(mangaId).executeAsBlocking()
val chapter = db.getChapter(chapterId).executeAsBlocking()
val it = Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
context.sendBroadcast(it)
context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
if (manga != null && chapter != null) {
val intent = ReaderActivity.newIntent(context, manga, chapter).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP

View File

@ -20,6 +20,7 @@ import android.widget.Toast
import com.afollestad.materialdialogs.MaterialDialog
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.transition.Transition
import com.jakewharton.rxbinding.support.v4.widget.refreshes
@ -46,6 +47,7 @@ import jp.wasabeef.glide.transformations.CropSquareTransformation
import jp.wasabeef.glide.transformations.MaskTransformation
import kotlinx.android.synthetic.main.manga_info_controller.*
import uy.kohesive.injekt.injectLazy
import java.io.File
import java.text.DateFormat
import java.text.DecimalFormat
import java.util.Date
@ -161,7 +163,7 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
when (item.itemId) {
R.id.action_open_in_browser -> openInBrowser()
R.id.action_open_in_web_view -> openInWebView()
R.id.action_share -> shareManga()
R.id.action_share -> prepareToShareManga()
R.id.action_add_to_home_screen -> addToHomeScreen()
else -> return super.onOptionsItemSelected(item)
}
@ -325,15 +327,40 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
/**
* Called to run Intent with [Intent.ACTION_SEND], which show share dialog.
*/
private fun shareManga() {
private fun prepareToShareManga() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
GlideApp.with(activity!!).asBitmap().load(presenter.manga).into(object :
CustomTarget<Bitmap>() {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
presenter.shareManga(resource)
}
override fun onLoadCleared(placeholder: Drawable?) {}
override fun onLoadFailed(errorDrawable: Drawable?) {
shareManga()
}
})
else shareManga()
}
/**
* Called to run Intent with [Intent.ACTION_SEND], which show share dialog.
*/
fun shareManga(cover: File? = null) {
val context = view?.context ?: return
val source = presenter.source as? HttpSource ?: return
val stream = cover?.getUriCompat(context)
try {
val url = source.mangaDetailsRequest(presenter.manga).url.toString()
val intent = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
type = "text/*"
putExtra(Intent.EXTRA_TEXT, url)
putExtra(Intent.EXTRA_TITLE, presenter.manga.title)
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
if (stream != null) {
clipData = ClipData.newRawUri(null, stream)
}
}
startActivity(Intent.createChooser(intent, context.getString(R.string.action_share)))
} catch (e: Exception) {
@ -523,11 +550,13 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
3 -> centerCrop().transform(MaskTransformation(R.drawable.mask_star))
}
}
.into(object : SimpleTarget<Bitmap>(96, 96) {
.into(object : CustomTarget<Bitmap>(96, 96) {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
createShortcut(resource)
}
override fun onLoadCleared(placeholder: Drawable?) { }
override fun onLoadFailed(errorDrawable: Drawable?) {
activity?.toast(R.string.icon_creation_fail)
}

View File

@ -1,5 +1,7 @@
package eu.kanade.tachiyomi.ui.manga.info
import android.app.Application
import android.graphics.Bitmap
import android.os.Bundle
import com.jakewharton.rxrelay.BehaviorRelay
import com.jakewharton.rxrelay.PublishRelay
@ -11,6 +13,8 @@ import eu.kanade.tachiyomi.data.database.models.MangaCategory
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.util.DiskUtil
import eu.kanade.tachiyomi.util.ImageUtil
import eu.kanade.tachiyomi.util.isNullOrUnsubscribed
import rx.Observable
import rx.Subscription
@ -18,6 +22,11 @@ import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.InputStream
import java.io.OutputStream
import java.util.*
/**
@ -116,6 +125,35 @@ class MangaInfoPresenter(
toggleFavorite()
}
fun shareManga(cover:Bitmap) {
val context = Injekt.get<Application>()
val destDir = File(context.cacheDir, "shared_image")
Observable.fromCallable { destDir.deleteRecursively() } // Keep only the last shared file
.map { saveImage(cover, destDir, manga) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeFirst(
{ view, file -> view.shareManga(file) },
{ view, error -> view.shareManga() }
)
}
private fun saveImage(cover:Bitmap, directory: File, manga: Manga): File? {
directory.mkdirs()
// Build destination file.
val filename = DiskUtil.buildValidFilename("${manga.title} - Cover.jpg")
val destFile = File(directory, filename)
val stream: OutputStream = FileOutputStream(destFile)
cover.compress(Bitmap.CompressFormat.JPEG,75,stream)
stream.flush()
stream.close()
return destFile
}
/**
* Get the default, and user categories.
*

View File

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.reader
import android.annotation.SuppressLint
import android.app.ProgressDialog
import android.content.ClipData
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
@ -156,17 +157,6 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>(),
config = ReaderConfig()
initializeMenu()
val container: ViewGroup = findViewById(R.id.reader_container)
val readerBHeight = reader_menu_bottom.layoutParams.height
container.doOnApplyWindowInsets { _, insets, padding ->
val bottomInset = if (Build.VERSION.SDK_INT >= 29)
(insets.mandatorySystemGestureInsets.bottom - insets.systemWindowInsetBottom)
else 0
reader_menu_bottom.updateLayoutParams<ViewGroup.MarginLayoutParams> {
height = readerBHeight + bottomInset
}
reader_menu_bottom.updatePaddingRelative(bottom = padding.bottom + bottomInset)
}
}
/**
@ -312,6 +302,9 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>(),
systemUi?.show()
reader_menu.visibility = View.VISIBLE
reader_menu_bottom.visibility = View.VISIBLE
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
window.navigationBarColor = getResourceColor(R.attr.colorPrimaryDark)
}
if (animate) {
if (!menuStickyVisible) {
val toolbarAnimation = AnimationUtils.loadAnimation(this, R.anim.enter_from_top)
@ -513,6 +506,7 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>(),
val intent = Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_STREAM, stream)
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
clipData = ClipData.newRawUri(null, stream)
type = "image/*"
}
startActivity(Intent.createChooser(intent, getString(R.string.action_share)))
@ -570,6 +564,9 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>(),
setMenuVisibility(false)
menuStickyVisible = false
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
window.navigationBarColor = getColor(android.R.color.transparent)
}
reader_menu_bottom.visibility = View.GONE
reader_menu.visibility = View.VISIBLE
val toolbarAnimation = AnimationUtils.loadAnimation(this, R.anim.enter_from_top)
@ -579,9 +576,6 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>(),
}
})
toolbar.startAnimation(toolbarAnimation)
/*val bottomAnimation = AnimationUtils.loadAnimation(this, R.anim
.enter_from_bottom)
reader_menu_bottom.startAnimation(bottomAnimation)*/
}
}
else {

View File

@ -20,6 +20,8 @@ class ReaderSeekBar @JvmOverloads constructor(
* Whether the seekbar should draw from right to left.
*/
var isRTL = false
private val boundingBox: Rect = Rect()
private val exclusions = listOf(boundingBox)
/**
* Draws the seekbar, translating the canvas if using a right to left reader.
@ -43,4 +45,14 @@ class ReaderSeekBar @JvmOverloads constructor(
}
return super.onTouchEvent(event)
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
if (Build.VERSION.SDK_INT >= 29) {
if (changed) {
boundingBox.set(left, top, right, bottom)
systemGestureExclusionRects = exclusions
}
}
}
}