Add chapter deeplink, make MangaDex use it

This commit is contained in:
Jobobby04 2020-12-26 16:13:55 -05:00
parent 1a609e557b
commit e078e34ab0
6 changed files with 95 additions and 8 deletions

View File

@ -340,6 +340,23 @@
android:scheme="https" android:scheme="https"
android:host="www.mangadex.cc" android:host="www.mangadex.cc"
android:pathPrefix="/title/" /> android:pathPrefix="/title/" />
<data
android:scheme="https"
android:host="www.mangadex.org"
android:pathPrefix="/chapter/" />
<data
android:scheme="https"
android:host="mangadex.org"
android:pathPrefix="/chapter/" />
<data
android:scheme="https"
android:host="www.mangadex.cc"
android:pathPrefix="/chapter/" />
<data
android:scheme="https"
android:host="www.mangadex.cc"
android:pathPrefix="/chapter/" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity

View File

@ -12,6 +12,10 @@ interface UrlImportableSource : Source {
return uri.host.orEmpty().toLowerCase() in matchingHosts return uri.host.orEmpty().toLowerCase() in matchingHosts
} }
fun mapUrlToChapterUrl(uri: Uri): String? = null
suspend fun mapChapterUrlToMangaUrl(uri: Uri): String? = null
// This method is allowed to block for IO if necessary // This method is allowed to block for IO if necessary
suspend fun mapUrlToMangaUrl(uri: Uri): String? suspend fun mapUrlToMangaUrl(uri: Uri): String?
@ -30,4 +34,20 @@ interface UrlImportableSource : Source {
url url
} }
} }
fun cleanChapterUrl(url: String): String {
return try {
val uri = URI(url)
var out = uri.path
if (uri.query != null) {
out += "?" + uri.query
}
if (uri.fragment != null) {
out += "#" + uri.fragment
}
out
} catch (e: URISyntaxException) {
url
}
}
} }

View File

@ -110,6 +110,18 @@ class MangaDex(delegate: HttpSource, val context: Context) :
} }
} }
override fun mapUrlToChapterUrl(uri: Uri): String? {
if (!uri.pathSegments.firstOrNull().equals("chapter", true)) return null
val id = uri.pathSegments.getOrNull(1) ?: return null
return MdUtil.apiChapter + id
}
override suspend fun mapChapterUrlToMangaUrl(uri: Uri): String? {
val id = uri.pathSegments.getOrNull(2) ?: return null
val mangaId = MangaHandler(client, headers, listOf(mdLang)).getMangaIdFromChapterId(id)
return MdUtil.mapMdIdToMangaUrl(mangaId)
}
override fun fetchMangaDetails(manga: SManga): Observable<SManga> { override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
return MangaHandler(client, headers, listOf(mdLang), preferences.mangaDexForceLatestCovers().get()).fetchMangaDetailsObservable(manga) return MangaHandler(client, headers, listOf(mdLang), preferences.mangaDexForceLatestCovers().get()).fetchMangaDetailsObservable(manga)
} }

View File

@ -79,9 +79,29 @@ class GalleryAdder {
} ?: return GalleryAddEvent.Fail.UnknownType(url, context) } ?: return GalleryAddEvent.Fail.UnknownType(url, context)
} }
val realChapterUrl = try {
source.mapUrlToChapterUrl(uri)
} catch (e: Exception) {
logger.e(context.getString(R.string.gallery_adder_uri_map_to_chapter_error), e)
null
}
val cleanedChapterUrl = if (realChapterUrl != null) {
try {
source.cleanChapterUrl(realChapterUrl)
} catch (e: Exception) {
logger.e(context.getString(R.string.gallery_adder_uri_clean_error), e)
null
}
} else null
val chapterMangaUrl = if (realChapterUrl != null) {
source.mapChapterUrlToMangaUrl(realChapterUrl.toUri())
} else null
// Map URL to manga URL // Map URL to manga URL
val realMangaUrl = try { val realMangaUrl = try {
source.mapUrlToMangaUrl(uri) chapterMangaUrl ?: source.mapUrlToMangaUrl(uri)
} catch (e: Exception) { } catch (e: Exception) {
logger.e(context.getString(R.string.gallery_adder_uri_map_to_manga_error), e) logger.e(context.getString(R.string.gallery_adder_uri_map_to_manga_error), e)
null null
@ -139,7 +159,16 @@ class GalleryAdder {
return GalleryAddEvent.Fail.Error(url, context.getString(R.string.gallery_adder_chapter_fetch_error, url)) return GalleryAddEvent.Fail.Error(url, context.getString(R.string.gallery_adder_chapter_fetch_error, url))
} }
return GalleryAddEvent.Success(url, manga, context) return if (cleanedChapterUrl != null) {
val chapter = db.getChapter(cleanedChapterUrl, manga.id!!).executeOnIO()
if (chapter != null) {
GalleryAddEvent.Success(url, manga, context, chapter)
} else {
GalleryAddEvent.Fail.Error(url, context.getString(R.string.gallery_adder_could_not_identify_chapter, url))
}
} else {
GalleryAddEvent.Success(url, manga, context)
}
} catch (e: Exception) { } catch (e: Exception) {
logger.w(context.getString(R.string.gallery_adder_could_not_add_manga, url), e) logger.w(context.getString(R.string.gallery_adder_could_not_add_manga, url), e)

View File

@ -9,11 +9,14 @@ import com.afollestad.materialdialogs.callbacks.onCancel
import com.afollestad.materialdialogs.callbacks.onDismiss import com.afollestad.materialdialogs.callbacks.onDismiss
import com.afollestad.materialdialogs.list.listItemsSingleChoice import com.afollestad.materialdialogs.list.listItemsSingleChoice
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.databinding.EhActivityInterceptBinding import eu.kanade.tachiyomi.databinding.EhActivityInterceptBinding
import eu.kanade.tachiyomi.source.online.UrlImportableSource import eu.kanade.tachiyomi.source.online.UrlImportableSource
import eu.kanade.tachiyomi.ui.base.activity.BaseViewBindingActivity import eu.kanade.tachiyomi.ui.base.activity.BaseViewBindingActivity
import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import exh.GalleryAddEvent import exh.GalleryAddEvent
import exh.GalleryAdder import exh.GalleryAdder
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -66,10 +69,14 @@ class InterceptActivity : BaseViewBindingActivity<EhActivityInterceptBinding>()
binding.interceptStatus.setText(R.string.launching_app) binding.interceptStatus.setText(R.string.launching_app)
onBackPressed() onBackPressed()
startActivity( startActivity(
Intent(this, MainActivity::class.java) if (it.chapter != null) {
.setAction(MainActivity.SHORTCUT_MANGA) ReaderActivity.newIntent(this, it.manga, it.chapter)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) } else {
.putExtra(MangaController.MANGA_EXTRA, it.mangaId) Intent(this, MainActivity::class.java)
.setAction(MainActivity.SHORTCUT_MANGA)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
.putExtra(MangaController.MANGA_EXTRA, it.mangaId)
}
) )
} }
is InterceptResult.Failure -> { is InterceptResult.Failure -> {
@ -126,7 +133,7 @@ class InterceptActivity : BaseViewBindingActivity<EhActivityInterceptBinding>()
status.value = when (result) { status.value = when (result) {
is GalleryAddEvent.Success -> result.manga.id?.let { is GalleryAddEvent.Success -> result.manga.id?.let {
InterceptResult.Success(it) InterceptResult.Success(it, result.manga, result.chapter)
} ?: InterceptResult.Failure(this@InterceptActivity.getString(R.string.manga_id_is_null)) } ?: InterceptResult.Failure(this@InterceptActivity.getString(R.string.manga_id_is_null))
is GalleryAddEvent.Fail -> InterceptResult.Failure(result.logMessage) is GalleryAddEvent.Fail -> InterceptResult.Failure(result.logMessage)
} }
@ -137,6 +144,6 @@ class InterceptActivity : BaseViewBindingActivity<EhActivityInterceptBinding>()
sealed class InterceptResult { sealed class InterceptResult {
object Idle : InterceptResult() object Idle : InterceptResult()
object Loading : InterceptResult() object Loading : InterceptResult()
data class Success(val mangaId: Long) : InterceptResult() data class Success(val mangaId: Long, val manga: Manga, val chapter: Chapter? = null) : InterceptResult()
data class Failure(val reason: String) : InterceptResult() data class Failure(val reason: String) : InterceptResult()
} }

View File

@ -437,9 +437,11 @@
<string name="gallery_adder_importing_manga">Importing manga (url: %1$s, fav: %2$s, forceSource: %3$s)…</string> <string name="gallery_adder_importing_manga">Importing manga (url: %1$s, fav: %2$s, forceSource: %3$s)…</string>
<string name="gallery_adder_source_uri_must_match">Source URI match check error!</string> <string name="gallery_adder_source_uri_must_match">Source URI match check error!</string>
<string name="gallery_adder_uri_map_to_manga_error">Source URI map-to-manga error!</string> <string name="gallery_adder_uri_map_to_manga_error">Source URI map-to-manga error!</string>
<string name="gallery_adder_uri_map_to_chapter_error">Source URI map-to-chapter error!</string>
<string name="gallery_adder_uri_clean_error">Source URI clean error!</string> <string name="gallery_adder_uri_clean_error">Source URI clean error!</string>
<string name="gallery_adder_chapter_fetch_error">Failed to update chapters for manga: %1$s!</string> <string name="gallery_adder_chapter_fetch_error">Failed to update chapters for manga: %1$s!</string>
<string name="gallery_adder_could_not_add_manga">Could not add manga (url: %1$s)!</string> <string name="gallery_adder_could_not_add_manga">Could not add manga (url: %1$s)!</string>
<string name="gallery_adder_could_not_identify_chapter">Could not identify chapter (url: %1$s)!</string>
<!-- Intercept Activity --> <!-- Intercept Activity -->
<string name="launching_app">Launching app…</string> <string name="launching_app">Launching app…</string>