Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
197393fbd1 | ||
|
|
51ef6e3c78 | ||
|
|
663277fe6f | ||
|
|
332a38d674 | ||
|
|
e9410a2f54 | ||
|
|
b5fa2bd660 |
@@ -13,8 +13,8 @@ android {
|
||||
applicationId 'org.koitharu.kotatsu'
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 31
|
||||
versionCode 377
|
||||
versionName '2.1.1'
|
||||
versionCode 378
|
||||
versionName '2.1.2'
|
||||
generatedDensities = []
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
|
||||
@@ -171,12 +171,11 @@ class MangaDexRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposit
|
||||
|
||||
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
||||
val domain = getDomain()
|
||||
val attrs = loaderContext.httpGet("https://api.$domain/chapter/${chapter.url}")
|
||||
val chapter = loaderContext.httpGet("https://api.$domain/at-home/server/${chapter.url}?forcePort443=false")
|
||||
.parseJson()
|
||||
.getJSONObject("data")
|
||||
.getJSONObject("attributes")
|
||||
val pages = attrs.getJSONArray("pages")
|
||||
val prefix = "https://uploads.$domain/data/${attrs.getString("hash")}/"
|
||||
.getJSONObject("chapter")
|
||||
val pages = chapter.getJSONArray("data")
|
||||
val prefix = "https://uploads.$domain/data/${chapter.getString("hash")}/"
|
||||
val referer = "https://$domain/"
|
||||
return List(pages.length()) { i ->
|
||||
val url = prefix + pages.getString(i)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.koitharu.kotatsu.core.parser.site
|
||||
|
||||
import android.util.Base64
|
||||
import org.koitharu.kotatsu.base.domain.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.core.exceptions.ParseException
|
||||
import org.koitharu.kotatsu.core.model.*
|
||||
@@ -75,6 +76,10 @@ class MangaOwlRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposit
|
||||
val info = doc.body().selectFirst("div.single_detail") ?: parseFailed("An error occurred while parsing")
|
||||
val table = doc.body().selectFirst("div.single-grid-right") ?: parseFailed("An error occurred while parsing")
|
||||
val dateFormat = SimpleDateFormat("MM/dd/yyyy", Locale.US)
|
||||
val trRegex = "window\\['tr'] = '([^']*)';".toRegex(RegexOption.IGNORE_CASE)
|
||||
val trElement = doc.getElementsByTag("script").find { trRegex.find(it.data()) != null } ?: parseFailed("Oops, tr not found")
|
||||
val tr = trRegex.find(trElement.data())!!.groups[1]!!.value
|
||||
val s = Base64.encodeToString(defaultDomain.toByteArray(), Base64.NO_PADDING)
|
||||
return manga.copy(
|
||||
description = info.selectFirst(".description")?.html(),
|
||||
largeCoverUrl = info.select("img").first()?.let { img ->
|
||||
@@ -100,7 +105,7 @@ class MangaOwlRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposit
|
||||
id = generateUid(href),
|
||||
name = a.select("label").text(),
|
||||
number = i + 1,
|
||||
url = href,
|
||||
url = "$href?tr=$tr&s=$s",
|
||||
scanlator = null,
|
||||
branch = null,
|
||||
uploadDate = dateFormat.tryParse(li.selectFirst("small:last-of-type")?.text()),
|
||||
@@ -120,7 +125,7 @@ class MangaOwlRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposit
|
||||
id = generateUid(url),
|
||||
url = url,
|
||||
preview = null,
|
||||
referer = fullUrl,
|
||||
referer = url,
|
||||
source = MangaSource.MANGAOWL,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
package org.koitharu.kotatsu.reader.ui.pager.webtoon
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.graphics.PointF
|
||||
import android.util.AttributeSet
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
import org.koitharu.kotatsu.utils.ext.toIntUp
|
||||
|
||||
class WebtoonImageView @JvmOverloads constructor(context: Context, attr: AttributeSet? = null) :
|
||||
SubsamplingScaleImageView(context, attr) {
|
||||
class WebtoonImageView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attr: AttributeSet? = null,
|
||||
) : SubsamplingScaleImageView(context, attr) {
|
||||
|
||||
private val ct = PointF()
|
||||
private val displayHeight = resources.displayMetrics.heightPixels
|
||||
private val displayHeight = (context as Activity).window.decorView.height
|
||||
|
||||
private var scrollPos = 0
|
||||
private var scrollRange = SCROLL_UNKNOWN
|
||||
@@ -55,6 +58,30 @@ class WebtoonImageView @JvmOverloads constructor(context: Context, attr: Attribu
|
||||
return desiredHeight
|
||||
}
|
||||
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
val widthSpecMode = MeasureSpec.getMode(widthMeasureSpec)
|
||||
val heightSpecMode = MeasureSpec.getMode(heightMeasureSpec)
|
||||
val parentWidth = MeasureSpec.getSize(widthMeasureSpec)
|
||||
val parentHeight = MeasureSpec.getSize(heightMeasureSpec)
|
||||
val resizeWidth = widthSpecMode != MeasureSpec.EXACTLY
|
||||
val resizeHeight = heightSpecMode != MeasureSpec.EXACTLY
|
||||
var width = parentWidth
|
||||
var height = parentHeight
|
||||
if (sWidth > 0 && sHeight > 0) {
|
||||
if (resizeWidth && resizeHeight) {
|
||||
width = sWidth
|
||||
height = sHeight
|
||||
} else if (resizeHeight) {
|
||||
height = (sHeight.toDouble() / sWidth.toDouble() * width).toInt()
|
||||
} else if (resizeWidth) {
|
||||
width = (sWidth.toDouble() / sHeight.toDouble() * height).toInt()
|
||||
}
|
||||
}
|
||||
width = width.coerceAtLeast(suggestedMinimumWidth)
|
||||
height = height.coerceIn(suggestedMinimumHeight, displayHeight)
|
||||
setMeasuredDimension(width, height)
|
||||
}
|
||||
|
||||
private fun scrollToInternal(pos: Int) {
|
||||
scrollPos = pos
|
||||
ct.set(sWidth / 2f, (height / 2f + pos.toFloat()) / minScale)
|
||||
|
||||
@@ -34,7 +34,7 @@ class WebtoonRecyclerView @JvmOverloads constructor(
|
||||
consumed[0] = 0
|
||||
consumed[1] = consumedY
|
||||
}
|
||||
return consumedY != 0
|
||||
return consumedY != 0 || dy == 0
|
||||
}
|
||||
|
||||
private fun consumeVerticalScroll(dy: Int): Int {
|
||||
|
||||
@@ -246,4 +246,7 @@
|
||||
<string name="system_default">Standard</string>
|
||||
<string name="exclude_nsfw_from_history">NSFW-Manga aus dem Verlauf ausschließen</string>
|
||||
<string name="error_empty_name">Der Name sollte nicht leer sein</string>
|
||||
<string name="show_pages_numbers">Seitenzahlen anzeigen</string>
|
||||
<string name="enabled_sources">Freigegebene Quellen</string>
|
||||
<string name="available_sources">Verfügbare Quellen</string>
|
||||
</resources>
|
||||
@@ -246,4 +246,7 @@
|
||||
<string name="system_default">Par défaut</string>
|
||||
<string name="exclude_nsfw_from_history">Exclure les mangas osés de l\'historique</string>
|
||||
<string name="error_empty_name">Le nom ne doit pas être vide</string>
|
||||
<string name="show_pages_numbers">Afficher les numéros de pages</string>
|
||||
<string name="enabled_sources">Sources activées</string>
|
||||
<string name="available_sources">Sources disponibles</string>
|
||||
</resources>
|
||||
@@ -246,4 +246,7 @@
|
||||
<string name="date_format">Formato della data</string>
|
||||
<string name="exclude_nsfw_from_history">Escludi i manga NSFW dalla storia</string>
|
||||
<string name="error_empty_name">Il nome non dovrebbe essere vuoto</string>
|
||||
<string name="show_pages_numbers">Mostra i numeri delle pagine</string>
|
||||
<string name="enabled_sources">Fonti abilitate</string>
|
||||
<string name="available_sources">Fonti disponibili</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user