Improve manga link sharing
This commit is contained in:
@@ -6,6 +6,7 @@ import android.text.SpannableStringBuilder
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.collection.MutableObjectIntMap
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import androidx.core.text.buildSpannedString
|
||||
import androidx.core.text.strikeThrough
|
||||
@@ -125,7 +126,8 @@ val Manga.isBroken: Boolean
|
||||
get() = source == UnknownMangaSource
|
||||
|
||||
val Manga.appUrl: Uri
|
||||
get() = Uri.parse("https://kotatsu.app/manga").buildUpon()
|
||||
get() = "https://kotatsu.app/manga".toUri()
|
||||
.buildUpon()
|
||||
.appendQueryParameter("source", source.name)
|
||||
.appendQueryParameter("name", title)
|
||||
.appendQueryParameter("url", url)
|
||||
|
||||
@@ -12,6 +12,8 @@ import android.provider.Settings
|
||||
import android.view.View
|
||||
import androidx.annotation.CheckResult
|
||||
import androidx.annotation.UiContext
|
||||
import androidx.core.app.ShareCompat
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.core.net.toUri
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.Fragment
|
||||
@@ -29,7 +31,10 @@ import org.koitharu.kotatsu.browser.cloudflare.CloudFlareActivity
|
||||
import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.core.model.MangaSourceInfo
|
||||
import org.koitharu.kotatsu.core.model.appUrl
|
||||
import org.koitharu.kotatsu.core.model.getTitle
|
||||
import org.koitharu.kotatsu.core.model.isBroken
|
||||
import org.koitharu.kotatsu.core.model.isLocal
|
||||
import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
|
||||
import org.koitharu.kotatsu.core.model.parcelable.ParcelableMangaListFilter
|
||||
import org.koitharu.kotatsu.core.model.parcelable.ParcelableMangaPage
|
||||
@@ -43,6 +48,8 @@ import org.koitharu.kotatsu.core.ui.dialog.ErrorDetailsDialog
|
||||
import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog
|
||||
import org.koitharu.kotatsu.core.util.ext.connectivityManager
|
||||
import org.koitharu.kotatsu.core.util.ext.findActivity
|
||||
import org.koitharu.kotatsu.core.util.ext.getThemeDrawable
|
||||
import org.koitharu.kotatsu.core.util.ext.toFileOrNull
|
||||
import org.koitharu.kotatsu.core.util.ext.toUriOrNull
|
||||
import org.koitharu.kotatsu.core.util.ext.withArgs
|
||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||
@@ -72,6 +79,7 @@ import org.koitharu.kotatsu.parsers.model.MangaPage
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.util.ellipsize
|
||||
import org.koitharu.kotatsu.parsers.util.isNullOrEmpty
|
||||
import org.koitharu.kotatsu.parsers.util.mapToArray
|
||||
import org.koitharu.kotatsu.reader.ui.colorfilter.ColorFilterConfigActivity
|
||||
@@ -96,6 +104,8 @@ import org.koitharu.kotatsu.stats.ui.StatsActivity
|
||||
import org.koitharu.kotatsu.stats.ui.sheet.MangaStatsSheet
|
||||
import org.koitharu.kotatsu.suggestions.ui.SuggestionsActivity
|
||||
import org.koitharu.kotatsu.tracker.ui.updates.UpdatesActivity
|
||||
import java.io.File
|
||||
import com.google.android.material.R as materialR
|
||||
|
||||
class AppRouter private constructor(
|
||||
private val activity: FragmentActivity?,
|
||||
@@ -391,6 +401,37 @@ class AppRouter private constructor(
|
||||
}.show()
|
||||
}
|
||||
|
||||
fun showShareDialog(manga: Manga) {
|
||||
if (manga.isBroken) {
|
||||
return
|
||||
}
|
||||
if (manga.isLocal) {
|
||||
manga.url.toUri().toFileOrNull()?.let {
|
||||
shareFile(it)
|
||||
}
|
||||
return
|
||||
}
|
||||
buildAlertDialog(contextOrNull() ?: return) {
|
||||
setIcon(context.getThemeDrawable(materialR.attr.actionModeShareDrawable))
|
||||
setTitle(R.string.share)
|
||||
setItems(
|
||||
arrayOf(
|
||||
context.getString(R.string.link_to_manga_in_app),
|
||||
context.getString(R.string.link_to_manga_on_s, manga.source.getTitle(context)),
|
||||
),
|
||||
) { _, which ->
|
||||
val link = when (which) {
|
||||
0 -> manga.appUrl.toString()
|
||||
1 -> manga.publicUrl
|
||||
else -> return@setItems
|
||||
}
|
||||
shareLink(link, manga.title)
|
||||
}
|
||||
setNegativeButton(android.R.string.cancel, null)
|
||||
setCancelable(true)
|
||||
}.show()
|
||||
}
|
||||
|
||||
fun showErrorDialog(error: Throwable, url: String? = null) {
|
||||
ErrorDetailsDialog().withArgs(2) {
|
||||
putSerializable(KEY_ERROR, error)
|
||||
@@ -565,6 +606,25 @@ class AppRouter private constructor(
|
||||
return fragment?.childFragmentManager ?: activity?.supportFragmentManager
|
||||
}
|
||||
|
||||
private fun shareLink(link: String, title: String) {
|
||||
val context = contextOrNull() ?: return
|
||||
ShareCompat.IntentBuilder(context)
|
||||
.setText(link)
|
||||
.setType(TYPE_TEXT)
|
||||
.setChooserTitle(context.getString(R.string.share_s, title.ellipsize(12)))
|
||||
.startChooser()
|
||||
}
|
||||
|
||||
private fun shareFile(file: File) { // TODO directory sharing support
|
||||
val context = contextOrNull() ?: return
|
||||
val intentBuilder = ShareCompat.IntentBuilder(context)
|
||||
.setType(TYPE_CBZ)
|
||||
val uri = FileProvider.getUriForFile(context, "${BuildConfig.APPLICATION_ID}.files", file)
|
||||
intentBuilder.addStream(uri)
|
||||
intentBuilder.setChooserTitle(context.getString(R.string.share_s, file.name))
|
||||
intentBuilder.startChooser()
|
||||
}
|
||||
|
||||
@UiContext
|
||||
private fun contextOrNull(): Context? = activity ?: fragment?.context
|
||||
|
||||
@@ -726,6 +786,10 @@ class AppRouter private constructor(
|
||||
private const val ACTION_ACCOUNT_SYNC_SETTINGS = "android.settings.ACCOUNT_SYNC_SETTINGS"
|
||||
private const val EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":settings:show_fragment_args"
|
||||
|
||||
private const val TYPE_TEXT = "text/plain"
|
||||
private const val TYPE_IMAGE = "image/*"
|
||||
private const val TYPE_CBZ = "application/x-cbz"
|
||||
|
||||
private fun Class<out Fragment>.fragmentTag() = name // TODO
|
||||
|
||||
private inline fun <reified F : Fragment> fragmentTag() = F::class.java.fragmentTag()
|
||||
|
||||
@@ -15,6 +15,7 @@ private const val TYPE_TEXT = "text/plain"
|
||||
private const val TYPE_IMAGE = "image/*"
|
||||
private const val TYPE_CBZ = "application/x-cbz"
|
||||
|
||||
@Deprecated("")
|
||||
class ShareHelper(private val context: Context) {
|
||||
|
||||
fun shareMangaLink(manga: Manga) {
|
||||
|
||||
@@ -5,20 +5,16 @@ import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
import androidx.core.net.toFile
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.LocalMangaSource
|
||||
import org.koitharu.kotatsu.core.model.isLocal
|
||||
import org.koitharu.kotatsu.core.nav.router
|
||||
import org.koitharu.kotatsu.core.os.AppShortcutManager
|
||||
import org.koitharu.kotatsu.core.util.ShareHelper
|
||||
import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog
|
||||
|
||||
class DetailsMenuProvider(
|
||||
private val activity: FragmentActivity,
|
||||
@@ -47,23 +43,16 @@ class DetailsMenuProvider(
|
||||
val manga = viewModel.getMangaOrNull() ?: return false
|
||||
when (menuItem.itemId) {
|
||||
R.id.action_share -> {
|
||||
val shareHelper = ShareHelper(activity)
|
||||
if (manga.isLocal) {
|
||||
shareHelper.shareCbz(listOf(manga.url.toUri().toFile()))
|
||||
} else {
|
||||
shareHelper.shareMangaLink(manga)
|
||||
}
|
||||
activity.router.showShareDialog(manga)
|
||||
}
|
||||
|
||||
R.id.action_delete -> {
|
||||
MaterialAlertDialogBuilder(activity)
|
||||
.setTitle(R.string.delete_manga)
|
||||
.setMessage(activity.getString(R.string.text_delete_local_manga, manga.title))
|
||||
.setPositiveButton(R.string.delete) { _, _ ->
|
||||
viewModel.deleteLocal()
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show()
|
||||
buildAlertDialog(activity) {
|
||||
setTitle(R.string.delete_manga)
|
||||
setMessage(activity.getString(R.string.text_delete_local_manga, manga.title))
|
||||
setPositiveButton(R.string.delete) { _, _ -> viewModel.deleteLocal() }
|
||||
setNegativeButton(android.R.string.cancel, null)
|
||||
}.show()
|
||||
}
|
||||
|
||||
R.id.action_save -> {
|
||||
|
||||
@@ -814,4 +814,6 @@
|
||||
<string name="error_disclaimer_manga">Try to open manga in a web browser to ensure it is available on its source.</string>
|
||||
<string name="error_disclaimer_app_outdated">It looks like your version of Kotatsu is out of date. Please install the latest version to get all available fixes.</string>
|
||||
<string name="error_disclaimer_report">You can submit a bug report to the developers. This will help us investigate and fix the issue.</string>
|
||||
<string name="link_to_manga_on_s">Link to manga on %s</string>
|
||||
<string name="link_to_manga_in_app">Link to manga in Kotatsu</string>
|
||||
</resources>
|
||||
|
||||
@@ -31,7 +31,7 @@ material = "1.13.0-alpha11"
|
||||
moshi = "1.15.2"
|
||||
okhttp = "4.12.0"
|
||||
okio = "3.10.2"
|
||||
parsers = "d5a4cf68c6"
|
||||
parsers = "e83636edc0"
|
||||
preference = "1.2.1"
|
||||
recyclerview = "1.4.0"
|
||||
room = "2.6.1"
|
||||
|
||||
Reference in New Issue
Block a user