Ktlint: do code format
This commit is contained in:
1 parent
04c99a5a36
commit
661bf3ecc2
159 files changed
+1631
-1273
No files matched your search
@@ -72,8 +72,8 @@ android {
|
||||
"de",
|
||||
"th",
|
||||
"tr",
|
||||
"nb-rNO"
|
||||
)
|
||||
"nb-rNO",
|
||||
),
|
||||
)
|
||||
buildConfigField("String", "COMMIT_SHA", "\"$commitSha\"")
|
||||
buildConfigField("String", "BUILD_TIME", "\"$buildTime\"")
|
||||
@@ -124,7 +124,6 @@ android {
|
||||
excludes += "**.txt"
|
||||
excludes += "**.bin"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dependenciesInfo.includeInApk = false
|
||||
|
||||
@@ -13,7 +13,7 @@ fun onNavDestinationSelected2(item: MenuItem, navController: NavController): Boo
|
||||
val builder = NavOptions.Builder().setLaunchSingleTop(true)
|
||||
if (
|
||||
navController.currentDestination!!.parent!!.findNode(item.itemId)
|
||||
is ActivityNavigator.Destination
|
||||
is ActivityNavigator.Destination
|
||||
) {
|
||||
builder.setEnterAnim(R.anim.nav_default_enter_anim)
|
||||
.setExitAnim(R.anim.nav_default_exit_anim)
|
||||
@@ -37,4 +37,4 @@ fun onNavDestinationSelected2(item: MenuItem, navController: NavController): Boo
|
||||
}
|
||||
|
||||
fun NavDestination.matchDestination(@IdRes destId: Int): Boolean =
|
||||
hierarchy.any { it.id == destId }
|
||||
hierarchy.any { it.id == destId }
|
||||
@@ -7,10 +7,10 @@ import android.util.AttributeSet
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import rikka.core.res.resolveColor
|
||||
|
||||
|
||||
@SuppressLint("PrivateResource")
|
||||
class ThemedSwipeRefreshLayout @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
) : SwipeRefreshLayout(context, attrs) {
|
||||
|
||||
init {
|
||||
@@ -22,4 +22,4 @@ class ThemedSwipeRefreshLayout @JvmOverloads constructor(
|
||||
(mCircleView.background as ShapeDrawable).paint.color = backgroundColor
|
||||
setColorSchemeColors(context.theme.resolveColor(com.google.android.material.R.attr.colorAccent))
|
||||
}
|
||||
}
|
||||
}
|
||||
+133
-104
@@ -62,7 +62,7 @@ import kotlin.math.sqrt
|
||||
@Suppress("unused")
|
||||
open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attr: AttributeSet? = null
|
||||
attr: AttributeSet? = null,
|
||||
) : View(context, attr) {
|
||||
private val decoderLock: ReadWriteLock = ReentrantReadWriteLock(true)
|
||||
|
||||
@@ -78,7 +78,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
private val srcArray = FloatArray(8)
|
||||
private val dstArray = FloatArray(8)
|
||||
|
||||
//The logical density of the display
|
||||
// The logical density of the display
|
||||
private val density: Float = resources.displayMetrics.density
|
||||
|
||||
// Bitmap (preview or full image)
|
||||
@@ -139,6 +139,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
|
||||
// Double tap zoom behaviour
|
||||
private var doubleTapZoomScale = 1F
|
||||
|
||||
@ZoomStyle private var doubleTapZoomStyle = ZOOM_FOCUS_FIXED
|
||||
private var doubleTapZoomDuration = 500
|
||||
|
||||
@@ -331,8 +332,9 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
imageSource.sRegion.left,
|
||||
imageSource.sRegion.top,
|
||||
imageSource.sRegion.width(),
|
||||
imageSource.sRegion.height()
|
||||
), false
|
||||
imageSource.sRegion.height(),
|
||||
),
|
||||
false,
|
||||
)
|
||||
} else if (imageSource.bitmap != null) {
|
||||
onImageLoaded(imageSource.bitmap, imageSource.isCached)
|
||||
@@ -436,64 +438,70 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
private fun setGestureDetector(context: Context) {
|
||||
detector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
|
||||
if (panEnabled && isReady && vTranslate != null && (abs(e1.x - e2.x) > 50 || abs(e1.y - e2.y) > 50) && (abs(velocityX) > 500 || abs(velocityY) > 500) && !isZooming) {
|
||||
val vTranslateEnd = PointF(vTranslate!!.x + velocityX * 0.25F, vTranslate!!.y + velocityY * 0.25F)
|
||||
val sCenterXEnd = (width / 2 - vTranslateEnd.x) / scale
|
||||
val sCenterYEnd = (height / 2 - vTranslateEnd.y) / scale
|
||||
AnimationBuilder(PointF(sCenterXEnd, sCenterYEnd))
|
||||
.withEasing(EASE_OUT_QUAD)
|
||||
.withPanLimited(false)
|
||||
.withOrigin(ORIGIN_FLING)
|
||||
.start()
|
||||
detector = GestureDetector(
|
||||
context,
|
||||
object : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
|
||||
if (panEnabled && isReady && vTranslate != null && (abs(e1.x - e2.x) > 50 || abs(e1.y - e2.y) > 50) && (abs(velocityX) > 500 || abs(velocityY) > 500) && !isZooming) {
|
||||
val vTranslateEnd = PointF(vTranslate!!.x + velocityX * 0.25F, vTranslate!!.y + velocityY * 0.25F)
|
||||
val sCenterXEnd = (width / 2 - vTranslateEnd.x) / scale
|
||||
val sCenterYEnd = (height / 2 - vTranslateEnd.y) / scale
|
||||
AnimationBuilder(PointF(sCenterXEnd, sCenterYEnd))
|
||||
.withEasing(EASE_OUT_QUAD)
|
||||
.withPanLimited(false)
|
||||
.withOrigin(ORIGIN_FLING)
|
||||
.start()
|
||||
return true
|
||||
}
|
||||
return super.onFling(e1, e2, velocityX, velocityY)
|
||||
}
|
||||
|
||||
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
|
||||
performClick()
|
||||
return true
|
||||
}
|
||||
return super.onFling(e1, e2, velocityX, velocityY)
|
||||
}
|
||||
|
||||
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
|
||||
performClick()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onDoubleTap(e: MotionEvent): Boolean {
|
||||
if (isZoomEnabled && isReady && vTranslate != null) {
|
||||
// Hacky solution for #15 - after a double tap the GestureDetector gets in a state
|
||||
// where the next fling is ignored, so here we replace it with a new one.
|
||||
setGestureDetector(context)
|
||||
return if (isQuickScaleEnabled) {
|
||||
// Store quick scale params. This will become either a double tap zoom or a
|
||||
// quick scale depending on whether the user swipes.
|
||||
vCenterStart = PointF(e.x, e.y)
|
||||
vTranslateStart = PointF(vTranslate!!.x, vTranslate!!.y)
|
||||
scaleStart = scale
|
||||
isQuickScaling = true
|
||||
isZooming = true
|
||||
quickScaleLastDistance = -1F
|
||||
quickScaleSCenter = viewToSourceCoord(vCenterStart!!)
|
||||
quickScaleVStart = PointF(e.x, e.y)
|
||||
quickScaleVLastPoint = PointF(quickScaleSCenter!!.x, quickScaleSCenter!!.y)
|
||||
quickScaleMoved = false
|
||||
// We need to get events in onTouchEvent after this.
|
||||
false
|
||||
} else {
|
||||
// Start double tap zoom animation.
|
||||
viewToSourceCoord(PointF(e.x, e.y))?.let { center ->
|
||||
doubleTapZoom(center, PointF(e.x, e.y))
|
||||
override fun onDoubleTap(e: MotionEvent): Boolean {
|
||||
if (isZoomEnabled && isReady && vTranslate != null) {
|
||||
// Hacky solution for #15 - after a double tap the GestureDetector gets in a state
|
||||
// where the next fling is ignored, so here we replace it with a new one.
|
||||
setGestureDetector(context)
|
||||
return if (isQuickScaleEnabled) {
|
||||
// Store quick scale params. This will become either a double tap zoom or a
|
||||
// quick scale depending on whether the user swipes.
|
||||
vCenterStart = PointF(e.x, e.y)
|
||||
vTranslateStart = PointF(vTranslate!!.x, vTranslate!!.y)
|
||||
scaleStart = scale
|
||||
isQuickScaling = true
|
||||
isZooming = true
|
||||
quickScaleLastDistance = -1F
|
||||
quickScaleSCenter = viewToSourceCoord(vCenterStart!!)
|
||||
quickScaleVStart = PointF(e.x, e.y)
|
||||
quickScaleVLastPoint = PointF(quickScaleSCenter!!.x, quickScaleSCenter!!.y)
|
||||
quickScaleMoved = false
|
||||
// We need to get events in onTouchEvent after this.
|
||||
false
|
||||
} else {
|
||||
// Start double tap zoom animation.
|
||||
viewToSourceCoord(PointF(e.x, e.y))?.let { center ->
|
||||
doubleTapZoom(center, PointF(e.x, e.y))
|
||||
}
|
||||
true
|
||||
}
|
||||
true
|
||||
}
|
||||
return super.onDoubleTapEvent(e)
|
||||
}
|
||||
return super.onDoubleTapEvent(e)
|
||||
}
|
||||
})
|
||||
singleDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
|
||||
performClick()
|
||||
return true
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
singleDetector = GestureDetector(
|
||||
context,
|
||||
object : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
|
||||
performClick()
|
||||
return true
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
@@ -730,7 +738,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
val dx = abs(event.x - vCenterStart!!.x)
|
||||
val dy = abs(event.y - vCenterStart!!.y)
|
||||
|
||||
//On the Samsung S6 long click event does not work, because the dx > 5 usually true
|
||||
// On the Samsung S6 long click event does not work, because the dx > 5 usually true
|
||||
val offset = density * 5
|
||||
if (dx > offset || dy > offset || isPanning) {
|
||||
consumed = true
|
||||
@@ -894,7 +902,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
scaleElapsed,
|
||||
anim!!.scaleStart,
|
||||
anim!!.scaleEnd - anim!!.scaleStart,
|
||||
anim!!.duration
|
||||
anim!!.duration,
|
||||
)
|
||||
|
||||
// Apply required animation to the focal point
|
||||
@@ -903,14 +911,14 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
scaleElapsed,
|
||||
anim!!.vFocusStart!!.x,
|
||||
anim!!.vFocusEnd.x - anim!!.vFocusStart!!.x,
|
||||
anim!!.duration
|
||||
anim!!.duration,
|
||||
)
|
||||
val vFocusNowY = ease(
|
||||
anim!!.easing,
|
||||
scaleElapsed,
|
||||
anim!!.vFocusStart!!.y,
|
||||
anim!!.vFocusEnd.y - anim!!.vFocusStart!!.y,
|
||||
anim!!.duration
|
||||
anim!!.duration,
|
||||
)
|
||||
// Find out where the focal point is at this scale and adjust its position to follow the animation path
|
||||
vTranslate!!.x -= sourceToViewX(anim!!.sCenterEnd.x) - vFocusNowX
|
||||
@@ -967,7 +975,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
tileWidth,
|
||||
tileHeight,
|
||||
0F,
|
||||
tileHeight
|
||||
tileHeight,
|
||||
)
|
||||
setMatrixArray(
|
||||
dstArray,
|
||||
@@ -978,7 +986,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
tile.vRect.right.toFloat(),
|
||||
tile.vRect.bottom.toFloat(),
|
||||
tile.vRect.left.toFloat(),
|
||||
tile.vRect.bottom.toFloat()
|
||||
tile.vRect.bottom.toFloat(),
|
||||
)
|
||||
mtrx.setPolyToPoly(srcArray, 0, dstArray, 0, 4)
|
||||
canvas.drawBitmap(tile.bitmap!!, mtrx, bitmapPaint)
|
||||
@@ -990,7 +998,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
"LOADING",
|
||||
(tile.vRect.left + px(5)).toFloat(),
|
||||
(tile.vRect.top + px(35)).toFloat(),
|
||||
debugTextPaint
|
||||
debugTextPaint,
|
||||
)
|
||||
}
|
||||
if (tile.visible && debug) {
|
||||
@@ -998,7 +1006,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
"ISS " + tile.sampleSize + " RECT " + tile.sRect.top + "," + tile.sRect.left + "," + tile.sRect.bottom + "," + tile.sRect.right,
|
||||
(tile.vRect.left + px(5)).toFloat(),
|
||||
(tile.vRect.top + px(15)).toFloat(),
|
||||
debugTextPaint
|
||||
debugTextPaint,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1023,21 +1031,36 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
"Scale: " + String.format(Locale.ENGLISH, "%.2f", scale) + " (" + String.format(
|
||||
Locale.ENGLISH,
|
||||
"%.2f",
|
||||
minScale()
|
||||
minScale(),
|
||||
) + " - " + String.format(
|
||||
Locale.ENGLISH, "%.2f", maxScale
|
||||
) + ")", px(5).toFloat(), px(15).toFloat(), debugTextPaint
|
||||
Locale.ENGLISH,
|
||||
"%.2f",
|
||||
maxScale,
|
||||
) + ")",
|
||||
px(5).toFloat(),
|
||||
px(15).toFloat(),
|
||||
debugTextPaint,
|
||||
)
|
||||
canvas.drawText(
|
||||
"Translate: " + String.format(Locale.ENGLISH, "%.2f", vTranslate!!.x) + ":" + String.format(
|
||||
Locale.ENGLISH, "%.2f", vTranslate!!.y
|
||||
), px(5).toFloat(), px(30).toFloat(), debugTextPaint
|
||||
Locale.ENGLISH,
|
||||
"%.2f",
|
||||
vTranslate!!.y,
|
||||
),
|
||||
px(5).toFloat(),
|
||||
px(30).toFloat(),
|
||||
debugTextPaint,
|
||||
)
|
||||
val center = center
|
||||
canvas.drawText(
|
||||
"Source center: " + String.format(Locale.ENGLISH, "%.2f", center!!.x) + ":" + String.format(
|
||||
Locale.ENGLISH, "%.2f", center.y
|
||||
), px(5).toFloat(), px(45).toFloat(), debugTextPaint
|
||||
Locale.ENGLISH,
|
||||
"%.2f",
|
||||
center.y,
|
||||
),
|
||||
px(5).toFloat(),
|
||||
px(45).toFloat(),
|
||||
debugTextPaint,
|
||||
)
|
||||
if (anim != null) {
|
||||
val vCenterStart = sourceToViewCoord(anim!!.sCenterStart)
|
||||
@@ -1061,7 +1084,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
sourceToViewX(quickScaleSCenter!!.x),
|
||||
sourceToViewY(quickScaleSCenter!!.y),
|
||||
px(35).toFloat(),
|
||||
debugLinePaint
|
||||
debugLinePaint,
|
||||
)
|
||||
}
|
||||
if (quickScaleVStart != null && isQuickScaling) {
|
||||
@@ -1084,7 +1107,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
f4: Float,
|
||||
f5: Float,
|
||||
f6: Float,
|
||||
f7: Float
|
||||
f7: Float,
|
||||
) {
|
||||
array[0] = f0
|
||||
array[1] = f1
|
||||
@@ -1158,7 +1181,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
debug(
|
||||
"loadTile, tile.sRect=%s, tile.sampleSize=%d",
|
||||
tile.sRect,
|
||||
tile.sampleSize
|
||||
tile.sampleSize,
|
||||
)
|
||||
decoderLock.readLock().lock()
|
||||
try {
|
||||
@@ -1429,13 +1452,13 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
x * sTileWidth,
|
||||
y * sTileHeight,
|
||||
if (x == xTiles - 1) sWidth else (x + 1) * sTileWidth,
|
||||
if (y == yTiles - 1) sHeight else (y + 1) * sTileHeight
|
||||
if (y == yTiles - 1) sHeight else (y + 1) * sTileHeight,
|
||||
)
|
||||
val tile = Tile(
|
||||
sRect = sRect,
|
||||
sampleSize = sampleSize,
|
||||
vRect = Rect(0, 0, 0, 0),
|
||||
fileSRect = Rect(sRect)
|
||||
fileSRect = Rect(sRect),
|
||||
)
|
||||
tileGrid.add(tile)
|
||||
}
|
||||
@@ -1564,7 +1587,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
private fun getMaxBitmapDimensions(canvas: Canvas): Point {
|
||||
return Point(
|
||||
canvas.maximumBitmapWidth.coerceAtMost(maxTileWidth),
|
||||
canvas.maximumBitmapHeight.coerceAtMost(maxTileHeight)
|
||||
canvas.maximumBitmapHeight.coerceAtMost(maxTileHeight),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1629,15 +1652,15 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
if (vTranslate == null || !isReady) return
|
||||
|
||||
fRect[
|
||||
viewToSourceX(vRect.left.toFloat()).toInt(),
|
||||
viewToSourceY(vRect.top.toFloat()).toInt(),
|
||||
viewToSourceX(vRect.right.toFloat()).toInt()
|
||||
viewToSourceX(vRect.left.toFloat()).toInt(),
|
||||
viewToSourceY(vRect.top.toFloat()).toInt(),
|
||||
viewToSourceX(vRect.right.toFloat()).toInt(),
|
||||
] = viewToSourceY(vRect.bottom.toFloat()).toInt()
|
||||
fileSRect(fRect, fRect)
|
||||
fRect[
|
||||
fRect.left.coerceAtLeast(0),
|
||||
fRect.top.coerceAtLeast(0),
|
||||
fRect.right.coerceAtLeast(sWidth)
|
||||
fRect.left.coerceAtLeast(0),
|
||||
fRect.top.coerceAtLeast(0),
|
||||
fRect.right.coerceAtLeast(sWidth),
|
||||
] = fRect.bottom.coerceAtLeast(sHeight)
|
||||
if (!sRegion.isEmpty) {
|
||||
fRect.offset(sRegion.left, sRegion.top)
|
||||
@@ -1754,9 +1777,9 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
*/
|
||||
private fun sourceToViewRect(sRect: Rect, vTarget: Rect) {
|
||||
vTarget[
|
||||
sourceToViewX(sRect.left.toFloat()).toInt(),
|
||||
sourceToViewY(sRect.top.toFloat()).toInt(),
|
||||
sourceToViewX(sRect.right.toFloat()).toInt()
|
||||
sourceToViewX(sRect.left.toFloat()).toInt(),
|
||||
sourceToViewY(sRect.top.toFloat()).toInt(),
|
||||
sourceToViewX(sRect.right.toFloat()).toInt(),
|
||||
] = sourceToViewY(sRect.bottom.toFloat()).toInt()
|
||||
}
|
||||
|
||||
@@ -1803,11 +1826,11 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
return when (minimumScaleType) {
|
||||
SCALE_TYPE_CENTER_INSIDE -> min(
|
||||
(width - hPadding) / sWidth.toFloat(),
|
||||
(height - vPadding) / sHeight.toFloat()
|
||||
(height - vPadding) / sHeight.toFloat(),
|
||||
)
|
||||
SCALE_TYPE_CENTER_CROP -> max(
|
||||
(width - hPadding) / sWidth.toFloat(),
|
||||
(height - vPadding) / sHeight.toFloat()
|
||||
(height - vPadding) / sHeight.toFloat(),
|
||||
)
|
||||
SCALE_TYPE_FIT_WIDTH -> (width - hPadding) / sWidth.toFloat()
|
||||
SCALE_TYPE_FIT_HEIGHT -> (height - vPadding) / sHeight.toFloat()
|
||||
@@ -2111,7 +2134,9 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
val state: ImageViewState?
|
||||
get() = if (vTranslate != null && sWidth > 0 && sHeight > 0) {
|
||||
ImageViewState(scale, center!!)
|
||||
} else null
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if pan gesture detection is enabled.
|
||||
@@ -2397,7 +2422,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
val sRect: Rect,
|
||||
val sampleSize: Int,
|
||||
val vRect: Rect,
|
||||
val fileSRect: Rect
|
||||
val fileSRect: Rect,
|
||||
) {
|
||||
var bitmap: Bitmap? = null
|
||||
var loading = false
|
||||
@@ -2432,7 +2457,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
val easing: Int,
|
||||
val origin: Int,
|
||||
val time: Long = System.currentTimeMillis(),
|
||||
val listener: OnAnimationEventListener?
|
||||
val listener: OnAnimationEventListener?,
|
||||
)
|
||||
|
||||
private data class ScaleAndTranslate(var scale: Float, val vTranslate: PointF)
|
||||
@@ -2578,12 +2603,16 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
val vxCenter = paddingLeft + (width - paddingRight - paddingLeft) / 2
|
||||
val vyCenter = paddingTop + (height - paddingBottom - paddingTop) / 2
|
||||
val targetScale = limitedScale(targetScale)
|
||||
val targetSCenter = if (panLimited) limitedSCenter(
|
||||
targetSCenter!!.x,
|
||||
targetSCenter.y,
|
||||
targetScale,
|
||||
PointF()
|
||||
) else targetSCenter!!
|
||||
val targetSCenter = if (panLimited) {
|
||||
limitedSCenter(
|
||||
targetSCenter!!.x,
|
||||
targetSCenter.y,
|
||||
targetScale,
|
||||
PointF(),
|
||||
)
|
||||
} else {
|
||||
targetSCenter!!
|
||||
}
|
||||
anim = Anim(
|
||||
scaleStart = scale,
|
||||
scaleEnd = targetScale,
|
||||
@@ -2593,13 +2622,13 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
vFocusStart = sourceToViewCoord(targetSCenter),
|
||||
vFocusEnd = PointF(
|
||||
vxCenter.toFloat(),
|
||||
vyCenter.toFloat()
|
||||
vyCenter.toFloat(),
|
||||
),
|
||||
duration = duration,
|
||||
interruptible = interruptible,
|
||||
easing = easing,
|
||||
origin = origin,
|
||||
listener = listener
|
||||
listener = listener,
|
||||
)
|
||||
if (vFocus != null) {
|
||||
// Calculate where translation will be at the end of the anim
|
||||
@@ -2611,7 +2640,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
// Adjust the position of the focus point at end so image will be in bounds
|
||||
anim!!.vFocusEnd.set(
|
||||
vFocus.x + (satEnd.vTranslate.x - vTranslateXEnd),
|
||||
vFocus.y + (satEnd.vTranslate.y - vTranslateYEnd)
|
||||
vFocus.y + (satEnd.vTranslate.y - vTranslateYEnd),
|
||||
)
|
||||
}
|
||||
invalidate()
|
||||
@@ -2623,7 +2652,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
@IntDef(
|
||||
ZOOM_FOCUS_FIXED,
|
||||
ZOOM_FOCUS_CENTER,
|
||||
ZOOM_FOCUS_CENTER_IMMEDIATE
|
||||
ZOOM_FOCUS_CENTER_IMMEDIATE,
|
||||
)
|
||||
annotation class ZoomStyle
|
||||
|
||||
@@ -2645,7 +2674,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
@IntDef(
|
||||
EASE_IN_OUT_QUAD,
|
||||
EASE_OUT_QUAD
|
||||
EASE_OUT_QUAD,
|
||||
)
|
||||
annotation class EasingStyle
|
||||
|
||||
@@ -2663,7 +2692,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
@IntDef(
|
||||
PAN_LIMIT_INSIDE,
|
||||
PAN_LIMIT_OUTSIDE,
|
||||
PAN_LIMIT_CENTER
|
||||
PAN_LIMIT_CENTER,
|
||||
)
|
||||
annotation class PanLimit
|
||||
|
||||
@@ -2690,7 +2719,7 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
|
||||
SCALE_TYPE_FIT_HEIGHT,
|
||||
SCALE_TYPE_ORIGINAL_SIZE,
|
||||
SCALE_TYPE_SMART_FIT,
|
||||
SCALE_TYPE_CUSTOM
|
||||
SCALE_TYPE_CUSTOM,
|
||||
)
|
||||
annotation class ScaleType
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Point
|
||||
import android.graphics.Rect
|
||||
import kotlin.Throws
|
||||
import com.davemorrissey.labs.subscaleview.provider.InputProvider
|
||||
import java.lang.Exception
|
||||
import kotlin.Throws
|
||||
|
||||
/**
|
||||
* Interface for image decoding classes.
|
||||
@@ -50,4 +50,4 @@ interface Decoder {
|
||||
* resources still in use.
|
||||
*/
|
||||
fun recycle()
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import com.davemorrissey.labs.subscaleview.provider.InputProvider
|
||||
|
||||
class ImageDecoder @JvmOverloads constructor(
|
||||
private val cropBorders: Boolean,
|
||||
bitmapConfig: Bitmap.Config? = null
|
||||
bitmapConfig: Bitmap.Config? = null,
|
||||
) : Decoder {
|
||||
init {
|
||||
val globalBitmapConfig = SubsamplingScaleImageView.preferredBitmapConfig
|
||||
@@ -59,4 +59,4 @@ class ImageDecoder @JvmOverloads constructor(
|
||||
override fun recycle() {
|
||||
TODO()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,5 +4,5 @@ import android.content.Context
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
|
||||
open class BaseDialogBuilder constructor(
|
||||
context: Context
|
||||
context: Context,
|
||||
) : MaterialAlertDialogBuilder(context)
|
||||
@@ -24,9 +24,9 @@ class CheckBoxDialogBuilder constructor(
|
||||
context: Context,
|
||||
message: String?,
|
||||
checkText: String?,
|
||||
checked: Boolean
|
||||
checked: Boolean,
|
||||
) : BaseDialogBuilder(
|
||||
context
|
||||
context,
|
||||
) {
|
||||
private val mCheckBox: CheckBox
|
||||
val isChecked: Boolean
|
||||
@@ -41,4 +41,4 @@ class CheckBoxDialogBuilder constructor(
|
||||
mCheckBox.isChecked = checked
|
||||
view.setOnClickListener { mCheckBox.toggle() }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,10 +29,11 @@ import com.hippo.ehviewer.R
|
||||
class EditTextDialogBuilder constructor(
|
||||
context: Context,
|
||||
text: String?,
|
||||
hint: String?
|
||||
hint: String?,
|
||||
) : BaseDialogBuilder(
|
||||
context
|
||||
), OnEditorActionListener {
|
||||
context,
|
||||
),
|
||||
OnEditorActionListener {
|
||||
private val mTextInputLayout: TextInputLayout
|
||||
val editText: EditText
|
||||
private var mDialog: AlertDialog? = null
|
||||
@@ -68,4 +69,4 @@ class EditTextDialogBuilder constructor(
|
||||
editText.setOnEditorActionListener(this)
|
||||
mTextInputLayout.hint = hint
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,9 +6,10 @@ import android.view.HapticFeedbackConstants
|
||||
import com.google.android.material.slider.Slider
|
||||
|
||||
class HapticSlider @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
) : Slider(context, attrs) {
|
||||
init {
|
||||
addOnChangeListener { _, _, _ -> performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,9 +31,9 @@ class ListCheckBoxDialogBuilder(
|
||||
items: List<CharSequence>,
|
||||
listener: (ListCheckBoxDialogBuilder?, AlertDialog?, Int) -> Unit,
|
||||
checkText: String?,
|
||||
checked: Boolean
|
||||
checked: Boolean,
|
||||
) : BaseDialogBuilder(
|
||||
context
|
||||
context,
|
||||
) {
|
||||
private val mCheckBox: CheckBox
|
||||
private var mDialog: AlertDialog? = null
|
||||
@@ -60,4 +60,4 @@ class ListCheckBoxDialogBuilder(
|
||||
mCheckBox.text = checkText
|
||||
mCheckBox.isChecked = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,25 +54,25 @@ class MSQLiteBuilder {
|
||||
*/
|
||||
fun version(version: Int): MSQLiteBuilder {
|
||||
check(version > this.version) {
|
||||
("New version must be bigger than current version. "
|
||||
+ "current version: " + this.version + ", new version: " + version + ".")
|
||||
(
|
||||
"New version must be bigger than current version. " +
|
||||
"current version: " + this.version + ", new version: " + version + "."
|
||||
)
|
||||
}
|
||||
this.version = version
|
||||
statements = ArrayList()
|
||||
statementsMap.put(version, statements)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a table.
|
||||
*/
|
||||
/**
|
||||
* Creates a table with int [.COLUMN_ID] primary key.
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun createTable(
|
||||
table: String,
|
||||
column: String = COLUMN_ID,
|
||||
clazz: Class<*>? = Int::class.javaPrimitiveType
|
||||
clazz: Class<*>? = Int::class.javaPrimitiveType,
|
||||
): MSQLiteBuilder {
|
||||
return statement("CREATE TABLE " + table + " (" + column + " " + javaTypeToSQLiteType(clazz) + " PRIMARY KEY);")
|
||||
}
|
||||
@@ -90,8 +90,8 @@ class MSQLiteBuilder {
|
||||
fun insertColumn(table: String, column: String, clazz: Class<*>?): MSQLiteBuilder {
|
||||
return statement(
|
||||
"ALTER TABLE $table ADD COLUMN $column " + javaTypeToSQLiteType(
|
||||
clazz
|
||||
) + ";"
|
||||
clazz,
|
||||
) + ";",
|
||||
)
|
||||
}
|
||||
|
||||
@@ -121,4 +121,4 @@ class MSQLiteBuilder {
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ internal class MSQLiteOpenHelper(
|
||||
context: Context?,
|
||||
name: String?,
|
||||
private val version: Int,
|
||||
private val builder: MSQLiteBuilder
|
||||
private val builder: MSQLiteBuilder,
|
||||
) : SQLiteOpenHelper(context, name, null, version) {
|
||||
override fun onCreate(db: SQLiteDatabase) {
|
||||
onUpgrade(db, 0, version)
|
||||
@@ -40,4 +40,4 @@ internal class MSQLiteOpenHelper(
|
||||
SqlUtils.dropAllTable(db)
|
||||
onCreate(db)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ class PreciselyClipDrawable(
|
||||
offsetX: Int,
|
||||
offsetY: Int,
|
||||
width: Int,
|
||||
height: Int
|
||||
height: Int,
|
||||
) : DrawableWrapper(drawable) {
|
||||
private val mScale: RectF
|
||||
private val mTemp = Rect()
|
||||
|
||||
@@ -22,7 +22,8 @@ import coil.request.ImageRequest
|
||||
import com.hippo.ehviewer.coil.imageRequest
|
||||
import com.hippo.widget.ObservedTextView
|
||||
|
||||
class UnikeryDrawable(private val mTextView: ObservedTextView, url: String) : WrapDrawable(),
|
||||
class UnikeryDrawable(private val mTextView: ObservedTextView, url: String) :
|
||||
WrapDrawable(),
|
||||
ObservedTextView.OnWindowAttachListener {
|
||||
private val mImageRequest: ImageRequest
|
||||
|
||||
@@ -78,4 +79,4 @@ class UnikeryDrawable(private val mTextView: ObservedTextView, url: String) : Wr
|
||||
drawable.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,7 @@ object Crash {
|
||||
fw.write("${collectClassStaticInfo(Build.VERSION::class.java)}\r\n")
|
||||
fw.write("MEMORY=")
|
||||
fw.write(
|
||||
FileUtils.humanReadableByteCount(OSUtils.getAppAllocatedMemory(), false)
|
||||
FileUtils.humanReadableByteCount(OSUtils.getAppAllocatedMemory(), false),
|
||||
)
|
||||
fw.write("\r\n")
|
||||
fw.write("MEMORY_NATIVE=")
|
||||
@@ -121,4 +121,4 @@ object Crash {
|
||||
IOUtils.closeQuietly(fw)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,8 +168,9 @@ class EhApplication : Application(), DefaultLifecycleObserver, ImageLoaderFactor
|
||||
}
|
||||
|
||||
override fun onPause(owner: LifecycleOwner) {
|
||||
if (!locked)
|
||||
if (!locked) {
|
||||
locked_last_leave_time = System.currentTimeMillis() / 1000
|
||||
}
|
||||
locked = true
|
||||
}
|
||||
|
||||
@@ -216,8 +217,8 @@ class EhApplication : Application(), DefaultLifecycleObserver, ImageLoaderFactor
|
||||
Cache(
|
||||
application.cacheDir.toOkioPath() / "http_cache",
|
||||
20L * 1024L * 1024L,
|
||||
FileSystem.SYSTEM
|
||||
)
|
||||
FileSystem.SYSTEM,
|
||||
),
|
||||
).build()
|
||||
}
|
||||
|
||||
|
||||
@@ -459,4 +459,4 @@ object EhDB {
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ object Settings {
|
||||
KEY_SHOW_JPN_TITLE,
|
||||
KEY_REQUEST_NEWS,
|
||||
KEY_REQUEST_NEWS_TIMER,
|
||||
KEY_HIDE_HV_EVENTS
|
||||
KEY_HIDE_HV_EVENTS,
|
||||
)
|
||||
|
||||
/********************
|
||||
@@ -275,8 +275,10 @@ object Settings {
|
||||
|
||||
private fun putStringToStringSet(key: String, value: String) {
|
||||
var set = getStringSet(key)
|
||||
if (set == null) set =
|
||||
mutableSetOf(value) else if (set.contains(value)) return else set.add(value)
|
||||
if (set == null) {
|
||||
set =
|
||||
mutableSetOf(value)
|
||||
} else if (set.contains(value)) return else set.add(value)
|
||||
sSettingsPre.edit().putStringSet(key, set).apply()
|
||||
}
|
||||
|
||||
@@ -284,7 +286,7 @@ object Settings {
|
||||
return try {
|
||||
NumberUtils.parseIntSafely(
|
||||
sSettingsPre.getString(key, defValue.toString()),
|
||||
defValue
|
||||
defValue,
|
||||
)
|
||||
} catch (e: ClassCastException) {
|
||||
Log.d(TAG, "Get ClassCastException when get $key value", e)
|
||||
@@ -469,7 +471,7 @@ object Settings {
|
||||
sSettingsPre.getString(KEY_FAV_CAT_6, DEFAULT_FAV_CAT_6)!!,
|
||||
sSettingsPre.getString(KEY_FAV_CAT_7, DEFAULT_FAV_CAT_7)!!,
|
||||
sSettingsPre.getString(KEY_FAV_CAT_8, DEFAULT_FAV_CAT_8)!!,
|
||||
sSettingsPre.getString(KEY_FAV_CAT_9, DEFAULT_FAV_CAT_9)!!
|
||||
sSettingsPre.getString(KEY_FAV_CAT_9, DEFAULT_FAV_CAT_9)!!,
|
||||
)
|
||||
|
||||
fun putFavCat(value: Array<String?>) {
|
||||
@@ -499,7 +501,7 @@ object Settings {
|
||||
sSettingsPre.getInt(KEY_FAV_COUNT_6, DEFAULT_FAV_COUNT),
|
||||
sSettingsPre.getInt(KEY_FAV_COUNT_7, DEFAULT_FAV_COUNT),
|
||||
sSettingsPre.getInt(KEY_FAV_COUNT_8, DEFAULT_FAV_COUNT),
|
||||
sSettingsPre.getInt(KEY_FAV_COUNT_9, DEFAULT_FAV_COUNT)
|
||||
sSettingsPre.getInt(KEY_FAV_COUNT_9, DEFAULT_FAV_COUNT),
|
||||
)
|
||||
|
||||
fun putFavCount(count: IntArray) {
|
||||
@@ -642,4 +644,4 @@ object Settings {
|
||||
|
||||
val preloadThumbAggressively: Boolean
|
||||
get() = getBoolean(KEY_PRELOAD_THUMB_AGGRESIVELY, DEFAULT_PRELOAD_THUMB_AGGRESIVELY)
|
||||
}
|
||||
}
|
||||
@@ -28,15 +28,17 @@ object EhClient {
|
||||
val callback: Callback<Any?>? = request.callback
|
||||
try {
|
||||
val result: Any? = request.run {
|
||||
if (args == null)
|
||||
if (args == null) {
|
||||
execute(method)
|
||||
else
|
||||
} else {
|
||||
execute(method, *args!!)
|
||||
}
|
||||
}
|
||||
withUIContext { callback?.onSuccess(result) }
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException)
|
||||
if (e is CancellationException) {
|
||||
throw e // Don't catch coroutine CancellationException
|
||||
}
|
||||
e.printStackTrace()
|
||||
withUIContext { callback?.onFailure(e) }
|
||||
}
|
||||
@@ -46,15 +48,15 @@ object EhClient {
|
||||
suspend fun execute(method: Int, vararg params: Any?): Any? {
|
||||
return when (method) {
|
||||
METHOD_GET_GALLERY_LIST -> EhEngine.getGalleryList(
|
||||
params[0] as String
|
||||
params[0] as String,
|
||||
)
|
||||
|
||||
METHOD_GET_GALLERY_DETAIL -> EhEngine.getGalleryDetail(
|
||||
params[0] as String
|
||||
params[0] as String,
|
||||
)
|
||||
|
||||
METHOD_GET_PREVIEW_LIST -> EhEngine.getPreviewList(
|
||||
params[0] as String
|
||||
params[0] as String,
|
||||
)
|
||||
|
||||
METHOD_GET_RATE_GALLERY -> EhEngine.rateGallery(
|
||||
@@ -62,48 +64,50 @@ object EhClient {
|
||||
params[1] as String?,
|
||||
params[2] as Long,
|
||||
params[3] as String?,
|
||||
params[4] as Float
|
||||
params[4] as Float,
|
||||
)
|
||||
|
||||
METHOD_GET_COMMENT_GALLERY -> EhEngine.commentGallery(
|
||||
params[0] as String?,
|
||||
params[1] as String,
|
||||
params[2] as String?
|
||||
params[2] as String?,
|
||||
)
|
||||
|
||||
METHOD_GET_GALLERY_TOKEN -> EhEngine.getGalleryToken(
|
||||
params[0] as Long,
|
||||
params[1] as String?,
|
||||
params[2] as Int
|
||||
params[2] as Int,
|
||||
)
|
||||
|
||||
METHOD_GET_FAVORITES -> EhEngine.getFavorites(
|
||||
params[0] as String
|
||||
params[0] as String,
|
||||
)
|
||||
|
||||
METHOD_ADD_FAVORITES -> EhEngine.addFavorites(
|
||||
params[0] as Long,
|
||||
params[1] as String?,
|
||||
params[2] as Int,
|
||||
params[3] as String?
|
||||
params[3] as String?,
|
||||
)
|
||||
|
||||
METHOD_ADD_FAVORITES_RANGE -> @Suppress("UNCHECKED_CAST") EhEngine.addFavoritesRange(
|
||||
params[0] as LongArray,
|
||||
params[1] as Array<String?>,
|
||||
params[2] as Int
|
||||
)
|
||||
METHOD_ADD_FAVORITES_RANGE ->
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
EhEngine.addFavoritesRange(
|
||||
params[0] as LongArray,
|
||||
params[1] as Array<String?>,
|
||||
params[2] as Int,
|
||||
)
|
||||
|
||||
METHOD_MODIFY_FAVORITES -> EhEngine.modifyFavorites(
|
||||
params[0] as String,
|
||||
params[1] as LongArray,
|
||||
params[2] as Int
|
||||
params[2] as Int,
|
||||
)
|
||||
|
||||
METHOD_GET_TORRENT_LIST -> EhEngine.getTorrentList(
|
||||
params[0] as String,
|
||||
params[1] as Long,
|
||||
params[2] as String?
|
||||
params[2] as String?,
|
||||
)
|
||||
|
||||
METHOD_VOTE_COMMENT -> EhEngine.voteComment(
|
||||
@@ -112,20 +116,20 @@ object EhClient {
|
||||
params[2] as Long,
|
||||
params[3] as String?,
|
||||
params[4] as Long,
|
||||
params[5] as Int
|
||||
params[5] as Int,
|
||||
)
|
||||
|
||||
METHOD_IMAGE_SEARCH -> EhEngine.imageSearch(
|
||||
params[0] as File,
|
||||
params[1] as Boolean,
|
||||
params[2] as Boolean,
|
||||
params[3] as Boolean
|
||||
params[3] as Boolean,
|
||||
)
|
||||
|
||||
METHOD_ARCHIVE_LIST -> EhEngine.getArchiveList(
|
||||
params[0] as String,
|
||||
params[1] as Long,
|
||||
params[2] as String?
|
||||
params[2] as String?,
|
||||
)
|
||||
|
||||
METHOD_DOWNLOAD_ARCHIVE -> EhEngine.downloadArchive(
|
||||
@@ -133,7 +137,7 @@ object EhClient {
|
||||
params[1] as String?,
|
||||
params[2] as String?,
|
||||
params[3] as String?,
|
||||
params[4] as Boolean
|
||||
params[4] as Boolean,
|
||||
)
|
||||
|
||||
METHOD_VOTE_TAG -> EhEngine.voteTag(
|
||||
@@ -142,7 +146,7 @@ object EhClient {
|
||||
params[2] as Long,
|
||||
params[3] as String?,
|
||||
params[4] as String?,
|
||||
params[5] as Int
|
||||
params[5] as Int,
|
||||
)
|
||||
|
||||
else -> throw IllegalStateException("Can't detect method $method")
|
||||
@@ -171,4 +175,4 @@ object EhClient {
|
||||
const val METHOD_ARCHIVE_LIST = 17
|
||||
const val METHOD_DOWNLOAD_ARCHIVE = 18
|
||||
const val METHOD_VOTE_TAG = 19
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ object EhCookieStore : CookieJar, CookiesStorage {
|
||||
fun hasSignedIn(): Boolean {
|
||||
val url = EhUrl.HOST_E.toHttpUrl()
|
||||
return contains(url, KEY_IPB_MEMBER_ID) &&
|
||||
contains(url, KEY_IPB_PASS_HASH)
|
||||
contains(url, KEY_IPB_PASS_HASH)
|
||||
}
|
||||
|
||||
const val KEY_IPB_MEMBER_ID = "ipb_member_id"
|
||||
@@ -60,8 +60,11 @@ object EhCookieStore : CookieJar, CookiesStorage {
|
||||
.build()
|
||||
|
||||
fun newCookie(
|
||||
cookie: Cookie, newDomain: String, forcePersistent: Boolean = false,
|
||||
forceLongLive: Boolean = false, forceNotHostOnly: Boolean = false
|
||||
cookie: Cookie,
|
||||
newDomain: String,
|
||||
forcePersistent: Boolean = false,
|
||||
forceLongLive: Boolean = false,
|
||||
forceNotHostOnly: Boolean = false,
|
||||
): Cookie {
|
||||
val builder = Cookie.Builder()
|
||||
builder.name(cookie.name)
|
||||
@@ -212,7 +215,7 @@ object EhCookieStore : CookieJar, CookiesStorage {
|
||||
return loadForRequest(requestUrl.toString().toHttpUrl()).map {
|
||||
okhttpCookieToKtorCookieMap[it] ?: KtorCookie(
|
||||
it.name,
|
||||
it.value
|
||||
it.value,
|
||||
).apply { okhttpCookieToKtorCookieMap[it] = this }
|
||||
}
|
||||
}
|
||||
@@ -253,10 +256,12 @@ object EhCookieStore : CookieJar, CookiesStorage {
|
||||
val urlHost = url.host
|
||||
return if (urlHost == domain) {
|
||||
true // As in 'example.com' matching 'example.com'.
|
||||
} else urlHost.endsWith(domain!!)
|
||||
&& urlHost[urlHost.length - domain.length - 1] == '.' && !verifyAsIpAddress(
|
||||
urlHost
|
||||
)
|
||||
} else {
|
||||
urlHost.endsWith(domain!!) &&
|
||||
urlHost[urlHost.length - domain.length - 1] == '.' && !verifyAsIpAddress(
|
||||
urlHost,
|
||||
)
|
||||
}
|
||||
// As in 'example.com' matching 'www.example.com'.
|
||||
}
|
||||
|
||||
@@ -280,4 +285,4 @@ object EhCookieStore : CookieJar, CookiesStorage {
|
||||
cookies
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,27 +70,27 @@ object EhDns : Dns {
|
||||
put(
|
||||
builtInHosts,
|
||||
"ehgt.org",
|
||||
*ehgtHosts
|
||||
*ehgtHosts,
|
||||
)
|
||||
put(
|
||||
builtInHosts,
|
||||
"gt0.ehgt.org",
|
||||
*ehgtHosts
|
||||
*ehgtHosts,
|
||||
)
|
||||
put(
|
||||
builtInHosts,
|
||||
"gt1.ehgt.org",
|
||||
*ehgtHosts
|
||||
*ehgtHosts,
|
||||
)
|
||||
put(
|
||||
builtInHosts,
|
||||
"gt2.ehgt.org",
|
||||
*ehgtHosts
|
||||
*ehgtHosts,
|
||||
)
|
||||
put(
|
||||
builtInHosts,
|
||||
"gt3.ehgt.org",
|
||||
*ehgtHosts
|
||||
*ehgtHosts,
|
||||
)
|
||||
put(
|
||||
builtInHosts,
|
||||
@@ -111,7 +111,7 @@ object EhDns : Dns {
|
||||
private fun put(
|
||||
map: MutableMap<String, List<InetAddress>>,
|
||||
host: String,
|
||||
vararg ips: Pair<String, Boolean>
|
||||
vararg ips: Pair<String, Boolean>,
|
||||
) {
|
||||
map[host] = ips.mapNotNull { pair ->
|
||||
Hosts.toInetAddress(host, pair.first).takeUnless { Settings.dF && pair.second }
|
||||
@@ -121,7 +121,7 @@ object EhDns : Dns {
|
||||
@Throws(UnknownHostException::class)
|
||||
override fun lookup(hostname: String): List<InetAddress> {
|
||||
return hosts[hostname] ?: builtInHosts[hostname].takeIf { Settings.builtInHosts }
|
||||
?: Dns.SYSTEM.lookup(hostname)
|
||||
?: Dns.SYSTEM.lookup(hostname)
|
||||
}
|
||||
|
||||
fun isInHosts(hostname: String): Boolean {
|
||||
|
||||
@@ -157,7 +157,7 @@ object EhEngine {
|
||||
private suspend fun fillGalleryList(
|
||||
list: MutableList<GalleryInfo>,
|
||||
url: String,
|
||||
filter: Boolean
|
||||
filter: Boolean,
|
||||
) {
|
||||
// Filter title and uploader
|
||||
if (filter) {
|
||||
@@ -177,8 +177,8 @@ object EhEngine {
|
||||
hasRated = true
|
||||
}
|
||||
}
|
||||
val needApi = filter && sEhFilter.needTags() && !hasTags
|
||||
|| Settings.showGalleryPages && !hasPages || hasRated
|
||||
val needApi = filter && sEhFilter.needTags() && !hasTags ||
|
||||
Settings.showGalleryPages && !hasPages || hasRated
|
||||
if (needApi) {
|
||||
fillGalleryListByApi(list, url)
|
||||
}
|
||||
@@ -187,8 +187,8 @@ object EhEngine {
|
||||
if (filter) {
|
||||
// Thumbnail mode need filter uploader again
|
||||
list.removeAll {
|
||||
!sEhFilter.filterUploader(it) || !sEhFilter.filterTag(it)
|
||||
|| !sEhFilter.filterTagNamespace(it)
|
||||
!sEhFilter.filterUploader(it) || !sEhFilter.filterTag(it) ||
|
||||
!sEhFilter.filterTagNamespace(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,7 +202,7 @@ object EhEngine {
|
||||
|
||||
suspend fun fillGalleryListByApi(
|
||||
galleryInfoList: List<GalleryInfo>,
|
||||
referer: String
|
||||
referer: String,
|
||||
): List<GalleryInfo> {
|
||||
val requestItems: MutableList<GalleryInfo> = ArrayList(MAX_REQUEST_SIZE)
|
||||
var i = 0
|
||||
@@ -220,7 +220,7 @@ object EhEngine {
|
||||
|
||||
private suspend fun doFillGalleryListByApi(
|
||||
galleryInfoList: List<GalleryInfo>,
|
||||
referer: String
|
||||
referer: String,
|
||||
) {
|
||||
val json = JSONObject()
|
||||
json.put("method", "gdata")
|
||||
@@ -269,8 +269,11 @@ object EhEngine {
|
||||
|
||||
@Throws(Throwable::class)
|
||||
suspend fun rateGallery(
|
||||
apiUid: Long, apiKey: String?, gid: Long, token: String?,
|
||||
rating: Float
|
||||
apiUid: Long,
|
||||
apiKey: String?,
|
||||
gid: Long,
|
||||
token: String?,
|
||||
rating: Float,
|
||||
): RateGalleryParser.Result {
|
||||
val json = JSONObject()
|
||||
json.put("method", "rategallery")
|
||||
@@ -290,7 +293,9 @@ object EhEngine {
|
||||
}
|
||||
|
||||
suspend fun commentGallery(
|
||||
url: String?, comment: String, id: String?
|
||||
url: String?,
|
||||
comment: String,
|
||||
id: String?,
|
||||
): GalleryCommentList {
|
||||
val builder = FormBody.Builder()
|
||||
if (id == null) {
|
||||
@@ -315,14 +320,16 @@ object EhEngine {
|
||||
|
||||
suspend fun getGalleryToken(
|
||||
gid: Long,
|
||||
gtoken: String?, page: Int
|
||||
gtoken: String?,
|
||||
page: Int,
|
||||
): String {
|
||||
val json = JSONObject()
|
||||
.put("method", "gtoken")
|
||||
.put(
|
||||
"pagelist", JSONArray().put(
|
||||
JSONArray().put(gid).put(gtoken).put(page + 1)
|
||||
)
|
||||
"pagelist",
|
||||
JSONArray().put(
|
||||
JSONArray().put(gid).put(gtoken).put(page + 1),
|
||||
),
|
||||
)
|
||||
val requestBody: RequestBody = json.toString().toRequestBody(MEDIA_TYPE_JSON)
|
||||
val url = EhUrl.apiUrl
|
||||
@@ -335,7 +342,7 @@ object EhEngine {
|
||||
}
|
||||
|
||||
suspend fun getFavorites(
|
||||
url: String
|
||||
url: String,
|
||||
): FavoritesParser.Result {
|
||||
val referer = EhUrl.referer
|
||||
Log.d(TAG, url)
|
||||
@@ -349,7 +356,9 @@ object EhEngine {
|
||||
*/
|
||||
suspend fun addFavorites(
|
||||
gid: Long,
|
||||
token: String?, dstCat: Int, note: String?
|
||||
token: String?,
|
||||
dstCat: Int,
|
||||
note: String?,
|
||||
) {
|
||||
val catStr: String = when (dstCat) {
|
||||
-1 -> {
|
||||
@@ -381,7 +390,8 @@ object EhEngine {
|
||||
@Throws(Throwable::class)
|
||||
suspend fun addFavoritesRange(
|
||||
gidArray: LongArray,
|
||||
tokenArray: Array<String?>, dstCat: Int
|
||||
tokenArray: Array<String?>,
|
||||
dstCat: Int,
|
||||
): Void? {
|
||||
check(gidArray.size == tokenArray.size)
|
||||
var i = 0
|
||||
@@ -395,7 +405,8 @@ object EhEngine {
|
||||
|
||||
suspend fun modifyFavorites(
|
||||
url: String,
|
||||
gidArray: LongArray, dstCat: Int
|
||||
gidArray: LongArray,
|
||||
dstCat: Int,
|
||||
): FavoritesParser.Result {
|
||||
val catStr: String = when (dstCat) {
|
||||
-1 -> {
|
||||
@@ -425,7 +436,9 @@ object EhEngine {
|
||||
}
|
||||
|
||||
suspend fun getTorrentList(
|
||||
url: String, gid: Long, token: String?
|
||||
url: String,
|
||||
gid: Long,
|
||||
token: String?,
|
||||
): List<TorrentParser.Result> {
|
||||
val referer = EhUrl.getGalleryDetailUrl(gid, token)
|
||||
Log.d(TAG, url)
|
||||
@@ -433,7 +446,9 @@ object EhEngine {
|
||||
}
|
||||
|
||||
suspend fun getArchiveList(
|
||||
url: String, gid: Long, token: String?
|
||||
url: String,
|
||||
gid: Long,
|
||||
token: String?,
|
||||
): ArchiveParser.Result {
|
||||
val referer = EhUrl.getGalleryDetailUrl(gid, token)
|
||||
Log.d(TAG, url)
|
||||
@@ -443,7 +458,10 @@ object EhEngine {
|
||||
|
||||
suspend fun downloadArchive(
|
||||
gid: Long,
|
||||
token: String?, or: String?, res: String?, isHAtH: Boolean
|
||||
token: String?,
|
||||
or: String?,
|
||||
res: String?,
|
||||
isHAtH: Boolean,
|
||||
): String? {
|
||||
if (or.isNullOrEmpty()) {
|
||||
throw EhException("Invalid form param or: $or")
|
||||
@@ -526,7 +544,8 @@ object EhEngine {
|
||||
}
|
||||
|
||||
private suspend fun getProfileInternal(
|
||||
url: String, referer: String
|
||||
url: String,
|
||||
referer: String,
|
||||
): ProfileParser.Result {
|
||||
Log.d(TAG, url)
|
||||
return EhRequestBuilder(url, referer).executeAndParsingWith(ProfileParser::parse)
|
||||
@@ -537,7 +556,7 @@ object EhEngine {
|
||||
Log.d(TAG, url)
|
||||
return getProfileInternal(
|
||||
EhRequestBuilder(url).executeAndParsingWith(ForumsParser::parse),
|
||||
url
|
||||
url,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -564,7 +583,11 @@ object EhEngine {
|
||||
|
||||
suspend fun voteComment(
|
||||
apiUid: Long,
|
||||
apiKey: String?, gid: Long, token: String?, commentId: Long, commentVote: Int
|
||||
apiKey: String?,
|
||||
gid: Long,
|
||||
token: String?,
|
||||
commentId: Long,
|
||||
commentVote: Int,
|
||||
): VoteCommentParser.Result {
|
||||
val json = JSONObject()
|
||||
json.put("method", "votecomment")
|
||||
@@ -588,7 +611,11 @@ object EhEngine {
|
||||
|
||||
suspend fun voteTag(
|
||||
apiUid: Long,
|
||||
apiKey: String?, gid: Long, token: String?, tags: String?, vote: Int
|
||||
apiKey: String?,
|
||||
gid: Long,
|
||||
token: String?,
|
||||
tags: String?,
|
||||
vote: Int,
|
||||
): VoteTagParser.Result {
|
||||
val json = JSONObject()
|
||||
json.put("method", "taggallery")
|
||||
@@ -613,38 +640,40 @@ object EhEngine {
|
||||
*/
|
||||
suspend fun imageSearch(
|
||||
image: File,
|
||||
uss: Boolean, osc: Boolean, se: Boolean
|
||||
uss: Boolean,
|
||||
osc: Boolean,
|
||||
se: Boolean,
|
||||
): GalleryListParser.Result {
|
||||
val builder = MultipartBody.Builder()
|
||||
builder.setType(MultipartBody.FORM)
|
||||
builder.addPart(
|
||||
Headers.headersOf(
|
||||
"Content-Disposition",
|
||||
"form-data; name=\"sfile\"; filename=\"a.jpg\""
|
||||
"form-data; name=\"sfile\"; filename=\"a.jpg\"",
|
||||
),
|
||||
image.asRequestBody(MEDIA_TYPE_JPEG)
|
||||
image.asRequestBody(MEDIA_TYPE_JPEG),
|
||||
)
|
||||
if (uss) {
|
||||
builder.addPart(
|
||||
Headers.headersOf("Content-Disposition", "form-data; name=\"fs_similar\""),
|
||||
"on".toRequestBody()
|
||||
"on".toRequestBody(),
|
||||
)
|
||||
}
|
||||
if (osc) {
|
||||
builder.addPart(
|
||||
Headers.headersOf("Content-Disposition", "form-data; name=\"fs_covers\""),
|
||||
"on".toRequestBody()
|
||||
"on".toRequestBody(),
|
||||
)
|
||||
}
|
||||
if (se) {
|
||||
builder.addPart(
|
||||
Headers.headersOf("Content-Disposition", "form-data; name=\"fs_exp\""),
|
||||
"on".toRequestBody()
|
||||
"on".toRequestBody(),
|
||||
)
|
||||
}
|
||||
builder.addPart(
|
||||
Headers.headersOf("Content-Disposition", "form-data; name=\"f_sfile\""),
|
||||
"File Search".toRequestBody()
|
||||
"File Search".toRequestBody(),
|
||||
)
|
||||
val url = EhUrl.imageSearchUrl
|
||||
val referer = EhUrl.referer
|
||||
@@ -659,7 +688,7 @@ object EhEngine {
|
||||
suspend fun getGalleryPage(
|
||||
url: String?,
|
||||
gid: Long,
|
||||
token: String?
|
||||
token: String?,
|
||||
): GalleryPageParser.Result {
|
||||
val referer = EhUrl.getGalleryDetailUrl(gid, token)
|
||||
Log.d(TAG, url!!)
|
||||
@@ -671,7 +700,7 @@ object EhEngine {
|
||||
index: Int,
|
||||
pToken: String?,
|
||||
showKey: String?,
|
||||
previousPToken: String?
|
||||
previousPToken: String?,
|
||||
): GalleryPageApiParser.Result {
|
||||
val json = JSONObject()
|
||||
json.put("method", "showpage")
|
||||
@@ -691,4 +720,4 @@ object EhEngine {
|
||||
.post(requestBody)
|
||||
.executeAndParsingWith(GalleryPageApiParser::parse)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -149,7 +149,7 @@ object EhFilter {
|
||||
val n = filters.size
|
||||
while (i < n) {
|
||||
if (filters[i].enable!! && title.lowercase(Locale.getDefault()).contains(
|
||||
filters[i].text!!
|
||||
filters[i].text!!,
|
||||
)
|
||||
) {
|
||||
return false
|
||||
@@ -210,7 +210,9 @@ object EhFilter {
|
||||
tagNamespace != filterNamespace
|
||||
) {
|
||||
false
|
||||
} else tagName == filterName
|
||||
} else {
|
||||
tagName == filterName
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
@@ -312,4 +314,4 @@ object EhFilter {
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,4 +77,4 @@ class EhRequest {
|
||||
callback?.onCancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ object EhSSLSocketFactory : SSLSocketFactory() {
|
||||
val sslSession = socket.session
|
||||
Log.d(
|
||||
"EhSSLSocketFactory",
|
||||
"Host: " + host + " Address: " + address + " Protocol:" + sslSession.protocol + " CipherSuite:" + sslSession.cipherSuite
|
||||
"Host: " + host + " Address: " + address + " Protocol:" + sslSession.protocol + " CipherSuite:" + sslSession.cipherSuite,
|
||||
)
|
||||
return socket
|
||||
}
|
||||
@@ -52,7 +52,7 @@ object EhSSLSocketFactory : SSLSocketFactory() {
|
||||
host: String,
|
||||
port: Int,
|
||||
localHost: InetAddress,
|
||||
localPort: Int
|
||||
localPort: Int,
|
||||
): Socket {
|
||||
return sslSocketFactory.createSocket(host, port, localHost, localPort)
|
||||
}
|
||||
@@ -65,7 +65,7 @@ object EhSSLSocketFactory : SSLSocketFactory() {
|
||||
address: InetAddress,
|
||||
port: Int,
|
||||
localAddress: InetAddress,
|
||||
localPort: Int
|
||||
localPort: Int,
|
||||
): Socket {
|
||||
return sslSocketFactory.createSocket(address, port, localAddress, localPort)
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ object EhTagDatabase {
|
||||
tags: Map<String, String>,
|
||||
keyword: String,
|
||||
translate: Boolean,
|
||||
exactly: Boolean
|
||||
exactly: Boolean,
|
||||
): Flow<Pair<String?, String>> = flow {
|
||||
if (exactly) {
|
||||
tags[keyword]?.let {
|
||||
@@ -103,7 +103,7 @@ object EhTagDatabase {
|
||||
fun suggestFlow(
|
||||
keyword: String,
|
||||
translate: Boolean,
|
||||
exactly: Boolean = false
|
||||
exactly: Boolean = false,
|
||||
): Flow<Pair<String?, String>> = flow {
|
||||
val keywordPrefix = keyword.substringBefore(':')
|
||||
val keywordTag = keyword.drop(keywordPrefix.length + 1)
|
||||
@@ -131,7 +131,6 @@ object EhTagDatabase {
|
||||
private fun String.containsIgnoreSpace(other: String, ignoreCase: Boolean = true): Boolean =
|
||||
removeSpace().contains(other.removeSpace(), ignoreCase)
|
||||
|
||||
|
||||
private val NAMESPACE_TO_PREFIX = HashMap<String, String>().also {
|
||||
it["artist"] = "a"
|
||||
it["cosplayer"] = "cos"
|
||||
@@ -279,4 +278,4 @@ object EhTagDatabase {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,4 +163,4 @@ object EhUrl {
|
||||
fun getTagDefinitionUrl(tag: String): String {
|
||||
return "https://ehwiki.org/wiki/" + tag.replace(' ', '_')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,13 +51,13 @@ object EhUtils {
|
||||
|
||||
// Remove [XXX], (XXX), {XXX}, ~XXX~ stuff
|
||||
private val PATTERN_TITLE_PREFIX = Pattern.compile(
|
||||
"^(?:\\([^)]*\\)|\\[[^]]*]|\\{[^}]*\\}|~[^~]*~|\\s+)*"
|
||||
"^(?:\\([^)]*\\)|\\[[^]]*]|\\{[^}]*\\}|~[^~]*~|\\s+)*",
|
||||
)
|
||||
|
||||
// Remove [XXX], (XXX), {XXX}, ~XXX~ stuff and something like ch. 1-23
|
||||
private val PATTERN_TITLE_SUFFIX = Pattern.compile(
|
||||
"(?:\\s+ch.[\\s\\d-]+)?(?:\\([^)]*\\)|\\[[^]]*]|\\{[^}]*\\}|~[^~]*~|\\s+)*$",
|
||||
Pattern.CASE_INSENSITIVE
|
||||
Pattern.CASE_INSENSITIVE,
|
||||
)
|
||||
|
||||
private val CATEGORY_VALUES = hashMapOf(
|
||||
@@ -72,7 +72,7 @@ object EhUtils {
|
||||
NON_H to arrayOf("non-h"),
|
||||
WESTERN to arrayOf("western"),
|
||||
PRIVATE to arrayOf("private"),
|
||||
UNKNOWN to arrayOf("unknown")
|
||||
UNKNOWN to arrayOf("unknown"),
|
||||
)
|
||||
private val CATEGORY_STRINGS = CATEGORY_VALUES.entries.map { (k, v) -> v to k }
|
||||
|
||||
@@ -83,8 +83,9 @@ object EhUtils {
|
||||
fun getCategory(type: String?): Int {
|
||||
for (entry in CATEGORY_STRINGS) {
|
||||
for (str in entry.first)
|
||||
if (str.equals(type, ignoreCase = true))
|
||||
if (str.equals(type, ignoreCase = true)) {
|
||||
return entry.second
|
||||
}
|
||||
}
|
||||
return UNKNOWN
|
||||
}
|
||||
@@ -164,4 +165,4 @@ object EhUtils {
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,4 +22,4 @@ interface AbstractGalleryInfo {
|
||||
var simpleLanguage: String?
|
||||
var favoriteSlot: Int
|
||||
var favoriteName: String?
|
||||
}
|
||||
}
|
||||
@@ -84,6 +84,6 @@ open class BaseGalleryInfo(
|
||||
override var favoriteSlot: Int = -2,
|
||||
|
||||
@Ignore
|
||||
override var favoriteName: String? = null
|
||||
override var favoriteName: String? = null,
|
||||
|
||||
) : GalleryInfo
|
||||
) : GalleryInfo
|
||||
@@ -55,4 +55,4 @@ class FavListUrlBuilder(
|
||||
return favCat in 0..9
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,5 +34,5 @@ class GalleryApiInfo(
|
||||
var expunged: Boolean = false,
|
||||
var rating: Float = 0f,
|
||||
var torrentcount: Int = 0,
|
||||
var tags: Array<String>?
|
||||
) : Parcelable
|
||||
var tags: Array<String>?,
|
||||
) : Parcelable
|
||||
@@ -46,5 +46,5 @@ class GalleryComment(
|
||||
@JvmField
|
||||
var comment: String? = null,
|
||||
@JvmField
|
||||
var lastEdited: Long = 0
|
||||
) : Parcelable
|
||||
var lastEdited: Long = 0,
|
||||
) : Parcelable
|
||||
@@ -23,5 +23,5 @@ class GalleryCommentList(
|
||||
@JvmField
|
||||
var comments: Array<GalleryComment>?,
|
||||
@JvmField
|
||||
var hasMore: Boolean
|
||||
) : Parcelable
|
||||
var hasMore: Boolean,
|
||||
) : Parcelable
|
||||
@@ -64,7 +64,7 @@ class GalleryDetail(
|
||||
"Vietnamese",
|
||||
"Polish",
|
||||
"Hungarian",
|
||||
"Dutch"
|
||||
"Dutch",
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -78,20 +78,20 @@ interface GalleryInfo : AbstractGalleryInfo, Parcelable {
|
||||
S_LANG_VI,
|
||||
S_LANG_PL,
|
||||
S_LANG_HU,
|
||||
S_LANG_NL
|
||||
S_LANG_NL,
|
||||
)
|
||||
val S_LANG_PATTERNS = arrayOf(
|
||||
Pattern.compile(
|
||||
"[(\\[]eng(?:lish)?[)\\]]|英訳",
|
||||
Pattern.CASE_INSENSITIVE
|
||||
), // [((\[]ch(?:inese)?[))\]]|[汉漢]化|中[国國][语語]|中文|中国翻訳
|
||||
Pattern.CASE_INSENSITIVE,
|
||||
), // [((\[]ch(?:inese)?[))\]]|[汉漢]化|中[国國][语語]|中文|中国翻訳
|
||||
Pattern.compile(
|
||||
"[(\uFF08\\[]ch(?:inese)?[)\uFF09\\]]|[汉漢]化|中[国國][语語]|中文|中国翻訳",
|
||||
Pattern.CASE_INSENSITIVE
|
||||
Pattern.CASE_INSENSITIVE,
|
||||
),
|
||||
Pattern.compile(
|
||||
"[(\\[]spanish[)\\]]|[(\\[]Español[)\\]]|スペイン翻訳",
|
||||
Pattern.CASE_INSENSITIVE
|
||||
Pattern.CASE_INSENSITIVE,
|
||||
),
|
||||
Pattern.compile("[(\\[]korean?[)\\]]|韓国翻訳", Pattern.CASE_INSENSITIVE),
|
||||
Pattern.compile("[(\\[]rus(?:sian)?[)\\]]|ロシア翻訳", Pattern.CASE_INSENSITIVE),
|
||||
@@ -99,17 +99,17 @@ interface GalleryInfo : AbstractGalleryInfo, Parcelable {
|
||||
Pattern.compile("[(\\[]portuguese|ポルトガル翻訳", Pattern.CASE_INSENSITIVE),
|
||||
Pattern.compile(
|
||||
"[(\\[]thai(?: ภาษาไทย)?[)\\]]|แปลไทย|タイ翻訳",
|
||||
Pattern.CASE_INSENSITIVE
|
||||
Pattern.CASE_INSENSITIVE,
|
||||
),
|
||||
Pattern.compile("[(\\[]german[)\\]]|ドイツ翻訳", Pattern.CASE_INSENSITIVE),
|
||||
Pattern.compile("[(\\[]italiano?[)\\]]|イタリア翻訳", Pattern.CASE_INSENSITIVE),
|
||||
Pattern.compile(
|
||||
"[(\\[]vietnamese(?: Tiếng Việt)?[)\\]]|ベトナム翻訳",
|
||||
Pattern.CASE_INSENSITIVE
|
||||
Pattern.CASE_INSENSITIVE,
|
||||
),
|
||||
Pattern.compile("[(\\[]polish[)\\]]|ポーランド翻訳", Pattern.CASE_INSENSITIVE),
|
||||
Pattern.compile("[(\\[]hun(?:garian)?[)\\]]|ハンガリー翻訳", Pattern.CASE_INSENSITIVE),
|
||||
Pattern.compile("[(\\[]dutch[)\\]]|オランダ翻訳", Pattern.CASE_INSENSITIVE)
|
||||
Pattern.compile("[(\\[]dutch[)\\]]|オランダ翻訳", Pattern.CASE_INSENSITIVE),
|
||||
)
|
||||
val S_LANG_TAGS = arrayOf(
|
||||
"language:english",
|
||||
@@ -125,7 +125,7 @@ interface GalleryInfo : AbstractGalleryInfo, Parcelable {
|
||||
"language:vietnamese",
|
||||
"language:polish",
|
||||
"language:hungarian",
|
||||
"language:dutch"
|
||||
"language:dutch",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,4 +33,4 @@ data class GalleryPreview(
|
||||
view.setClip(offsetX, offsetY, clipWidth, clipHeight)
|
||||
view.load(imageUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,5 +22,5 @@ import kotlinx.parcelize.Parcelize
|
||||
class GalleryTagGroup(
|
||||
private val mTagList: ArrayList<String> = arrayListOf(),
|
||||
@JvmField
|
||||
var groupName: String? = null
|
||||
) : Parcelable, MutableList<String> by mTagList
|
||||
var groupName: String? = null,
|
||||
) : Parcelable, MutableList<String> by mTagList
|
||||
@@ -32,7 +32,8 @@ import java.net.URLDecoder
|
||||
|
||||
@Parcelize
|
||||
data class ListUrlBuilder(
|
||||
@get:Mode @Mode var mode: Int = MODE_NORMAL,
|
||||
@get:Mode @Mode
|
||||
var mode: Int = MODE_NORMAL,
|
||||
private var mPrev: String? = null,
|
||||
private var mNext: String? = null,
|
||||
private var mJumpTo: String? = null,
|
||||
@@ -129,7 +130,9 @@ data class ListUrlBuilder(
|
||||
}
|
||||
return if (q.pageFrom != pageFrom) {
|
||||
false
|
||||
} else q.pageTo == pageTo
|
||||
} else {
|
||||
q.pageTo == pageTo
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -294,7 +297,7 @@ data class ListUrlBuilder(
|
||||
mNext?.let {
|
||||
ub.addQuery("next", it)
|
||||
}
|
||||
// Search key
|
||||
// Search key
|
||||
// the settings of ub:UrlBuilder may be overwritten by following Advance search
|
||||
StringUtils.split(mKeyword, '|')?.forEachIndexed { idx, keyword ->
|
||||
val keyword = keyword.trim { it <= ' ' }
|
||||
@@ -391,7 +394,7 @@ data class ListUrlBuilder(
|
||||
MODE_WHATS_HOT,
|
||||
MODE_IMAGE_SEARCH,
|
||||
MODE_SUBSCRIPTION,
|
||||
MODE_TOPLIST
|
||||
MODE_TOPLIST,
|
||||
)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
private annotation class Mode
|
||||
@@ -404,4 +407,4 @@ data class ListUrlBuilder(
|
||||
const val MODE_SUBSCRIPTION = 0x5
|
||||
const val MODE_TOPLIST = 0x6
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,4 +18,4 @@ package com.hippo.ehviewer.client.exception
|
||||
open class EhException : Exception {
|
||||
constructor(detailMessage: String?) : super(detailMessage)
|
||||
constructor(detailMessage: String?, cause: Throwable?) : super(detailMessage, cause)
|
||||
}
|
||||
}
|
||||
@@ -15,4 +15,4 @@
|
||||
*/
|
||||
package com.hippo.ehviewer.client.exception
|
||||
|
||||
class NoHAtHClientException(detailMessage: String?) : EhException(detailMessage)
|
||||
class NoHAtHClientException(detailMessage: String?) : EhException(detailMessage)
|
||||
@@ -18,4 +18,4 @@ package com.hippo.ehviewer.client.exception
|
||||
/**
|
||||
* It is an exception for get offensive tip for g.e-hentai.org
|
||||
*/
|
||||
class OffensiveException : EhException("OFFENSIVE")
|
||||
class OffensiveException : EhException("OFFENSIVE")
|
||||
@@ -24,8 +24,8 @@ class ParseException : EhException {
|
||||
|
||||
constructor(detailMessage: String?, body: String, cause: Throwable?) : super(
|
||||
detailMessage,
|
||||
cause
|
||||
cause,
|
||||
) {
|
||||
this.body = body
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,4 +15,4 @@
|
||||
*/
|
||||
package com.hippo.ehviewer.client.exception
|
||||
|
||||
class PiningException : EhException("pining for the fjords")
|
||||
class PiningException : EhException("pining for the fjords")
|
||||
@@ -78,7 +78,7 @@ object ArchiveParser {
|
||||
val name: String,
|
||||
val size: String,
|
||||
val cost: String,
|
||||
val isHAtH: Boolean
|
||||
val isHAtH: Boolean,
|
||||
)
|
||||
|
||||
class Result(val paramOr: String?, val archiveList: List<Archive>, var funds: HomeParser.Funds?)
|
||||
|
||||
@@ -53,10 +53,10 @@ object FavoritesParser {
|
||||
class Result(
|
||||
val catArray: Array<String?>,
|
||||
val countArray: IntArray,
|
||||
galleryListResult: GalleryListParser.Result
|
||||
galleryListResult: GalleryListParser.Result,
|
||||
) {
|
||||
val prev = galleryListResult.prev
|
||||
val next = galleryListResult.next
|
||||
val galleryInfoList = galleryListResult.galleryInfoList
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ object GalleryDetailParser {
|
||||
private val PATTERN_ERROR = Regex("<div class=\"d\">\n<p>([^<]+)</p>")
|
||||
private val PATTERN_DETAIL = Regex(
|
||||
"var gid = (\\d+);.+?var token = \"([a-f0-9]+)\";.+?var apiuid = ([\\-\\d]+);.+?var apikey = \"([a-f0-9]+)\";",
|
||||
RegexOption.DOT_MATCHES_ALL
|
||||
RegexOption.DOT_MATCHES_ALL,
|
||||
)
|
||||
private val PATTERN_TORRENT =
|
||||
Regex("<a[^<>]*onclick=\"return popUp\\('([^']+)'[^)]+\\)\">Torrent Download[^<]+(\\d+)[^<]+</a")
|
||||
@@ -170,7 +170,8 @@ object GalleryDetailParser {
|
||||
val ratingCount = gm.getElementById("rating_count")
|
||||
if (null != ratingCount) {
|
||||
gd.ratingCount = NumberUtils.parseIntSafely(
|
||||
StringUtils.trim(ratingCount.text()), 0
|
||||
StringUtils.trim(ratingCount.text()),
|
||||
0,
|
||||
)
|
||||
} else {
|
||||
gd.ratingCount = 0
|
||||
@@ -293,7 +294,7 @@ object GalleryDetailParser {
|
||||
tag = tag.substring(0, index).trim()
|
||||
}
|
||||
if (it.className() == "gtw") {
|
||||
tag = "_$tag" // weak tag
|
||||
tag = "_$tag" // weak tag
|
||||
}
|
||||
group.add(tag)
|
||||
}
|
||||
@@ -370,7 +371,8 @@ object GalleryDetailParser {
|
||||
val es = c5.children()
|
||||
if (!es.isEmpty()) {
|
||||
comment.score = NumberUtils.parseIntSafely(
|
||||
StringUtils.trim(es[0].text()), 0
|
||||
StringUtils.trim(es[0].text()),
|
||||
0,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -428,15 +430,18 @@ object GalleryDetailParser {
|
||||
val list = c1s.mapNotNull { parseComment(it) }
|
||||
val chd = cdiv.getElementById("chd")
|
||||
var hasMore = false
|
||||
NodeTraversor.traverse(object : NodeVisitor {
|
||||
override fun head(node: Node, depth: Int) {
|
||||
if (node is Element && node.text() == "click to show all") {
|
||||
hasMore = true
|
||||
NodeTraversor.traverse(
|
||||
object : NodeVisitor {
|
||||
override fun head(node: Node, depth: Int) {
|
||||
if (node is Element && node.text() == "click to show all") {
|
||||
hasMore = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun tail(node: Node, depth: Int) {}
|
||||
}, chd!!)
|
||||
override fun tail(node: Node, depth: Int) {}
|
||||
},
|
||||
chd!!,
|
||||
)
|
||||
GalleryCommentList(list.toTypedArray(), hasMore)
|
||||
} catch (e: Throwable) {
|
||||
ExceptionUtils.throwIfFatal(e)
|
||||
|
||||
@@ -51,7 +51,7 @@ object GalleryListParser {
|
||||
Triple("64", "176", "240"),
|
||||
Triple("0", "0", "240"),
|
||||
Triple("80", "0", "128"),
|
||||
Triple("224", "128", "224")
|
||||
Triple("224", "128", "224"),
|
||||
)
|
||||
|
||||
private fun parseRating(ratingStyle: String): String? {
|
||||
@@ -71,7 +71,9 @@ object GalleryListParser {
|
||||
rate -= num1 / 16
|
||||
return if (num2 == 21) {
|
||||
"${rate - 1}.5"
|
||||
} else rate.toString()
|
||||
} else {
|
||||
rate.toString()
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseFavoriteSlot(style: String): Int {
|
||||
@@ -334,4 +336,4 @@ object GalleryListParser {
|
||||
var noWatchedTags = false
|
||||
val galleryInfoList = mutableListOf<GalleryInfo>()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ object HomeParser {
|
||||
}
|
||||
|
||||
fun parseResetLimits(body: String): Limits? {
|
||||
return if (body.contains(RESET_SUCCEED)){
|
||||
return if (body.contains(RESET_SUCCEED)) {
|
||||
null
|
||||
} else {
|
||||
parse(body)
|
||||
@@ -41,4 +41,4 @@ object HomeParser {
|
||||
data class Limits(val current: Int = 0, val maximum: Int, val resetCost: Int = 0)
|
||||
data class Funds(val fundsGP: Int, val fundsC: Int)
|
||||
class Result(val limits: Limits, val funds: Funds)
|
||||
}
|
||||
}
|
||||
@@ -15,10 +15,10 @@ fun ImageRequest.Builder.ehUrl(url: String) = apply {
|
||||
|
||||
inline fun Context.imageRequest(
|
||||
url: String,
|
||||
builder: ImageRequest.Builder.() -> Unit = {}
|
||||
builder: ImageRequest.Builder.() -> Unit = {},
|
||||
): ImageRequest {
|
||||
return ImageRequest.Builder(this)
|
||||
.ehUrl(url)
|
||||
.apply(builder)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ object MergeInterceptor : Interceptor {
|
||||
pendingContinuationMap.remove(key)?.forEach { it.resume(Unit) }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
).build()
|
||||
|
||||
pendingContinuationMapLock.lock()
|
||||
|
||||
@@ -72,7 +72,7 @@ fun updateDailyCheckWork(context: Context) {
|
||||
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
|
||||
workName,
|
||||
ExistingPeriodicWorkPolicy.UPDATE,
|
||||
getDailyCheckWorkRequest()
|
||||
getDailyCheckWorkRequest(),
|
||||
)
|
||||
} else {
|
||||
WorkManager.getInstance(context).cancelUniqueWork(workName)
|
||||
@@ -93,7 +93,6 @@ suspend fun checkDawn() = runCatching {
|
||||
it.printStackTrace()
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
fun showEventNotification(html: String) {
|
||||
if (Settings.hideHvEvents && html.contains("You have encountered a monster!")) {
|
||||
|
||||
@@ -3,4 +3,4 @@ package com.hippo.ehviewer.dao
|
||||
interface BasicDao<T> {
|
||||
fun list(): List<T>
|
||||
fun insert(t: T): Long
|
||||
}
|
||||
}
|
||||
@@ -13,4 +13,4 @@ class BookmarkInfo : BaseGalleryInfo() {
|
||||
@JvmField
|
||||
@ColumnInfo(name = "TIME")
|
||||
var time: Long = 0
|
||||
}
|
||||
}
|
||||
@@ -15,4 +15,4 @@ interface BookmarksDao : BasicDao<BookmarkInfo> {
|
||||
|
||||
@Query("SELECT * FROM BOOKMARKS ORDER BY TIME DESC")
|
||||
override fun list(): List<BookmarkInfo>
|
||||
}
|
||||
}
|
||||
@@ -11,5 +11,5 @@ data class DownloadDirname(
|
||||
var gid: Long = 0,
|
||||
|
||||
@ColumnInfo(name = "DIRNAME")
|
||||
var dirname: String? = null
|
||||
)
|
||||
var dirname: String? = null,
|
||||
)
|
||||
@@ -24,4 +24,4 @@ interface DownloadDirnameDao : BasicDao<DownloadDirname> {
|
||||
|
||||
@Query("SELECT * FROM DOWNLOAD_DIRNAME")
|
||||
override fun list(): List<DownloadDirname>
|
||||
}
|
||||
}
|
||||
@@ -66,4 +66,4 @@ class DownloadInfo() : BaseGalleryInfo() {
|
||||
const val STATE_FINISH = 3
|
||||
const val STATE_FAILED = 4
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,5 +14,5 @@ data class DownloadLabel(
|
||||
var label: String? = null,
|
||||
|
||||
@ColumnInfo(name = "TIME")
|
||||
var time: Long = 0
|
||||
)
|
||||
var time: Long = 0,
|
||||
)
|
||||
@@ -25,4 +25,4 @@ interface DownloadLabelDao : BasicDao<DownloadLabel> {
|
||||
|
||||
@Delete
|
||||
fun delete(downloadLabel: DownloadLabel)
|
||||
}
|
||||
}
|
||||
@@ -28,4 +28,4 @@ interface DownloadsDao : BasicDao<DownloadInfo> {
|
||||
|
||||
@Delete
|
||||
fun delete(downloadInfo: DownloadInfo)
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import androidx.room.RoomDatabase
|
||||
@Database(
|
||||
entities = [BookmarkInfo::class, DownloadInfo::class, DownloadLabel::class, DownloadDirname::class, Filter::class, HistoryInfo::class, LocalFavoriteInfo::class, QuickSearch::class],
|
||||
version = 4,
|
||||
exportSchema = false
|
||||
exportSchema = false,
|
||||
)
|
||||
abstract class EhDatabase : RoomDatabase() {
|
||||
abstract fun bookmarksBao(): BookmarksDao
|
||||
|
||||
@@ -20,5 +20,5 @@ data class Filter(
|
||||
|
||||
@PrimaryKey
|
||||
@ColumnInfo(name = "_id")
|
||||
var id: Long? = null
|
||||
)
|
||||
var id: Long? = null,
|
||||
)
|
||||
@@ -22,4 +22,4 @@ interface FilterDao : BasicDao<Filter> {
|
||||
|
||||
@Query("SELECT * FROM FILTER WHERE TEXT = :text AND MODE = :mode")
|
||||
fun load(text: String, mode: Int): Filter?
|
||||
}
|
||||
}
|
||||
@@ -35,4 +35,4 @@ interface HistoryDao : BasicDao<HistoryInfo> {
|
||||
|
||||
@Query("DELETE FROM HISTORY")
|
||||
fun deleteAll()
|
||||
}
|
||||
}
|
||||
@@ -28,4 +28,4 @@ class LocalFavoriteInfo() : BaseGalleryInfo() {
|
||||
init {
|
||||
favoriteSlot = -1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,4 +27,4 @@ interface LocalFavoritesDao : BasicDao<LocalFavoriteInfo> {
|
||||
|
||||
@Query("DELETE FROM LOCAL_FAVORITES WHERE GID = :gid")
|
||||
fun deleteByKey(gid: Long)
|
||||
}
|
||||
}
|
||||
@@ -35,5 +35,5 @@ data class QuickSearch(
|
||||
var pageTo: Int = 0,
|
||||
|
||||
@ColumnInfo(name = "TIME")
|
||||
var time: Long = 0
|
||||
)
|
||||
var time: Long = 0,
|
||||
)
|
||||
@@ -25,4 +25,4 @@ interface QuickSearchDao : BasicDao<QuickSearch> {
|
||||
|
||||
@Delete
|
||||
fun delete(quickSearch: QuickSearch)
|
||||
}
|
||||
}
|
||||
@@ -826,7 +826,7 @@ object DownloadManager : OnSpiderListener {
|
||||
index: Int,
|
||||
contentLength: Long,
|
||||
receivedSize: Long,
|
||||
bytesRead: Int
|
||||
bytesRead: Int,
|
||||
) {
|
||||
var task = mNotifyTaskPool.pop()
|
||||
if (task == null) {
|
||||
@@ -850,7 +850,7 @@ object DownloadManager : OnSpiderListener {
|
||||
error: String?,
|
||||
finished: Int,
|
||||
downloaded: Int,
|
||||
total: Int
|
||||
total: Int,
|
||||
) {
|
||||
var task = mNotifyTaskPool.pop()
|
||||
if (task == null) {
|
||||
@@ -972,7 +972,7 @@ object DownloadManager : OnSpiderListener {
|
||||
index: Int,
|
||||
contentLength: Long,
|
||||
receivedSize: Long,
|
||||
bytesRead: Int
|
||||
bytesRead: Int,
|
||||
) {
|
||||
mType = TYPE_ON_PAGE_DOWNLOAD
|
||||
mIndex = index
|
||||
@@ -994,7 +994,7 @@ object DownloadManager : OnSpiderListener {
|
||||
error: String?,
|
||||
finished: Int,
|
||||
downloaded: Int,
|
||||
total: Int
|
||||
total: Int,
|
||||
) {
|
||||
mType = TYPE_ON_PAGE_FAILURE
|
||||
mIndex = index
|
||||
@@ -1038,7 +1038,7 @@ object DownloadManager : OnSpiderListener {
|
||||
mIndex,
|
||||
mContentLength,
|
||||
mReceivedSize,
|
||||
mBytesRead
|
||||
mBytesRead,
|
||||
)
|
||||
|
||||
TYPE_ON_PAGE_SUCCESS -> {
|
||||
@@ -1229,4 +1229,4 @@ object DownloadManager : OnSpiderListener {
|
||||
private fun MutableList<DownloadInfo>.sortByDateDescending() {
|
||||
sortByDescending { it.time }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,10 +60,10 @@ class DownloadService : Service(), DownloadManager.DownloadListener {
|
||||
mNotifyManager!!.createNotificationChannel(
|
||||
NotificationChannelCompat.Builder(
|
||||
mChannelID!!,
|
||||
NotificationManagerCompat.IMPORTANCE_LOW
|
||||
NotificationManagerCompat.IMPORTANCE_LOW,
|
||||
)
|
||||
.setName(getString(R.string.download_service))
|
||||
.build()
|
||||
.build(),
|
||||
)
|
||||
mDownloadManager = DownloadManager
|
||||
mDownloadManager!!.setDownloadListener(this)
|
||||
@@ -166,7 +166,7 @@ class DownloadService : Service(), DownloadManager.DownloadListener {
|
||||
.addAction(
|
||||
R.drawable.v_pause_x24,
|
||||
getString(R.string.stat_download_action_stop_all),
|
||||
piStopAll
|
||||
piStopAll,
|
||||
)
|
||||
.setShowWhen(false)
|
||||
.setChannelId(mChannelID!!)
|
||||
@@ -187,8 +187,10 @@ class DownloadService : Service(), DownloadManager.DownloadListener {
|
||||
activityIntent.action = ACTION_START_DOWNLOADSCENE
|
||||
activityIntent.putExtra(ACTION_START_DOWNLOADSCENE_ARGS, bundle)
|
||||
val piActivity = PendingIntent.getActivity(
|
||||
this@DownloadService, 0,
|
||||
activityIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
this@DownloadService,
|
||||
0,
|
||||
activityIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
|
||||
)
|
||||
mDownloadedBuilder = NotificationCompat.Builder(applicationContext, mChannelID!!)
|
||||
.setSmallIcon(android.R.drawable.stat_sys_download_done)
|
||||
@@ -210,7 +212,7 @@ class DownloadService : Service(), DownloadManager.DownloadListener {
|
||||
.setContentText(getString(R.string.stat_509_alert_title))
|
||||
.setContentText(getString(R.string.stat_509_alert_text))
|
||||
.setStyle(
|
||||
NotificationCompat.BigTextStyle().bigText(getString(R.string.stat_509_alert_text))
|
||||
NotificationCompat.BigTextStyle().bigText(getString(R.string.stat_509_alert_text)),
|
||||
)
|
||||
.setAutoCancel(true)
|
||||
.setOngoing(false)
|
||||
@@ -241,8 +243,10 @@ class DownloadService : Service(), DownloadManager.DownloadListener {
|
||||
activityIntent.action = ACTION_START_DOWNLOADSCENE
|
||||
activityIntent.putExtra(ACTION_START_DOWNLOADSCENE_ARGS, bundle)
|
||||
val piActivity = PendingIntent.getActivity(
|
||||
this@DownloadService, 0,
|
||||
activityIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
this@DownloadService,
|
||||
0,
|
||||
activityIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
|
||||
)
|
||||
mDownloadingBuilder!!.setContentTitle(EhUtils.getSuitableTitle(info))
|
||||
.setContentText(null)
|
||||
@@ -267,7 +271,7 @@ class DownloadService : Service(), DownloadManager.DownloadListener {
|
||||
getString(
|
||||
R.string.download_speed_text_2,
|
||||
text,
|
||||
ReadableTime.getShortTimeInterval(remaining)
|
||||
ReadableTime.getShortTimeInterval(remaining),
|
||||
)
|
||||
} else {
|
||||
getString(R.string.download_speed_text, text)
|
||||
@@ -327,7 +331,7 @@ class DownloadService : Service(), DownloadManager.DownloadListener {
|
||||
text = if (sItemTitleArray.size() >= 1) {
|
||||
getString(
|
||||
R.string.stat_download_done_line_succeeded,
|
||||
sItemTitleArray.valueAt(0)
|
||||
sItemTitleArray.valueAt(0),
|
||||
)
|
||||
} else {
|
||||
Log.d("TAG", "WTF, sItemTitleArray is null")
|
||||
@@ -343,7 +347,7 @@ class DownloadService : Service(), DownloadManager.DownloadListener {
|
||||
text = if (sItemTitleArray.size() >= 1) {
|
||||
getString(
|
||||
R.string.stat_download_done_line_failed,
|
||||
sItemTitleArray.valueAt(0)
|
||||
sItemTitleArray.valueAt(0),
|
||||
)
|
||||
} else {
|
||||
Log.d("TAG", "WTF, sItemTitleArray is null")
|
||||
@@ -376,8 +380,8 @@ class DownloadService : Service(), DownloadManager.DownloadListener {
|
||||
style.addLine(
|
||||
getString(
|
||||
if (fin) R.string.stat_download_done_line_succeeded else R.string.stat_download_done_line_failed,
|
||||
title
|
||||
)
|
||||
title,
|
||||
),
|
||||
)
|
||||
i++
|
||||
}
|
||||
@@ -413,7 +417,7 @@ class DownloadService : Service(), DownloadManager.DownloadListener {
|
||||
private var mService: Service,
|
||||
private val mNotifyManager: NotificationManagerCompat,
|
||||
private val mBuilder: NotificationCompat.Builder,
|
||||
private val mId: Int
|
||||
private val mId: Int,
|
||||
) : Runnable {
|
||||
private var mLastTime: Long = 0
|
||||
private var mPosted = false
|
||||
@@ -431,7 +435,7 @@ class DownloadService : Service(), DownloadManager.DownloadListener {
|
||||
// Wait long enough, do it now
|
||||
if (ActivityCompat.checkSelfPermission(
|
||||
mService,
|
||||
Manifest.permission.POST_NOTIFICATIONS
|
||||
Manifest.permission.POST_NOTIFICATIONS,
|
||||
) != PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
return
|
||||
@@ -487,7 +491,7 @@ class DownloadService : Service(), DownloadManager.DownloadListener {
|
||||
OPS_NOTIFY -> {
|
||||
if (ActivityCompat.checkSelfPermission(
|
||||
mService,
|
||||
Manifest.permission.POST_NOTIFICATIONS
|
||||
Manifest.permission.POST_NOTIFICATIONS,
|
||||
) != PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
return
|
||||
@@ -547,4 +551,4 @@ class DownloadService : Service(), DownloadManager.DownloadListener {
|
||||
sItemTitleArray.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ class EhPageLoader(private val mGalleryInfo: GalleryInfo) : PageLoader2(), OnSpi
|
||||
"%d-%s-%08d",
|
||||
mGalleryInfo.gid,
|
||||
mGalleryInfo.token,
|
||||
index + 1
|
||||
index + 1,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ class EhPageLoader(private val mGalleryInfo: GalleryInfo) : PageLoader2(), OnSpi
|
||||
mGalleryInfo.gid,
|
||||
mGalleryInfo.token,
|
||||
index + 1,
|
||||
extension
|
||||
extension,
|
||||
)
|
||||
}
|
||||
return String.format(
|
||||
@@ -69,7 +69,7 @@ class EhPageLoader(private val mGalleryInfo: GalleryInfo) : PageLoader2(), OnSpi
|
||||
"%d-%s-%08d",
|
||||
mGalleryInfo.gid,
|
||||
mGalleryInfo.token,
|
||||
index + 1
|
||||
index + 1,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ class EhPageLoader(private val mGalleryInfo: GalleryInfo) : PageLoader2(), OnSpi
|
||||
index: Int,
|
||||
contentLength: Long,
|
||||
receivedSize: Long,
|
||||
bytesRead: Int
|
||||
bytesRead: Int,
|
||||
) {
|
||||
if (contentLength > 0) {
|
||||
notifyPagePercent(index, receivedSize.toFloat() / contentLength)
|
||||
@@ -128,7 +128,7 @@ class EhPageLoader(private val mGalleryInfo: GalleryInfo) : PageLoader2(), OnSpi
|
||||
error: String?,
|
||||
finished: Int,
|
||||
downloaded: Int,
|
||||
total: Int
|
||||
total: Int,
|
||||
) {
|
||||
notifyPageFailed(index, error)
|
||||
}
|
||||
@@ -152,4 +152,4 @@ class EhPageLoader(private val mGalleryInfo: GalleryInfo) : PageLoader2(), OnSpi
|
||||
mSpiderQueen = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ abstract class PageLoader2 : PageLoader() {
|
||||
}
|
||||
|
||||
val SUPPORT_IMAGE_EXTENSIONS = arrayOf(
|
||||
".jpg", // Joint Photographic Experts Group
|
||||
".png", // Portable Network Graphics
|
||||
".gif"
|
||||
".jpg", // Joint Photographic Experts Group
|
||||
".png", // Portable Network Graphics
|
||||
".gif",
|
||||
)
|
||||
@@ -9,7 +9,7 @@ private val OBSOLETE_CACHE_DIRS = arrayOf(
|
||||
"image",
|
||||
"thumb",
|
||||
"gallery_image",
|
||||
"spider_info"
|
||||
"spider_info",
|
||||
)
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
|
||||
@@ -33,7 +33,8 @@ import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import java.util.LinkedList
|
||||
|
||||
class AccountPreference @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
) : MessagePreference(context, attrs) {
|
||||
private val mActivity = context as SettingsActivity
|
||||
private var message: String? = null
|
||||
@@ -59,16 +60,19 @@ class AccountPreference @JvmOverloads constructor(
|
||||
i++
|
||||
}
|
||||
if (ipbMemberId != null || ipbPassHash != null || igneous != null) {
|
||||
message = (EhCookieStore.KEY_IPB_MEMBER_ID + ": " + ipbMemberId + "<br>"
|
||||
+ EhCookieStore.KEY_IPB_PASS_HASH + ": " + ipbPassHash + "<br>"
|
||||
+ EhCookieStore.KEY_IGNEOUS + ": " + igneous)
|
||||
message = (
|
||||
EhCookieStore.KEY_IPB_MEMBER_ID + ": " + ipbMemberId + "<br>" +
|
||||
EhCookieStore.KEY_IPB_PASS_HASH + ": " + ipbPassHash + "<br>" +
|
||||
EhCookieStore.KEY_IGNEOUS + ": " + igneous
|
||||
)
|
||||
setDialogMessage(
|
||||
Html.fromHtml(
|
||||
context.getString(
|
||||
R.string.settings_eh_identity_cookies_signed,
|
||||
message
|
||||
), Html.FROM_HTML_MODE_LEGACY
|
||||
)
|
||||
message,
|
||||
),
|
||||
Html.FROM_HTML_MODE_LEGACY,
|
||||
),
|
||||
)
|
||||
message = message!!.replace("<br>", "\n")
|
||||
} else {
|
||||
@@ -89,4 +93,4 @@ class AccountPreference @JvmOverloads constructor(
|
||||
mActivity.showTip(R.string.settings_eh_sign_out_tip, BaseScene.LENGTH_SHORT)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@ package com.hippo.ehviewer.preference
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import com.hippo.ehviewer.download.DownloadManager as downloadManager
|
||||
import com.hippo.ehviewer.GetText
|
||||
import com.hippo.ehviewer.R
|
||||
import com.hippo.ehviewer.Settings
|
||||
@@ -26,6 +25,7 @@ import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import com.hippo.ehviewer.download.DownloadManager as downloadManager
|
||||
|
||||
private val NO_REDUNDANCY =
|
||||
GetText.getString(R.string.settings_download_clean_redundancy_no_redundancy)
|
||||
@@ -35,7 +35,8 @@ private val FINAL_CLEAR_REDUNDANCY_MSG =
|
||||
{ cnt: Int -> if (cnt == 0) NO_REDUNDANCY else CLEAR_REDUNDANCY_DONE(cnt) }
|
||||
|
||||
class CleanRedundancyPreference @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
) : TaskPreference(context, attrs) {
|
||||
private fun clearFile(file: UniFile): Boolean {
|
||||
var name = file.name ?: return false
|
||||
@@ -56,16 +57,19 @@ class CleanRedundancyPreference @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
override fun launchJob() {
|
||||
if (singletonJob?.isActive == true) singletonJob?.invokeOnCompletion {
|
||||
launchUI {
|
||||
dialog.dismiss()
|
||||
if (singletonJob?.isActive == true) {
|
||||
singletonJob?.invokeOnCompletion {
|
||||
launchUI {
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
else singletonJob = launch {
|
||||
val cnt = doRealWork()
|
||||
withUIContext {
|
||||
showTip(FINAL_CLEAR_REDUNDANCY_MSG(cnt))
|
||||
dialog.dismiss()
|
||||
} else {
|
||||
singletonJob = launch {
|
||||
val cnt = doRealWork()
|
||||
withUIContext {
|
||||
showTip(FINAL_CLEAR_REDUNDANCY_MSG(cnt))
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ class ImageLimitsPreference(context: Context, attrs: AttributeSet) :
|
||||
val (fundsGP, fundsC) = mActivity.mFunds!!
|
||||
val cost = if (fundsGP >= resetCost) "$resetCost GP" else "$resetCost Credits"
|
||||
val message = mActivity.getString(R.string.current_limits, "$current / $maximum", cost) +
|
||||
"\n" + mActivity.getString(R.string.current_funds, "$fundsGP+", fundsC)
|
||||
"\n" + mActivity.getString(R.string.current_funds, "$fundsGP+", fundsC)
|
||||
mDialog.setMessage(message)
|
||||
resetButton.isEnabled = resetCost in 1..maxOf(fundsGP, fundsC)
|
||||
}
|
||||
@@ -83,4 +83,4 @@ class ImageLimitsPreference(context: Context, attrs: AttributeSet) :
|
||||
mActivity.resetImageLimits()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,8 @@ import com.hippo.yorozuya.MathUtils
|
||||
import com.hippo.yorozuya.ViewUtils
|
||||
|
||||
class ProxyPreference @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
) : DialogPreference(context, attrs), View.OnClickListener {
|
||||
private var mType: TextInputLayout? = null
|
||||
private var mIpInputLayout: TextInputLayout? = null
|
||||
@@ -56,8 +57,8 @@ class ProxyPreference @JvmOverloads constructor(
|
||||
|
||||
private fun updateSummary(type: Int, ip: String?, port: Int) {
|
||||
var type1 = type
|
||||
if ((type1 == EhProxySelector.TYPE_HTTP || type1 == EhProxySelector.TYPE_SOCKS)
|
||||
&& (TextUtils.isEmpty(ip) || !InetValidator.isValidInetPort(port))
|
||||
if ((type1 == EhProxySelector.TYPE_HTTP || type1 == EhProxySelector.TYPE_SOCKS) &&
|
||||
(TextUtils.isEmpty(ip) || !InetValidator.isValidInetPort(port))
|
||||
) {
|
||||
type1 = EhProxySelector.TYPE_SYSTEM
|
||||
}
|
||||
@@ -67,13 +68,13 @@ class ProxyPreference @JvmOverloads constructor(
|
||||
R.string.settings_advanced_proxy_summary_1,
|
||||
getProxyTypeText(type1),
|
||||
ip,
|
||||
port
|
||||
port,
|
||||
)
|
||||
} else {
|
||||
val context = context
|
||||
context.getString(
|
||||
R.string.settings_advanced_proxy_summary_2,
|
||||
getProxyTypeText(type1)
|
||||
getProxyTypeText(type1),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -95,11 +96,14 @@ class ProxyPreference @JvmOverloads constructor(
|
||||
mPort = ViewUtils.`$$`(dialog, R.id.port) as EditText
|
||||
val type = Settings.proxyType
|
||||
(mType!!.editText as AutoCompleteTextView).setText(
|
||||
array[MathUtils.clamp(
|
||||
type,
|
||||
0,
|
||||
array.size
|
||||
)], false
|
||||
array[
|
||||
MathUtils.clamp(
|
||||
type,
|
||||
0,
|
||||
array.size,
|
||||
),
|
||||
],
|
||||
false,
|
||||
)
|
||||
mIp!!.setText(Settings.proxyIp)
|
||||
val portString: String?
|
||||
@@ -164,4 +168,4 @@ class ProxyPreference @JvmOverloads constructor(
|
||||
EhApplication.ehProxySelector.updateProxy()
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@ package com.hippo.ehviewer.preference
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import com.hippo.ehviewer.download.DownloadManager as downloadManager
|
||||
import com.hippo.ehviewer.EhDB
|
||||
import com.hippo.ehviewer.GetText
|
||||
import com.hippo.ehviewer.R
|
||||
@@ -35,6 +34,7 @@ import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import moe.tarsin.coroutines.runSuspendCatching
|
||||
import com.hippo.ehviewer.download.DownloadManager as downloadManager
|
||||
|
||||
private val RESTORE_NOT_FOUND = GetText.getString(R.string.settings_download_restore_not_found)
|
||||
private val RESTORE_FAILED = GetText.getString(R.string.settings_download_restore_failed)
|
||||
@@ -42,7 +42,8 @@ private val RESTORE_COUNT_MSG =
|
||||
{ cnt: Int -> if (cnt == 0) RESTORE_NOT_FOUND else GetText.getString(R.string.settings_download_restore_successfully, cnt) }
|
||||
|
||||
class RestoreDownloadPreference @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
) : TaskPreference(context, attrs) {
|
||||
private val mManager: DownloadManager = downloadManager
|
||||
private var restoreDirCount = 0
|
||||
@@ -88,39 +89,42 @@ class RestoreDownloadPreference @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
override fun launchJob() {
|
||||
if (singletonJob?.isActive == true) singletonJob?.invokeOnCompletion {
|
||||
launchUI {
|
||||
dialog.dismiss()
|
||||
if (singletonJob?.isActive == true) {
|
||||
singletonJob?.invokeOnCompletion {
|
||||
launchUI {
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
else singletonJob = launch {
|
||||
val result = doRealWork()
|
||||
withUIContext {
|
||||
if (result == null) {
|
||||
showTip(RESTORE_FAILED)
|
||||
} else {
|
||||
if (result.isEmpty()) {
|
||||
showTip(RESTORE_COUNT_MSG(restoreDirCount))
|
||||
} else {
|
||||
singletonJob = launch {
|
||||
val result = doRealWork()
|
||||
withUIContext {
|
||||
if (result == null) {
|
||||
showTip(RESTORE_FAILED)
|
||||
} else {
|
||||
var count = 0
|
||||
var i = 0
|
||||
val n = result.size
|
||||
while (i < n) {
|
||||
val item = result[i]
|
||||
// Avoid failed gallery info
|
||||
if (null != item.title) {
|
||||
// Put to download
|
||||
mManager.addDownload(item, null)
|
||||
// Put download dir to DB
|
||||
EhDB.putDownloadDirname(item.gid, (item as RestoreItem).dirname)
|
||||
count++
|
||||
if (result.isEmpty()) {
|
||||
showTip(RESTORE_COUNT_MSG(restoreDirCount))
|
||||
} else {
|
||||
var count = 0
|
||||
var i = 0
|
||||
val n = result.size
|
||||
while (i < n) {
|
||||
val item = result[i]
|
||||
// Avoid failed gallery info
|
||||
if (null != item.title) {
|
||||
// Put to download
|
||||
mManager.addDownload(item, null)
|
||||
// Put download dir to DB
|
||||
EhDB.putDownloadDirname(item.gid, (item as RestoreItem).dirname)
|
||||
count++
|
||||
}
|
||||
i++
|
||||
}
|
||||
i++
|
||||
showTip(RESTORE_COUNT_MSG(count + restoreDirCount))
|
||||
}
|
||||
showTip(RESTORE_COUNT_MSG(count + restoreDirCount))
|
||||
}
|
||||
dialog.dismiss()
|
||||
}
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
|
||||
abstract class TaskPreference @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
) : DialogPreference(context, attrs), CoroutineScope {
|
||||
override val coroutineContext = Dispatchers.IO + Job()
|
||||
protected lateinit var dialog: AlertDialog
|
||||
@@ -47,7 +48,7 @@ abstract class TaskPreference @JvmOverloads constructor(
|
||||
protected fun showTip(msg: String) {
|
||||
(context as SettingsActivity).showTip(
|
||||
msg,
|
||||
Snackbar.LENGTH_SHORT
|
||||
Snackbar.LENGTH_SHORT,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -22,11 +22,12 @@ import com.hippo.ehviewer.BuildConfig
|
||||
import com.hippo.ehviewer.R
|
||||
|
||||
class VersionPreference @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
) : Preference(context, attrs) {
|
||||
init {
|
||||
setTitle(R.string.settings_about_version)
|
||||
summary = "${BuildConfig.VERSION_NAME} (${BuildConfig.COMMIT_SHA})\n" +
|
||||
context.getString(R.string.settings_about_build_time, BuildConfig.BUILD_TIME)
|
||||
context.getString(R.string.settings_about_build_time, BuildConfig.BUILD_TIME)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,9 +30,9 @@ import com.hippo.ehviewer.coil.read
|
||||
import com.hippo.ehviewer.gallery.SUPPORT_IMAGE_EXTENSIONS
|
||||
import com.hippo.image.Image.CloseableSource
|
||||
import com.hippo.image.rewriteGifSource2
|
||||
import com.hippo.util.sendTo
|
||||
import com.hippo.unifile.UniFile
|
||||
import com.hippo.unifile.openOutputStream
|
||||
import com.hippo.util.sendTo
|
||||
import com.hippo.yorozuya.FileUtils
|
||||
import io.ktor.client.plugins.onDownload
|
||||
import io.ktor.client.request.prepareGet
|
||||
@@ -136,7 +136,7 @@ class SpiderDen(private val mGalleryInfo: GalleryInfo) {
|
||||
index: Int,
|
||||
url: String,
|
||||
referer: String?,
|
||||
notifyProgress: (Long, Long, Int) -> Unit
|
||||
notifyProgress: (Long, Long, Int) -> Unit,
|
||||
): Boolean {
|
||||
return client.prepareGet(url) {
|
||||
var state: Long = 0
|
||||
@@ -161,10 +161,11 @@ class SpiderDen(private val mGalleryInfo: GalleryInfo) {
|
||||
outFile.openOutputStream().use {
|
||||
ret = body.bodyAsChannel().copyTo(it.channel)
|
||||
}
|
||||
if (contentType == ContentType.Image.GIF)
|
||||
if (contentType == ContentType.Image.GIF) {
|
||||
outFile.openFileDescriptor("rw").use {
|
||||
rewriteGifSource2(it.fd)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class SpiderInfo @JvmOverloads constructor(
|
||||
|
||||
var previewPages: Int = -1,
|
||||
|
||||
var previewPerPage: Int = -1
|
||||
var previewPerPage: Int = -1,
|
||||
)
|
||||
|
||||
fun SpiderInfo.write(file: UniFile) {
|
||||
|
||||
@@ -20,7 +20,6 @@ import android.util.Log
|
||||
import androidx.annotation.IntDef
|
||||
import androidx.collection.LongSparseArray
|
||||
import androidx.collection.set
|
||||
import com.hippo.ehviewer.EhApplication.Companion.okHttpClient as plainTextOkHttpClient
|
||||
import com.hippo.ehviewer.GetText
|
||||
import com.hippo.ehviewer.R
|
||||
import com.hippo.ehviewer.Settings
|
||||
@@ -33,8 +32,8 @@ import com.hippo.ehviewer.client.EhUrl.referer
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo
|
||||
import com.hippo.ehviewer.client.exception.ParseException
|
||||
import com.hippo.ehviewer.client.parser.GalleryDetailParser.parsePages
|
||||
import com.hippo.ehviewer.client.parser.GalleryDetailParser.parsePreviewPages
|
||||
import com.hippo.ehviewer.client.parser.GalleryDetailParser.parsePreviewList
|
||||
import com.hippo.ehviewer.client.parser.GalleryDetailParser.parsePreviewPages
|
||||
import com.hippo.ehviewer.client.parser.GalleryMultiPageViewerPTokenParser
|
||||
import com.hippo.ehviewer.client.parser.GalleryPageUrlParser
|
||||
import com.hippo.image.Image
|
||||
@@ -57,6 +56,7 @@ import moe.tarsin.coroutines.runSuspendCatching
|
||||
import okhttp3.executeAsync
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import com.hippo.ehviewer.EhApplication.Companion.okHttpClient as plainTextOkHttpClient
|
||||
|
||||
class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineScope {
|
||||
override val coroutineContext = Dispatchers.IO + Job()
|
||||
@@ -103,7 +103,7 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
|
||||
index,
|
||||
contentLength,
|
||||
receivedSize,
|
||||
bytesRead
|
||||
bytesRead,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -116,7 +116,7 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
|
||||
index,
|
||||
mFinishedPages.get(),
|
||||
mDownloadedPages.get(),
|
||||
mPageStateArray.size
|
||||
mPageStateArray.size,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,7 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
|
||||
error,
|
||||
mFinishedPages.get(),
|
||||
mDownloadedPages.get(),
|
||||
mPageStateArray.size
|
||||
mPageStateArray.size,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -142,7 +142,7 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
|
||||
it.onFinish(
|
||||
mFinishedPages.get(),
|
||||
mDownloadedPages.get(),
|
||||
mPageStateArray.size
|
||||
mPageStateArray.size,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -298,7 +298,9 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
|
||||
val state = getPageState(index)
|
||||
return if (STATE_FINISHED != state) {
|
||||
false
|
||||
} else mSpiderDen.saveToUniFile(index, file)
|
||||
} else {
|
||||
mSpiderDen.saveToUniFile(index, file)
|
||||
}
|
||||
}
|
||||
|
||||
fun save(index: Int, dir: UniFile, filename: String): UniFile? {
|
||||
@@ -315,7 +317,9 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
|
||||
val state = getPageState(index)
|
||||
return if (STATE_FINISHED != state) {
|
||||
null
|
||||
} else mSpiderDen.getExtension(index)
|
||||
} else {
|
||||
mSpiderDen.getExtension(index)
|
||||
}
|
||||
}
|
||||
|
||||
val startPage: Int
|
||||
@@ -358,8 +362,12 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
|
||||
private suspend fun readSpiderInfoFromInternet(): SpiderInfo? {
|
||||
val request = EhRequestBuilder(
|
||||
getGalleryDetailUrl(
|
||||
galleryInfo.gid, galleryInfo.token, 0, false
|
||||
), referer
|
||||
galleryInfo.gid,
|
||||
galleryInfo.token,
|
||||
0,
|
||||
false,
|
||||
),
|
||||
referer,
|
||||
).build()
|
||||
return runSuspendCatching {
|
||||
plainTextOkHttpClient.newCall(request).executeAsync().use { response ->
|
||||
@@ -378,7 +386,8 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
|
||||
suspend fun getPTokenFromMultiPageViewer(index: Int): String? {
|
||||
val spiderInfo = mSpiderInfo
|
||||
val url = getGalleryMultiPageViewerUrl(
|
||||
galleryInfo.gid, galleryInfo.token!!
|
||||
galleryInfo.gid,
|
||||
galleryInfo.token!!,
|
||||
)
|
||||
val referer = referer
|
||||
val request = EhRequestBuilder(url, referer).build()
|
||||
@@ -411,7 +420,10 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
|
||||
previewIndex = previewIndex.coerceAtMost(spiderInfo.previewPages - 1)
|
||||
}
|
||||
val url = getGalleryDetailUrl(
|
||||
galleryInfo.gid, galleryInfo.token, previewIndex, false
|
||||
galleryInfo.gid,
|
||||
galleryInfo.token,
|
||||
previewIndex,
|
||||
false,
|
||||
)
|
||||
val referer = referer
|
||||
val request = EhRequestBuilder(url, referer).build()
|
||||
@@ -552,12 +564,14 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
|
||||
if (isDownloadMode) return
|
||||
synchronized(mFetcherJobMap) {
|
||||
mFetcherJobMap.forEach { (i, job) ->
|
||||
if (i < cancelBounds.first || i > cancelBounds.second)
|
||||
if (i < cancelBounds.first || i > cancelBounds.second) {
|
||||
job.cancel()
|
||||
}
|
||||
}
|
||||
list.forEach {
|
||||
if (mFetcherJobMap[it]?.isActive != true)
|
||||
if (mFetcherJobMap[it]?.isActive != true) {
|
||||
doLaunchDownloadJob(it, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -615,7 +629,7 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
|
||||
pToken = getPToken(index) ?: return updatePageState(
|
||||
index,
|
||||
STATE_FAILED,
|
||||
PTOKEN_FAILED_MESSAGE
|
||||
PTOKEN_FAILED_MESSAGE,
|
||||
).also {
|
||||
mSpiderInfo.pTokenMap[index] = TOKEN_FAILED
|
||||
}
|
||||
@@ -697,7 +711,7 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
|
||||
index,
|
||||
pToken,
|
||||
localShowKey,
|
||||
previousPToken
|
||||
previousPToken,
|
||||
).also {
|
||||
if (check509(it.imageUrl)) {
|
||||
// Get 509
|
||||
@@ -742,7 +756,7 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
|
||||
val success: Boolean = mSpiderDen.makeHttpCallAndSaveImage(
|
||||
index,
|
||||
targetImageUrl,
|
||||
referer
|
||||
referer,
|
||||
) { contentLength: Long, receivedSize: Long, bytesRead: Int ->
|
||||
mPagePercentMap[index] = receivedSize.toFloat() / contentLength
|
||||
notifyPageDownload(index, contentLength, receivedSize, bytesRead)
|
||||
@@ -826,8 +840,8 @@ private val URL_509_ARRAY = arrayOf(
|
||||
"https://ehgt.org/g/509.gif",
|
||||
"https://ehgt.org/g/509s.gif",
|
||||
"https://exhentai.org/img/509.gif",
|
||||
"https://exhentai.org/img/509s.gif"
|
||||
"https://exhentai.org/img/509s.gif",
|
||||
)
|
||||
private const val WORKER_DEBUG_TAG = "SpiderQueenWorker"
|
||||
|
||||
private fun check509(url: String) = url in URL_509_ARRAY
|
||||
private fun check509(url: String) = url in URL_509_ARRAY
|
||||
@@ -39,8 +39,10 @@ import com.hippo.ehviewer.download.DownloadManager as downloadManager
|
||||
|
||||
object CommonOperations {
|
||||
private fun doAddToFavorites(
|
||||
activity: Activity, galleryInfo: GalleryInfo,
|
||||
slot: Int, listener: EhClient.Callback<Unit>
|
||||
activity: Activity,
|
||||
galleryInfo: GalleryInfo,
|
||||
slot: Int,
|
||||
listener: EhClient.Callback<Unit>,
|
||||
) {
|
||||
when (slot) {
|
||||
-1 -> {
|
||||
@@ -64,8 +66,10 @@ object CommonOperations {
|
||||
|
||||
@JvmOverloads
|
||||
fun addToFavorites(
|
||||
activity: Activity, galleryInfo: GalleryInfo,
|
||||
listener: EhClient.Callback<Unit>, select: Boolean = false
|
||||
activity: Activity,
|
||||
galleryInfo: GalleryInfo,
|
||||
listener: EhClient.Callback<Unit>,
|
||||
select: Boolean = false,
|
||||
) {
|
||||
val slot = Settings.defaultFavSlot
|
||||
val localFav = activity.getString(R.string.local_favorites)
|
||||
@@ -76,11 +80,12 @@ object CommonOperations {
|
||||
activity,
|
||||
galleryInfo,
|
||||
slot,
|
||||
DelegateFavoriteCallback(listener, galleryInfo, newFavoriteName, slot)
|
||||
DelegateFavoriteCallback(listener, galleryInfo, newFavoriteName, slot),
|
||||
)
|
||||
} else {
|
||||
ListCheckBoxDialogBuilder(
|
||||
activity, items,
|
||||
activity,
|
||||
items,
|
||||
{ builder: ListCheckBoxDialogBuilder?, _: AlertDialog?, position: Int ->
|
||||
val slot1 = position - 1
|
||||
val newFavoriteName = if (slot1 in 0..9) items[slot1 + 1] else null
|
||||
@@ -88,14 +93,16 @@ object CommonOperations {
|
||||
activity,
|
||||
galleryInfo,
|
||||
slot1,
|
||||
DelegateFavoriteCallback(listener, galleryInfo, newFavoriteName, slot1)
|
||||
DelegateFavoriteCallback(listener, galleryInfo, newFavoriteName, slot1),
|
||||
)
|
||||
if (builder?.isChecked == true) {
|
||||
Settings.putDefaultFavSlot(slot1)
|
||||
} else {
|
||||
Settings.putDefaultFavSlot(Settings.INVALID_DEFAULT_FAV_SLOT)
|
||||
}
|
||||
}, activity.getString(R.string.remember_favorite_collection), false
|
||||
},
|
||||
activity.getString(R.string.remember_favorite_collection),
|
||||
false,
|
||||
)
|
||||
.setTitle(R.string.add_favorites_dialog_title)
|
||||
.setOnCancelListener { listener.onCancel() }
|
||||
@@ -104,8 +111,9 @@ object CommonOperations {
|
||||
}
|
||||
|
||||
fun removeFromFavorites(
|
||||
activity: Activity?, galleryInfo: GalleryInfo,
|
||||
listener: EhClient.Callback<Unit>
|
||||
activity: Activity?,
|
||||
galleryInfo: GalleryInfo,
|
||||
listener: EhClient.Callback<Unit>,
|
||||
) {
|
||||
EhDB.removeLocalFavorites(galleryInfo.gid)
|
||||
val request = EhRequest()
|
||||
@@ -122,7 +130,7 @@ object CommonOperations {
|
||||
fun startDownload(
|
||||
activity: MainActivity,
|
||||
galleryInfos: List<GalleryInfo>,
|
||||
forceDefault: Boolean
|
||||
forceDefault: Boolean,
|
||||
) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
application.topActivity?.checkAndRequestNotificationPermission()
|
||||
@@ -133,7 +141,7 @@ object CommonOperations {
|
||||
private fun doStartDownload(
|
||||
activity: MainActivity,
|
||||
galleryInfos: List<GalleryInfo>,
|
||||
forceDefault: Boolean
|
||||
forceDefault: Boolean,
|
||||
) {
|
||||
val dm = downloadManager
|
||||
val toStart = LongList()
|
||||
@@ -185,7 +193,8 @@ object CommonOperations {
|
||||
items.add(activity.getString(R.string.default_download_label_name))
|
||||
items.addAll(list.mapNotNull { it.label })
|
||||
ListCheckBoxDialogBuilder(
|
||||
activity, items,
|
||||
activity,
|
||||
items,
|
||||
{ builder: ListCheckBoxDialogBuilder?, _: AlertDialog?, position: Int ->
|
||||
var label1: String?
|
||||
if (position == 0) {
|
||||
@@ -213,7 +222,9 @@ object CommonOperations {
|
||||
}
|
||||
// Notify
|
||||
activity.showTip(R.string.added_to_download_list, BaseScene.LENGTH_SHORT)
|
||||
}, activity.getString(R.string.remember_download_label), false
|
||||
},
|
||||
activity.getString(R.string.remember_download_label),
|
||||
false,
|
||||
)
|
||||
.setTitle(R.string.download)
|
||||
.show()
|
||||
@@ -221,8 +232,10 @@ object CommonOperations {
|
||||
}
|
||||
|
||||
private class DelegateFavoriteCallback(
|
||||
private val delegate: EhClient.Callback<Unit>, private val info: GalleryInfo,
|
||||
private val newFavoriteName: String?, private val slot: Int
|
||||
private val delegate: EhClient.Callback<Unit>,
|
||||
private val info: GalleryInfo,
|
||||
private val newFavoriteName: String?,
|
||||
private val slot: Int,
|
||||
) : EhClient.Callback<Unit> {
|
||||
override fun onSuccess(result: Unit) {
|
||||
info.favoriteName = newFavoriteName
|
||||
|
||||
@@ -80,9 +80,11 @@ abstract class EhActivity : AppCompatActivity() {
|
||||
fun checkAndRequestNotificationPermission() {
|
||||
if (ContextCompat.checkSelfPermission(
|
||||
this,
|
||||
Manifest.permission.POST_NOTIFICATIONS
|
||||
Manifest.permission.POST_NOTIFICATIONS,
|
||||
) == PackageManager.PERMISSION_GRANTED
|
||||
) return
|
||||
) {
|
||||
return
|
||||
}
|
||||
if (Settings.notificationRequired) return
|
||||
requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class GalleryInfoBottomSheet(detail: GalleryDetail) : BottomSheetDialogFragment(
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
savedInstanceState: Bundle?,
|
||||
): View? {
|
||||
parseDetail()
|
||||
val view = inflater.inflate(R.layout.scene_gallery_info, container, false)
|
||||
@@ -155,8 +155,8 @@ class GalleryInfoBottomSheet(detail: GalleryDetail) : BottomSheetDialogFragment(
|
||||
mInflater.inflate(
|
||||
if (viewType == TYPE_HEADER) R.layout.item_gallery_info_header else R.layout.item_gallery_info_data,
|
||||
parent,
|
||||
false
|
||||
)
|
||||
false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -179,4 +179,4 @@ class GalleryInfoBottomSheet(detail: GalleryDetail) : BottomSheetDialogFragment(
|
||||
private const val TYPE_HEADER = 0
|
||||
private const val TYPE_DATA = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,7 +122,7 @@ class MainActivity : EhActivity() {
|
||||
override fun onBackPressed() {
|
||||
check(Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU)
|
||||
val isDrawerOpen = binding.drawView.isDrawerOpen(GravityCompat.START) or
|
||||
binding.drawView.isDrawerOpen(GravityCompat.END)
|
||||
binding.drawView.isDrawerOpen(GravityCompat.END)
|
||||
if (isDrawerOpen) {
|
||||
binding.drawView.closeDrawers()
|
||||
} else {
|
||||
@@ -142,7 +142,7 @@ class MainActivity : EhActivity() {
|
||||
.setPositiveButton(android.R.string.copy) { _: DialogInterface?, _: Int ->
|
||||
this@MainActivity.addTextToClipboard(
|
||||
url,
|
||||
false
|
||||
false,
|
||||
)
|
||||
}
|
||||
.show()
|
||||
@@ -167,7 +167,7 @@ class MainActivity : EhActivity() {
|
||||
val args = Bundle()
|
||||
args.putString(
|
||||
GalleryListScene.KEY_ACTION,
|
||||
GalleryListScene.ACTION_LIST_URL_BUILDER
|
||||
GalleryListScene.ACTION_LIST_URL_BUILDER,
|
||||
)
|
||||
args.putParcelable(GalleryListScene.KEY_LIST_URL_BUILDER, listUrlBuilder)
|
||||
navController.navigate(R.id.galleryListScene, args)
|
||||
@@ -201,7 +201,7 @@ class MainActivity : EhActivity() {
|
||||
builder.keyword = intent.getStringExtra(Intent.EXTRA_TEXT)
|
||||
navController.navigate(
|
||||
R.id.galleryListScene,
|
||||
builder.toStartArgs()
|
||||
builder.toStartArgs(),
|
||||
)
|
||||
return true
|
||||
} else if (type != null && type.startsWith("image/")) {
|
||||
@@ -215,7 +215,7 @@ class MainActivity : EhActivity() {
|
||||
builder.isUseSimilarityScan = true
|
||||
navController.navigate(
|
||||
R.id.galleryListScene,
|
||||
builder.toStartArgs()
|
||||
builder.toStartArgs(),
|
||||
)
|
||||
return true
|
||||
}
|
||||
@@ -329,13 +329,13 @@ class MainActivity : EhActivity() {
|
||||
try {
|
||||
val intent = Intent(
|
||||
android.provider.Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
|
||||
Uri.parse("package:$packageName")
|
||||
Uri.parse("package:$packageName"),
|
||||
)
|
||||
startActivity(intent)
|
||||
} catch (t: Throwable) {
|
||||
val intent = Intent(
|
||||
android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
|
||||
Uri.parse("package:$packageName")
|
||||
Uri.parse("package:$packageName"),
|
||||
)
|
||||
startActivity(intent)
|
||||
}
|
||||
@@ -343,7 +343,7 @@ class MainActivity : EhActivity() {
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setNeutralButton(R.string.dont_show_again) { _: DialogInterface?, _: Int ->
|
||||
Settings.putAppLinkVerifyTip(
|
||||
true
|
||||
true,
|
||||
)
|
||||
}
|
||||
.show()
|
||||
@@ -369,7 +369,7 @@ class MainActivity : EhActivity() {
|
||||
Snackbar.make(
|
||||
binding.drawView,
|
||||
R.string.metered_network_warning,
|
||||
Snackbar.LENGTH_LONG
|
||||
Snackbar.LENGTH_LONG,
|
||||
)
|
||||
.setAction(R.string.settings) {
|
||||
val panelIntent =
|
||||
@@ -430,7 +430,7 @@ class MainActivity : EhActivity() {
|
||||
val snackbar = Snackbar.make(
|
||||
binding.drawView,
|
||||
R.string.clipboard_gallery_url_snack_message,
|
||||
Snackbar.LENGTH_SHORT
|
||||
Snackbar.LENGTH_SHORT,
|
||||
)
|
||||
snackbar.setAction(R.string.clipboard_gallery_url_snack_action) {
|
||||
it()
|
||||
@@ -447,18 +447,20 @@ class MainActivity : EhActivity() {
|
||||
if (scene is BaseScene) {
|
||||
binding.rightDrawer.removeAllViews()
|
||||
val drawerView = scene.createDrawerView(
|
||||
scene.layoutInflater, binding.rightDrawer, null
|
||||
scene.layoutInflater,
|
||||
binding.rightDrawer,
|
||||
null,
|
||||
)
|
||||
if (drawerView != null) {
|
||||
binding.rightDrawer.addView(drawerView)
|
||||
binding.drawView.setDrawerLockMode(
|
||||
DrawerLayout.LOCK_MODE_UNLOCKED,
|
||||
GravityCompat.END
|
||||
GravityCompat.END,
|
||||
)
|
||||
} else {
|
||||
binding.drawView.setDrawerLockMode(
|
||||
DrawerLayout.LOCK_MODE_LOCKED_CLOSED,
|
||||
GravityCompat.END
|
||||
GravityCompat.END,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -510,12 +512,14 @@ class MainActivity : EhActivity() {
|
||||
fun showTip(message: CharSequence, length: Int, useToast: Boolean = false) {
|
||||
findViewById<View>(R.id.snackbar)?.takeUnless { useToast }?.apply {
|
||||
Snackbar.make(
|
||||
this, message,
|
||||
if (length == BaseScene.LENGTH_LONG) Snackbar.LENGTH_LONG else Snackbar.LENGTH_SHORT
|
||||
this,
|
||||
message,
|
||||
if (length == BaseScene.LENGTH_LONG) Snackbar.LENGTH_LONG else Snackbar.LENGTH_SHORT,
|
||||
).show()
|
||||
} ?: Toast.makeText(
|
||||
this, message,
|
||||
if (length == BaseScene.LENGTH_LONG) Toast.LENGTH_LONG else Toast.LENGTH_SHORT
|
||||
this,
|
||||
message,
|
||||
if (length == BaseScene.LENGTH_LONG) Toast.LENGTH_LONG else Toast.LENGTH_SHORT,
|
||||
).show()
|
||||
}
|
||||
|
||||
@@ -540,9 +544,9 @@ class MainActivity : EhActivity() {
|
||||
availableNetworks.remove(network)
|
||||
if (network == activeNetwork) {
|
||||
connectivityManager.bindProcessToNetwork(
|
||||
availableNetworks.takeIf { it.isNotEmpty() }?.last()
|
||||
availableNetworks.takeIf { it.isNotEmpty() }?.last(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,10 +39,11 @@ fun Context.isAuthenticationSupported(): Boolean {
|
||||
class SecurityActivity : AppCompatActivity() {
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (isAuthenticationSupported())
|
||||
if (isAuthenticationSupported()) {
|
||||
startAuthentication(getString(R.string.settings_privacy_require_unlock))
|
||||
else
|
||||
} else {
|
||||
onSuccess()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
@@ -61,8 +62,8 @@ class SecurityActivity : AppCompatActivity() {
|
||||
callback = callback(
|
||||
{ _, _, _ -> onFailed() },
|
||||
{ _, _ -> onSuccess() },
|
||||
{ onFailed() }
|
||||
)
|
||||
{ onFailed() },
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -70,25 +71,25 @@ class SecurityActivity : AppCompatActivity() {
|
||||
crossinline onAuthenticationError: (
|
||||
activity: FragmentActivity?,
|
||||
errorCode: Int,
|
||||
errString: CharSequence
|
||||
errString: CharSequence,
|
||||
) -> Unit,
|
||||
crossinline onAuthenticationSucceeded: (
|
||||
activity: FragmentActivity?,
|
||||
result: BiometricPrompt.AuthenticationResult
|
||||
result: BiometricPrompt.AuthenticationResult,
|
||||
) -> Unit,
|
||||
crossinline onAuthenticationFailed: (
|
||||
activity: FragmentActivity?
|
||||
) -> Unit
|
||||
activity: FragmentActivity?,
|
||||
) -> Unit,
|
||||
) = object : AuthPromptCallback() {
|
||||
override fun onAuthenticationError(
|
||||
activity: FragmentActivity?,
|
||||
errorCode: Int,
|
||||
errString: CharSequence
|
||||
errString: CharSequence,
|
||||
) = onAuthenticationError(activity, errorCode, errString)
|
||||
|
||||
override fun onAuthenticationSucceeded(
|
||||
activity: FragmentActivity?,
|
||||
result: BiometricPrompt.AuthenticationResult
|
||||
result: BiometricPrompt.AuthenticationResult,
|
||||
) = onAuthenticationSucceeded(activity, result)
|
||||
|
||||
override fun onAuthenticationFailed(activity: FragmentActivity?) =
|
||||
@@ -109,4 +110,4 @@ class SecurityActivity : AppCompatActivity() {
|
||||
companion object {
|
||||
private var isAuthenticating = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,8 +87,9 @@ class SettingsActivity : EhActivity() {
|
||||
|
||||
fun showTip(message: CharSequence?, length: Int) {
|
||||
Snackbar.make(
|
||||
findViewById(R.id.snackbar), message!!,
|
||||
if (length == BaseScene.LENGTH_LONG) Snackbar.LENGTH_LONG else Snackbar.LENGTH_SHORT
|
||||
findViewById(R.id.snackbar),
|
||||
message!!,
|
||||
if (length == BaseScene.LENGTH_LONG) Snackbar.LENGTH_LONG else Snackbar.LENGTH_SHORT,
|
||||
).show()
|
||||
}
|
||||
|
||||
@@ -116,4 +117,4 @@ class SettingsActivity : EhActivity() {
|
||||
super.finish()
|
||||
ActivityNavigator.applyPopAnimationsToPendingTransition(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ import com.hippo.ehviewer.Settings as AppSettings
|
||||
|
||||
class AdvancedFragment : BasePreferenceFragment() {
|
||||
private var exportLauncher = registerForActivityResult<String, Uri>(
|
||||
ActivityResultContracts.CreateDocument("application/vnd.sqlite3")
|
||||
ActivityResultContracts.CreateDocument("application/vnd.sqlite3"),
|
||||
) { uri: Uri? ->
|
||||
if (uri != null) {
|
||||
try {
|
||||
@@ -68,7 +68,7 @@ class AdvancedFragment : BasePreferenceFragment() {
|
||||
requireActivity().grantUriPermission(
|
||||
BuildConfig.APPLICATION_ID,
|
||||
uri,
|
||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
ExceptionUtils.throwIfFatal(e)
|
||||
@@ -86,11 +86,15 @@ class AdvancedFragment : BasePreferenceFragment() {
|
||||
alertDialog.dismiss()
|
||||
}
|
||||
showTip(
|
||||
if (success) GetText.getString(
|
||||
R.string.settings_advanced_export_data_to,
|
||||
uri.toString()
|
||||
) else GetText.getString(R.string.settings_advanced_export_data_failed),
|
||||
BaseScene.LENGTH_SHORT
|
||||
if (success) {
|
||||
GetText.getString(
|
||||
R.string.settings_advanced_export_data_to,
|
||||
uri.toString(),
|
||||
)
|
||||
} else {
|
||||
GetText.getString(R.string.settings_advanced_export_data_failed)
|
||||
},
|
||||
BaseScene.LENGTH_SHORT,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -100,7 +104,7 @@ class AdvancedFragment : BasePreferenceFragment() {
|
||||
}
|
||||
}
|
||||
private var dumpLogcatLauncher = registerForActivityResult<String, Uri>(
|
||||
ActivityResultContracts.CreateDocument("application/zip")
|
||||
ActivityResultContracts.CreateDocument("application/zip"),
|
||||
) { uri: Uri? ->
|
||||
if (uri != null) {
|
||||
try {
|
||||
@@ -108,7 +112,7 @@ class AdvancedFragment : BasePreferenceFragment() {
|
||||
requireActivity().grantUriPermission(
|
||||
BuildConfig.APPLICATION_ID,
|
||||
uri,
|
||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
ExceptionUtils.throwIfFatal(e)
|
||||
@@ -156,7 +160,7 @@ class AdvancedFragment : BasePreferenceFragment() {
|
||||
out.close()
|
||||
IOUtils.copy(
|
||||
FileInputStream(zipFile),
|
||||
requireActivity().contentResolver.openOutputStream(uri)
|
||||
requireActivity().contentResolver.openOutputStream(uri),
|
||||
)
|
||||
finished = true
|
||||
} catch (e: Exception) {
|
||||
@@ -169,22 +173,26 @@ class AdvancedFragment : BasePreferenceFragment() {
|
||||
finished = LogCat.save(requireActivity().contentResolver.openOutputStream(uri))
|
||||
}
|
||||
showTip(
|
||||
if (finished) getString(
|
||||
R.string.settings_advanced_dump_logcat_to,
|
||||
uri.toString()
|
||||
) else getString(R.string.settings_advanced_dump_logcat_failed),
|
||||
BaseScene.LENGTH_SHORT
|
||||
if (finished) {
|
||||
getString(
|
||||
R.string.settings_advanced_dump_logcat_to,
|
||||
uri.toString(),
|
||||
)
|
||||
} else {
|
||||
getString(R.string.settings_advanced_dump_logcat_failed)
|
||||
},
|
||||
BaseScene.LENGTH_SHORT,
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
showTip(
|
||||
getString(R.string.settings_advanced_dump_logcat_failed),
|
||||
BaseScene.LENGTH_SHORT
|
||||
BaseScene.LENGTH_SHORT,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
private var importDataLauncher = registerForActivityResult<Array<String>, Uri>(
|
||||
ActivityResultContracts.OpenDocument()
|
||||
ActivityResultContracts.OpenDocument(),
|
||||
) { uri: Uri? ->
|
||||
if (uri != null) {
|
||||
try {
|
||||
@@ -192,7 +200,7 @@ class AdvancedFragment : BasePreferenceFragment() {
|
||||
requireActivity().grantUriPermission(
|
||||
BuildConfig.APPLICATION_ID,
|
||||
uri,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION,
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
ExceptionUtils.throwIfFatal(e)
|
||||
@@ -212,7 +220,7 @@ class AdvancedFragment : BasePreferenceFragment() {
|
||||
if (null == error) {
|
||||
showTip(
|
||||
getString(R.string.settings_advanced_import_data_successfully),
|
||||
BaseScene.LENGTH_SHORT
|
||||
BaseScene.LENGTH_SHORT,
|
||||
)
|
||||
} else {
|
||||
showTip(error, BaseScene.LENGTH_SHORT)
|
||||
@@ -289,15 +297,16 @@ class AdvancedFragment : BasePreferenceFragment() {
|
||||
return true
|
||||
} else if (KEY_OPEN_BY_DEFAULT == key) {
|
||||
try {
|
||||
@SuppressLint("InlinedApi") val intent = Intent(
|
||||
@SuppressLint("InlinedApi")
|
||||
val intent = Intent(
|
||||
Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
|
||||
Uri.parse("package:" + requireContext().packageName)
|
||||
Uri.parse("package:" + requireContext().packageName),
|
||||
)
|
||||
startActivity(intent)
|
||||
} catch (t: Throwable) {
|
||||
val intent = Intent(
|
||||
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
|
||||
Uri.parse("package:" + requireContext().packageName)
|
||||
Uri.parse("package:" + requireContext().packageName),
|
||||
)
|
||||
startActivity(intent)
|
||||
}
|
||||
@@ -319,7 +328,7 @@ class AdvancedFragment : BasePreferenceFragment() {
|
||||
if (result.galleryInfoList.isEmpty()) {
|
||||
showTip(
|
||||
R.string.settings_advanced_backup_favorite_nothing,
|
||||
BaseScene.LENGTH_SHORT
|
||||
BaseScene.LENGTH_SHORT,
|
||||
)
|
||||
} else {
|
||||
if (favTotal == 0 && result.countArray != null) {
|
||||
@@ -334,8 +343,9 @@ class AdvancedFragment : BasePreferenceFragment() {
|
||||
showTip(
|
||||
GetText.getString(
|
||||
R.string.settings_advanced_backup_favorite_start,
|
||||
status
|
||||
), BaseScene.LENGTH_SHORT
|
||||
status,
|
||||
),
|
||||
BaseScene.LENGTH_SHORT,
|
||||
)
|
||||
Log.d("LocalFavorites", "now backup page $status")
|
||||
EhDB.putLocalFavorites(result.galleryInfoList)
|
||||
@@ -357,14 +367,14 @@ class AdvancedFragment : BasePreferenceFragment() {
|
||||
} else {
|
||||
showTip(
|
||||
R.string.settings_advanced_backup_favorite_success,
|
||||
BaseScene.LENGTH_SHORT
|
||||
BaseScene.LENGTH_SHORT,
|
||||
)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
showTip(
|
||||
R.string.settings_advanced_backup_favorite_failed,
|
||||
BaseScene.LENGTH_SHORT
|
||||
BaseScene.LENGTH_SHORT,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -406,4 +416,4 @@ class AdvancedFragment : BasePreferenceFragment() {
|
||||
private const val KEY_OPEN_BY_DEFAULT = "open_by_default"
|
||||
private const val KEY_BACKUP_FAVORITE = "backup_favorite"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,4 +70,4 @@ abstract class BaseFragment : Fragment() {
|
||||
visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,10 @@ import androidx.preference.PreferenceFragmentCompat
|
||||
import com.hippo.ehviewer.R
|
||||
import com.hippo.ehviewer.ui.SettingsActivity
|
||||
|
||||
open class BasePreferenceFragment : PreferenceFragmentCompat(),
|
||||
Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener {
|
||||
open class BasePreferenceFragment :
|
||||
PreferenceFragmentCompat(),
|
||||
Preference.OnPreferenceClickListener,
|
||||
Preference.OnPreferenceChangeListener {
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
setTitle(fragmentTitle)
|
||||
@@ -81,4 +83,4 @@ open class BasePreferenceFragment : PreferenceFragmentCompat(),
|
||||
fun showTip(message: CharSequence?, length: Int) {
|
||||
(requireActivity() as SettingsActivity).showTip(message, length)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,12 +34,12 @@ import eu.kanade.tachiyomi.util.lang.launchNonCancellable
|
||||
class DownloadFragment : BasePreferenceFragment() {
|
||||
private var mDownloadLocation: Preference? = null
|
||||
private var pickImageDirLauncher = registerForActivityResult<Uri?, Uri>(
|
||||
ActivityResultContracts.OpenDocumentTree()
|
||||
ActivityResultContracts.OpenDocumentTree(),
|
||||
) { treeUri: Uri? ->
|
||||
if (treeUri != null) {
|
||||
requireActivity().contentResolver.takePersistableUriPermission(
|
||||
treeUri,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
|
||||
)
|
||||
val uniFile = UniFile.fromTreeUri(activity, treeUri)
|
||||
if (uniFile != null) {
|
||||
@@ -51,7 +51,7 @@ class DownloadFragment : BasePreferenceFragment() {
|
||||
} else {
|
||||
showTip(
|
||||
R.string.settings_download_cant_get_download_location,
|
||||
BaseScene.LENGTH_SHORT
|
||||
BaseScene.LENGTH_SHORT,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -89,7 +89,7 @@ class DownloadFragment : BasePreferenceFragment() {
|
||||
if (KEY_DOWNLOAD_LOCATION == key) {
|
||||
val file = Settings.downloadLocation
|
||||
if (file != null && !UniFile.isFileUri(
|
||||
Settings.downloadLocation!!.uri
|
||||
Settings.downloadLocation!!.uri,
|
||||
)
|
||||
) {
|
||||
BaseDialogBuilder(requireContext())
|
||||
@@ -107,7 +107,7 @@ class DownloadFragment : BasePreferenceFragment() {
|
||||
} else {
|
||||
showTip(
|
||||
R.string.settings_download_cant_get_download_location,
|
||||
BaseScene.LENGTH_SHORT
|
||||
BaseScene.LENGTH_SHORT,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -148,4 +148,4 @@ class DownloadFragment : BasePreferenceFragment() {
|
||||
companion object {
|
||||
const val KEY_DOWNLOAD_LOCATION = "download_location"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,4 +147,4 @@ class EhFragment : BasePreferenceFragment() {
|
||||
@get:StringRes
|
||||
override val fragmentTitle: Int
|
||||
get() = R.string.settings_eh
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,7 @@ class FilterFragment : BaseFragment() {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
savedInstanceState: Bundle?,
|
||||
): View {
|
||||
val recyclerView =
|
||||
inflater.inflate(R.layout.rv_layout, container, false) as RecyclerView
|
||||
@@ -237,7 +237,7 @@ class FilterFragment : BaseFragment() {
|
||||
holder.itemView.setOnClickListener {
|
||||
mFilterList.trigger(filter)
|
||||
|
||||
//for updating delete line on filter text
|
||||
// for updating delete line on filter text
|
||||
mAdapter.notifyItemChanged(position)
|
||||
}
|
||||
holder.delete?.setOnClickListener { showDeleteFilterDialog(filter) }
|
||||
@@ -253,7 +253,9 @@ class FilterFragment : BaseFragment() {
|
||||
val filter = mFilterList[position]
|
||||
if (filter.id != null) {
|
||||
(filter.text.hashCode() shr filter.mode) + filter.id!!
|
||||
} else (filter.text.hashCode() shr filter.mode).toLong()
|
||||
} else {
|
||||
(filter.text.hashCode() shr filter.mode).toLong()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -425,4 +427,4 @@ class FilterFragment : BaseFragment() {
|
||||
private const val TYPE_ITEM = 0
|
||||
private const val TYPE_HEADER = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ class HostsFragment : BaseFragment(), View.OnClickListener {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
savedInstanceState: Bundle?,
|
||||
): View {
|
||||
val recyclerView = inflater.inflate(R.layout.rv_layout, container, false) as RecyclerView
|
||||
val tip = getTipView(R.string.hosts)
|
||||
@@ -225,4 +225,4 @@ class HostsFragment : BaseFragment(), View.OnClickListener {
|
||||
private const val KEY_HOST = "com.hippo.ehviewer.ui.fragment.HostsFragment.HOST"
|
||||
private const val KEY_IP = "com.hippo.ehviewer.ui.fragment.HostsFragment.IP"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,4 +71,4 @@ class PrivacyFragment : BasePreferenceFragment() {
|
||||
getString(R.string.settings_privacy_require_unlock_delay_summary, value.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ class UConfigFragment : BaseFragment() {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
savedInstanceState: Bundle?,
|
||||
): View {
|
||||
_binding = ActivityWebviewBinding.inflate(inflater, container, false)
|
||||
binding.webview.run {
|
||||
@@ -74,21 +74,25 @@ class UConfigFragment : BaseFragment() {
|
||||
binding.progress.visibility = View.VISIBLE
|
||||
binding.webview.loadUrl(url)
|
||||
showTip(R.string.apply_tip, BaseScene.LENGTH_LONG)
|
||||
requireActivity().addMenuProvider(object : MenuProvider {
|
||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||
menuInflater.inflate(R.menu.activity_u_config, menu)
|
||||
}
|
||||
|
||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||
if (menuItem.itemId == R.id.action_apply) {
|
||||
if (loaded) {
|
||||
apply()
|
||||
}
|
||||
return true
|
||||
requireActivity().addMenuProvider(
|
||||
object : MenuProvider {
|
||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||
menuInflater.inflate(R.menu.activity_u_config, menu)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}, viewLifecycleOwner, Lifecycle.State.RESUMED)
|
||||
|
||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||
if (menuItem.itemId == R.id.action_apply) {
|
||||
if (loaded) {
|
||||
apply()
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
},
|
||||
viewLifecycleOwner,
|
||||
Lifecycle.State.RESUMED,
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -112,7 +116,7 @@ class UConfigFragment : BaseFragment() {
|
||||
"""javascript:(function() {
|
||||
var apply = document.getElementById("apply").children[0];
|
||||
apply.click();
|
||||
})();"""
|
||||
})();""",
|
||||
)
|
||||
}
|
||||
|
||||
@@ -170,4 +174,4 @@ class UConfigFragment : BaseFragment() {
|
||||
loaded = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded 100 of 159 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user