[VizShonenJump] Add URL intent for series and chapter links (#16398)
VizShonenJump: Open links in extension
This commit is contained in:
parent
ca87da67a3
commit
ce08808666
|
@ -1,2 +1,25 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest package="eu.kanade.tachiyomi.extension" />
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="eu.kanade.tachiyomi.extension">
|
||||||
|
|
||||||
|
<application>
|
||||||
|
<activity
|
||||||
|
android:name=".en.vizshonenjump.VizUrlActivity"
|
||||||
|
android:excludeFromRecents="true"
|
||||||
|
android:exported="true"
|
||||||
|
android:theme="@android:style/Theme.NoDisplay">
|
||||||
|
<intent-filter android:autoVerify="true">
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
|
<data android:host="www.viz.com" />
|
||||||
|
<data android:scheme="https" />
|
||||||
|
|
||||||
|
<data android:pathPattern="/..*/chapters/..*" />
|
||||||
|
<data android:pathPattern="/..*/..*/chapter/..*" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
|
|
|
@ -6,7 +6,7 @@ ext {
|
||||||
extName = 'VIZ Shonen Jump'
|
extName = 'VIZ Shonen Jump'
|
||||||
pkgNameSuffix = 'en.vizshonenjump'
|
pkgNameSuffix = 'en.vizshonenjump'
|
||||||
extClass = '.VizShonenJump'
|
extClass = '.VizShonenJump'
|
||||||
extVersionCode = 17
|
extVersionCode = 18
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
|
@ -114,6 +114,15 @@ class VizShonenJump : ParsedHttpSource() {
|
||||||
override fun latestUpdatesNextPageSelector(): String? = null
|
override fun latestUpdatesNextPageSelector(): String? = null
|
||||||
|
|
||||||
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
|
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
|
||||||
|
if (query.startsWith(PREFIX_URL_SEARCH)) {
|
||||||
|
return fetchMangaDetails(
|
||||||
|
SManga.create().apply {
|
||||||
|
this.url = query.substringAfter(PREFIX_URL_SEARCH)
|
||||||
|
this.title = ""
|
||||||
|
this.initialized = false
|
||||||
|
},
|
||||||
|
).map { MangasPage(listOf(it), false) }
|
||||||
|
}
|
||||||
return super.fetchSearchManga(page, query, filters)
|
return super.fetchSearchManga(page, query, filters)
|
||||||
.map {
|
.map {
|
||||||
val filteredMangas = it.mangas.filter { m -> m.title.contains(query, true) }
|
val filteredMangas = it.mangas.filter { m -> m.title.contains(query, true) }
|
||||||
|
@ -159,7 +168,17 @@ class VizShonenJump : ParsedHttpSource() {
|
||||||
artist = author
|
artist = author
|
||||||
status = SManga.ONGOING
|
status = SManga.ONGOING
|
||||||
description = seriesIntro.select("div.line-solid").firstOrNull()?.text()
|
description = seriesIntro.select("div.line-solid").firstOrNull()?.text()
|
||||||
thumbnail_url = mangaFromList?.thumbnail_url ?: ""
|
thumbnail_url = if (!mangaFromList?.thumbnail_url.isNullOrEmpty()) {
|
||||||
|
mangaFromList!!.thumbnail_url // Can't be null in this branch
|
||||||
|
} else {
|
||||||
|
document.selectFirst("section.section_chapters td a > img")?.attr("data-original") ?: ""
|
||||||
|
}
|
||||||
|
url = mangaUrl
|
||||||
|
title = if (!mangaFromList?.title.isNullOrEmpty()) {
|
||||||
|
mangaFromList!!.title // Can't be null in this branch
|
||||||
|
} else {
|
||||||
|
seriesIntro.selectFirst("h2.type-lg")?.text() ?: ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,5 +361,7 @@ class VizShonenJump : ParsedHttpSource() {
|
||||||
|
|
||||||
private const val REFRESH_LOGIN_LINKS_URL = "account/refresh_login_links"
|
private const val REFRESH_LOGIN_LINKS_URL = "account/refresh_login_links"
|
||||||
private const val MANGA_AUTH_CHECK_URL = "manga/auth"
|
private const val MANGA_AUTH_CHECK_URL = "manga/auth"
|
||||||
|
|
||||||
|
const val PREFIX_URL_SEARCH = "url:"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
package eu.kanade.tachiyomi.extension.en.vizshonenjump
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.ActivityNotFoundException
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
class VizUrlActivity : Activity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
val pathSegments: List<String>? = intent?.data?.pathSegments
|
||||||
|
if (!pathSegments.isNullOrEmpty() && pathSegments.size >= 3) {
|
||||||
|
// Have to use .equals, otherwise get an error 'Didn't find class "kotlin.jvm.internal.Intrinsics"'
|
||||||
|
val seriesSlug = if (pathSegments[2].equals("chapter") && contains(pathSegments[1], "-chapter-")) {
|
||||||
|
substringBeforeLast(pathSegments[1], "-chapter-")
|
||||||
|
} else {
|
||||||
|
pathSegments[2]
|
||||||
|
}
|
||||||
|
val mainIntent = Intent().apply {
|
||||||
|
action = "eu.kanade.tachiyomi.SEARCH"
|
||||||
|
putExtra(
|
||||||
|
"query",
|
||||||
|
"${VizShonenJump.PREFIX_URL_SEARCH}/${pathSegments[0]}/chapters/$seriesSlug",
|
||||||
|
)
|
||||||
|
putExtra("filter", packageName)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
startActivity(mainIntent)
|
||||||
|
} catch (e: ActivityNotFoundException) {
|
||||||
|
Log.e("VizUrlActivity", "failed to start activity with error: $e")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.e("VizUrlActivity", "could not parse uri from intent $intent")
|
||||||
|
}
|
||||||
|
|
||||||
|
finish()
|
||||||
|
exitProcess(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun containsAt(haystack: String, startIndex: Int, needle: String): Boolean {
|
||||||
|
for (i in 0 until needle.length) {
|
||||||
|
if (needle[i] != haystack[startIndex + i]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun contains(haystack: String, needle: String): Boolean {
|
||||||
|
if (needle.length > haystack.length) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for (startIndex in 0..haystack.length - needle.length) {
|
||||||
|
if (containsAt(haystack, startIndex, needle)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun substringBeforeLast(haystack: String, needle: String): String {
|
||||||
|
if (needle.length > haystack.length) {
|
||||||
|
return haystack
|
||||||
|
}
|
||||||
|
for (startIndex in (haystack.length - needle.length) downTo 0) {
|
||||||
|
if (containsAt(haystack, startIndex, needle)) {
|
||||||
|
return haystack.subSequence(0, startIndex).toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return haystack
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue