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:
parent
fee4328ad0
commit
d263f03cc7
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user