Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4f2a33016 | ||
|
|
ee7ede2885 | ||
|
|
6abc404eb7 | ||
|
|
61afe01e36 | ||
|
|
c3e60f9988 | ||
|
|
593197cd7e | ||
|
|
ee1592b478 | ||
|
|
dfe435c4f3 | ||
|
|
69e85f8b90 | ||
|
|
c9bde3c487 | ||
|
|
65e9557d9f |
3
.idea/codeStyles/Project.xml
generated
3
.idea/codeStyles/Project.xml
generated
@@ -1,9 +1,6 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<option name="RIGHT_MARGIN" value="120" />
|
||||
<AndroidXmlCodeStyleSettings>
|
||||
<option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
|
||||
</AndroidXmlCodeStyleSettings>
|
||||
<JetCodeStyleSettings>
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
|
||||
3
.idea/gradle.xml
generated
3
.idea/gradle.xml
generated
@@ -1,8 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="delegatedBuild" value="false" />
|
||||
<option name="testRunner" value="PLATFORM" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="modules">
|
||||
|
||||
@@ -19,8 +19,8 @@ android {
|
||||
applicationId "xyz.quaver.pupil"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 29
|
||||
versionCode 43
|
||||
versionName "4.7"
|
||||
versionCode 48
|
||||
versionName "4.12"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
multiDexEnabled true
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
@@ -66,7 +66,7 @@ dependencies {
|
||||
implementation 'androidx.preference:preference:1.1.0'
|
||||
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
||||
implementation "androidx.biometric:biometric:1.0.1"
|
||||
implementation 'com.android.support:multidex:1.0.3'
|
||||
implementation 'androidx.multidex:multidex:2.0.1'
|
||||
implementation "com.daimajia.swipelayout:library:1.2.0@aar"
|
||||
implementation 'com.google.android.material:material:1.2.0-alpha05'
|
||||
implementation 'com.google.firebase:firebase-core:17.2.2'
|
||||
@@ -74,14 +74,12 @@ dependencies {
|
||||
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
|
||||
implementation 'com.github.arimorty:floatingsearchview:2.1.1'
|
||||
implementation 'com.github.clans:fab:1.6.4'
|
||||
|
||||
implementation 'com.github.bumptech.glide:glide:4.11.0'
|
||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
|
||||
kapt 'com.github.bumptech.glide:compiler:4.11.0'
|
||||
implementation ("com.github.bumptech.glide:recyclerview-integration:4.11.0") {
|
||||
transitive = false
|
||||
}
|
||||
|
||||
implementation 'net.rdrei.android.dirchooser:library:3.2@aar'
|
||||
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
|
||||
implementation 'com.andrognito.patternlockview:patternlockview:1.0.0'
|
||||
|
||||
7
app/proguard-rules.pro
vendored
7
app/proguard-rules.pro
vendored
@@ -23,8 +23,13 @@
|
||||
-dontobfuscate
|
||||
|
||||
-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||
-keep public class * extends com.bumptech.glide.module.AppGlideModule
|
||||
-keep class * extends com.bumptech.glide.module.AppGlideModule {
|
||||
<init>(...);
|
||||
}
|
||||
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||
**[] $VALUES;
|
||||
public *;
|
||||
}
|
||||
-keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder {
|
||||
*** rewind();
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":43,"versionName":"4.7","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
|
||||
[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":48,"versionName":"4.12","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release","dirName":""},"path":"app-release.apk","properties":{}}]
|
||||
@@ -105,9 +105,9 @@ class ExampleInstrumentedTest {
|
||||
val galleryID = 1561552
|
||||
|
||||
runBlocking {
|
||||
Log.i("PUPILD", Cache(context).getReader(galleryID)?.title ?: "null")
|
||||
Log.i("PUPILD", Cache(context).getReader(galleryID)?.galleryInfo?.title ?: "null")
|
||||
}
|
||||
|
||||
Log.i("PUPILD", Cache(context).getReaderOrNull(galleryID)?.title ?: "null")
|
||||
Log.i("PUPILD", Cache(context).getReaderOrNull(galleryID)?.galleryInfo?.title ?: "null")
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
|
||||
|
||||
<application
|
||||
android:name=".Pupil"
|
||||
android:allowBackup="true"
|
||||
|
||||
@@ -49,13 +49,12 @@ import xyz.quaver.pupil.R
|
||||
import xyz.quaver.pupil.types.Tag
|
||||
import xyz.quaver.pupil.util.Histories
|
||||
import xyz.quaver.pupil.util.download.Cache
|
||||
import xyz.quaver.pupil.util.download.DownloadWorker
|
||||
import xyz.quaver.pupil.util.wordCapitalize
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.concurrent.schedule
|
||||
|
||||
class GalleryBlockAdapter(context: Context, private val galleries: List<GalleryBlock>) : RecyclerSwipeAdapter<RecyclerView.ViewHolder>(), SwipeAdapterInterface {
|
||||
class GalleryBlockAdapter(private val context: Context, private val galleries: List<GalleryBlock>) : RecyclerSwipeAdapter<RecyclerView.ViewHolder>(), SwipeAdapterInterface {
|
||||
|
||||
enum class ViewType {
|
||||
NEXT,
|
||||
@@ -68,11 +67,12 @@ class GalleryBlockAdapter(context: Context, private val galleries: List<GalleryB
|
||||
|
||||
val timer = Timer()
|
||||
|
||||
var isThin = false
|
||||
|
||||
inner class GalleryViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
||||
var timerTask: TimerTask? = null
|
||||
|
||||
private fun updateProgress(context: Context, galleryID: Int) {
|
||||
val cache = Cache(context).getCachedGallery(galleryID)
|
||||
val reader = Cache(context).getReaderOrNull(galleryID)
|
||||
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
@@ -84,9 +84,7 @@ class GalleryBlockAdapter(context: Context, private val galleries: List<GalleryB
|
||||
|
||||
with(view.galleryblock_progressbar) {
|
||||
|
||||
progress = cache.listFiles()?.count { file ->
|
||||
Regex("^[0-9]+.+\$").matches(file.name)
|
||||
} ?: 0
|
||||
progress = Cache(context).getImages(galleryID)?.size ?: 0
|
||||
|
||||
if (visibility == View.GONE) {
|
||||
visibility = View.VISIBLE
|
||||
@@ -126,6 +124,10 @@ class GalleryBlockAdapter(context: Context, private val galleries: List<GalleryB
|
||||
val artists = galleryBlock.artists
|
||||
val series = galleryBlock.series
|
||||
|
||||
if (isThin)
|
||||
galleryblock_thumbnail.layoutParams.width = context.resources.getDimensionPixelSize(
|
||||
R.dimen.galleryblock_thumbnail_thin
|
||||
)
|
||||
galleryblock_thumbnail.setImageDrawable(CircularProgressDrawable(context).also {
|
||||
it.start()
|
||||
})
|
||||
@@ -138,16 +140,18 @@ class GalleryBlockAdapter(context: Context, private val galleries: List<GalleryB
|
||||
null
|
||||
}
|
||||
|
||||
glide
|
||||
.load(thumbnail)
|
||||
.skipMemoryCache(true)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.error(R.drawable.image_broken_variant)
|
||||
.apply {
|
||||
if (BuildConfig.CENSOR)
|
||||
override(5, 8)
|
||||
}
|
||||
.into(galleryblock_thumbnail)
|
||||
galleryblock_thumbnail.post {
|
||||
glide
|
||||
.load(thumbnail)
|
||||
.skipMemoryCache(true)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.error(R.drawable.image_broken_variant)
|
||||
.apply {
|
||||
if (BuildConfig.CENSOR)
|
||||
override(5, 8)
|
||||
}
|
||||
.into(galleryblock_thumbnail)
|
||||
}
|
||||
}
|
||||
|
||||
//Check cache
|
||||
@@ -264,6 +268,14 @@ class GalleryBlockAdapter(context: Context, private val galleries: List<GalleryB
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Make some views invisible to make it thinner
|
||||
if (isThin) {
|
||||
galleryblock_language.visibility = View.GONE
|
||||
galleryblock_type.visibility = View.GONE
|
||||
galleryblock_tag_group.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -341,10 +353,10 @@ class GalleryBlockAdapter(context: Context, private val galleries: List<GalleryB
|
||||
mItemManger.closeAllExcept(layout)
|
||||
|
||||
holder.view.galleryblock_download.text =
|
||||
if (DownloadWorker.getInstance(holder.view.context).progress.indexOfKey(gallery.id) < 0)
|
||||
holder.view.context.getString(R.string.main_download)
|
||||
else
|
||||
if (Cache(context).isDownloading(gallery.id))
|
||||
holder.view.context.getString(android.R.string.cancel)
|
||||
else
|
||||
holder.view.context.getString(R.string.main_download)
|
||||
}
|
||||
|
||||
override fun onClose(layout: SwipeLayout?) {}
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
package xyz.quaver.pupil.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.BitmapFactory
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@@ -29,7 +28,6 @@ import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.ListPreloader
|
||||
import com.bumptech.glide.RequestBuilder
|
||||
import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.crashlytics.android.Crashlytics
|
||||
import io.fabric.sdk.android.Fabric
|
||||
import kotlinx.android.synthetic.main.item_reader.view.*
|
||||
@@ -65,8 +63,7 @@ class ReaderAdapter(private val context: Context,
|
||||
override fun getPreloadRequestBuilder(item: File): RequestBuilder<*>? {
|
||||
return glide
|
||||
.load(item)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.skipMemoryCache(true)
|
||||
.fitCenter()
|
||||
.error(R.drawable.image_broken_variant)
|
||||
.apply {
|
||||
if (BuildConfig.CENSOR)
|
||||
@@ -103,6 +100,9 @@ class ReaderAdapter(private val context: Context,
|
||||
} else {
|
||||
holder.view.layoutParams.height = RecyclerView.LayoutParams.WRAP_CONTENT
|
||||
holder.view.container.layoutParams.height = 0
|
||||
|
||||
(holder.view.container.layoutParams as ConstraintLayout.LayoutParams)
|
||||
.dimensionRatio = "W,${reader!!.galleryInfo.files[position].width}:${reader!!.galleryInfo.files[position].height}"
|
||||
}
|
||||
|
||||
holder.view.image.setOnPhotoTapListener { _, _, _ ->
|
||||
@@ -113,10 +113,6 @@ class ReaderAdapter(private val context: Context,
|
||||
onItemClickListener?.invoke(position)
|
||||
}
|
||||
|
||||
if (!isFullScreen)
|
||||
(holder.view.container.layoutParams as ConstraintLayout.LayoutParams)
|
||||
.dimensionRatio = "${reader!!.galleryInfo.files[position].width}:${reader!!.galleryInfo.files[position].height}"
|
||||
|
||||
holder.view.reader_index.text = (position+1).toString()
|
||||
|
||||
val images = Cache(context).getImage(galleryID, position)
|
||||
@@ -124,34 +120,19 @@ class ReaderAdapter(private val context: Context,
|
||||
|
||||
if (progress?.isInfinite() == true && images != null) {
|
||||
holder.view.reader_item_progressbar.visibility = View.INVISIBLE
|
||||
holder.view.container.apply {
|
||||
val options = BitmapFactory.Options().apply {
|
||||
inJustDecodeBounds = true
|
||||
}
|
||||
|
||||
BitmapFactory.decodeFile(images.canonicalPath, options)
|
||||
|
||||
maxWidth = options.outWidth
|
||||
maxHeight = options.outHeight
|
||||
holder.view.image.post {
|
||||
glide
|
||||
.load(images)
|
||||
.fitCenter()
|
||||
.error(R.drawable.image_broken_variant)
|
||||
.into(holder.view.image)
|
||||
}
|
||||
|
||||
glide
|
||||
.load(images)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.skipMemoryCache(true)
|
||||
.dontTransform()
|
||||
.error(R.drawable.image_broken_variant)
|
||||
.apply {
|
||||
if (BuildConfig.CENSOR)
|
||||
override(5, 8)
|
||||
}
|
||||
.into(holder.view.image)
|
||||
} else {
|
||||
holder.view.reader_item_progressbar.visibility = View.VISIBLE
|
||||
holder.view.container.apply {
|
||||
maxWidth = Integer.MAX_VALUE
|
||||
maxHeight = Integer.MAX_VALUE
|
||||
}
|
||||
|
||||
glide.clear(holder.view.image)
|
||||
|
||||
if (progress?.isNaN() == true) {
|
||||
if (Fabric.isInitialized())
|
||||
|
||||
@@ -330,6 +330,13 @@ class MainActivity : AppCompatActivity() {
|
||||
true
|
||||
}
|
||||
|
||||
with(main_fab_cancel) {
|
||||
setImageResource(R.drawable.cancel)
|
||||
setOnClickListener {
|
||||
DownloadWorker.getInstance(context).stop()
|
||||
}
|
||||
}
|
||||
|
||||
with(main_fab_jump) {
|
||||
setImageResource(R.drawable.ic_jump)
|
||||
setOnClickListener {
|
||||
@@ -408,7 +415,7 @@ class MainActivity : AppCompatActivity() {
|
||||
if (!completeFlag.get(galleryID, false)) {
|
||||
val worker = DownloadWorker.getInstance(context)
|
||||
|
||||
if (worker.progress.indexOfKey(galleryID) >= 0) //download in progress
|
||||
if (Cache(context).isDownloading(galleryID)) //download in progress
|
||||
worker.cancel(galleryID)
|
||||
else {
|
||||
Cache(context).setDownloading(galleryID, true)
|
||||
@@ -724,6 +731,15 @@ class MainActivity : AppCompatActivity() {
|
||||
setOnMenuItemClickListener {
|
||||
when(it.itemId) {
|
||||
R.id.main_menu_settings -> startActivityForResult(Intent(this@MainActivity, SettingsActivity::class.java), REQUEST_SETTINGS)
|
||||
R.id.main_menu_thin -> {
|
||||
main_recyclerview.apply {
|
||||
(adapter as GalleryBlockAdapter).apply {
|
||||
isThin = !isThin
|
||||
}
|
||||
|
||||
adapter = adapter // Force to redraw
|
||||
}
|
||||
}
|
||||
R.id.main_menu_sort_newest -> {
|
||||
sortMode = SortMode.NEWEST
|
||||
it.isChecked = true
|
||||
|
||||
@@ -361,6 +361,8 @@ class ReaderActivity : AppCompatActivity() {
|
||||
|
||||
window.attributes = this
|
||||
}
|
||||
|
||||
reader_recyclerview.adapter = reader_recyclerview.adapter // Force to redraw
|
||||
}
|
||||
|
||||
private fun scrollMode(isScroll: Boolean) {
|
||||
@@ -386,7 +388,7 @@ class ReaderActivity : AppCompatActivity() {
|
||||
if (worker.progress[galleryID]?.all { !it.isFinite() } == true) // If download is finished, stop animating
|
||||
post {
|
||||
setImageResource(R.drawable.ic_download)
|
||||
labelText = getString(R.string.reader_fab_download)
|
||||
labelText = getString(R.string.reader_fab_download_cancel)
|
||||
}
|
||||
else // Or continue animate
|
||||
post {
|
||||
|
||||
@@ -21,13 +21,11 @@ package xyz.quaver.pupil.util.download
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.util.Base64
|
||||
import android.util.Log
|
||||
import android.util.SparseArray
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.crashlytics.android.Crashlytics
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.io.InputStream
|
||||
import xyz.quaver.Code
|
||||
import xyz.quaver.hitomi.GalleryBlock
|
||||
@@ -35,6 +33,7 @@ import xyz.quaver.hitomi.Reader
|
||||
import xyz.quaver.proxy
|
||||
import xyz.quaver.pupil.util.getCachedGallery
|
||||
import xyz.quaver.pupil.util.getDownloadDirectory
|
||||
import xyz.quaver.pupil.util.isParentOf
|
||||
import xyz.quaver.pupil.util.json
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
@@ -246,15 +245,27 @@ class Cache(context: Context) : ContextWrapper(context) {
|
||||
}
|
||||
}
|
||||
|
||||
fun moveToDownload(galleryID: Int) {
|
||||
fun moveToDownload(galleryID: Int) = CoroutineScope(Dispatchers.IO).launch {
|
||||
val cache = getCachedGallery(galleryID).also {
|
||||
if (!it.exists())
|
||||
return
|
||||
return@launch
|
||||
}
|
||||
val download = File(getDownloadDirectory(this), galleryID.toString())
|
||||
val download = File(getDownloadDirectory(this@Cache), galleryID.toString())
|
||||
|
||||
cache.copyRecursively(download, true) { _, _ -> OnErrorAction.SKIP }
|
||||
if (download.isParentOf(cache))
|
||||
return@launch
|
||||
|
||||
Log.i("PUPILD", "MOVING ${cache.canonicalPath} --> ${download.canonicalPath}")
|
||||
|
||||
cache.copyRecursively(download, true) { file, err ->
|
||||
Log.i("PUPILD", "MOVING ERROR ${file.canonicalPath} ${err.message}")
|
||||
OnErrorAction.SKIP
|
||||
}
|
||||
Log.i("PUPILD", "MOVED ${cache.canonicalPath}")
|
||||
|
||||
Log.i("PUPILD", "DELETING ${cache.canonicalPath}")
|
||||
cache.deleteRecursively()
|
||||
Log.i("PUPILD", "DELETED ${cache.canonicalPath}")
|
||||
}
|
||||
|
||||
fun isDownloading(galleryID: Int) = getCachedMetadata(galleryID)?.isDownloading == true
|
||||
|
||||
@@ -149,7 +149,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
||||
|
||||
private val loop = loop()
|
||||
private val worker = SparseArray<Job?>()
|
||||
val clients = SparseArray<OkHttpClient>()
|
||||
|
||||
val interceptor = Interceptor { chain ->
|
||||
val request = chain.request()
|
||||
@@ -159,7 +158,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
||||
.body(ProgressResponseBody(request.tag(), response.body(), progressListener))
|
||||
.build()
|
||||
}
|
||||
fun buildClient() =
|
||||
val client =
|
||||
OkHttpClient.Builder()
|
||||
.addInterceptor(interceptor)
|
||||
.connectTimeout(0, TimeUnit.SECONDS)
|
||||
@@ -172,17 +171,14 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
||||
queue.clear()
|
||||
|
||||
loop.cancel()
|
||||
for (i in 0..worker.size()) {
|
||||
for (i in 0 until worker.size()) {
|
||||
val galleryID = worker.keyAt(i)
|
||||
|
||||
Cache(this@DownloadWorker).setDownloading(galleryID, false)
|
||||
worker[galleryID]?.cancel()
|
||||
}
|
||||
|
||||
for (i in 0 until clients.size()) {
|
||||
clients.valueAt(i).dispatcher().cancelAll()
|
||||
}
|
||||
clients.clear()
|
||||
client.dispatcher().cancelAll()
|
||||
|
||||
progress.clear()
|
||||
exception.clear()
|
||||
@@ -194,17 +190,19 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
||||
queue.remove(galleryID)
|
||||
worker[galleryID]?.cancel()
|
||||
|
||||
clients[galleryID]?.dispatcher()?.cancelAll()
|
||||
clients.remove(galleryID)
|
||||
client.dispatcher().queuedCalls().filter {
|
||||
((it.request().tag() as Pair<*, *>).first as Int) == galleryID
|
||||
}.forEach {
|
||||
it.cancel()
|
||||
}
|
||||
|
||||
progress.remove(galleryID)
|
||||
exception.remove(galleryID)
|
||||
notification.remove(galleryID)
|
||||
notificationManager.cancel(galleryID)
|
||||
|
||||
if (progress.indexOfKey(galleryID) >= 0) {
|
||||
if (progress.indexOfKey(galleryID) >= 0)
|
||||
Cache(this@DownloadWorker).setDownloading(galleryID, false)
|
||||
}
|
||||
}
|
||||
|
||||
fun isCompleted(galleryID: Int) = progress[galleryID]?.all { !it.isFinite() } == true
|
||||
@@ -236,10 +234,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
||||
tag(galleryID to index)
|
||||
}.build()
|
||||
|
||||
if (clients.get(galleryID) == null)
|
||||
clients.put(galleryID, buildClient())
|
||||
|
||||
clients[galleryID]?.newCall(request)?.enqueue(callback)
|
||||
client.newCall(request).enqueue(callback)
|
||||
}
|
||||
|
||||
private fun download(galleryID: Int) = CoroutineScope(Dispatchers.IO).launch {
|
||||
@@ -294,8 +289,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
||||
notify(galleryID)
|
||||
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
if (isCompleted(galleryID) && clients.indexOfKey(galleryID) >= 0) {
|
||||
clients.remove(galleryID)
|
||||
if (isCompleted(galleryID)) {
|
||||
with(Cache(this@DownloadWorker)) {
|
||||
if (isDownloading(galleryID)) {
|
||||
moveToDownload(galleryID)
|
||||
@@ -320,8 +314,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
||||
notify(galleryID)
|
||||
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
if (isCompleted(galleryID) && clients.indexOfKey(galleryID) >= 0) {
|
||||
clients.remove(galleryID)
|
||||
if (isCompleted(galleryID)) {
|
||||
with(Cache(this@DownloadWorker)) {
|
||||
if (isDownloading(galleryID)) {
|
||||
moveToDownload(galleryID)
|
||||
@@ -340,8 +333,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
||||
notify(galleryID)
|
||||
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
if (isCompleted(galleryID) && clients.indexOfKey(galleryID) >= 0) {
|
||||
clients.remove(galleryID)
|
||||
if (isCompleted(galleryID)) {
|
||||
with(Cache(this@DownloadWorker)) {
|
||||
if (isDownloading(galleryID)) {
|
||||
moveToDownload(galleryID)
|
||||
@@ -418,7 +410,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
||||
|
||||
val galleryID = queue.peek() ?: continue
|
||||
|
||||
if (clients.indexOfKey(galleryID) >= 0) // Gallery already downloading!
|
||||
if (progress.indexOfKey(galleryID) >= 0) // Gallery already downloading!
|
||||
continue
|
||||
|
||||
if (notification[galleryID] == null)
|
||||
@@ -427,10 +419,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
||||
if (Cache(this@DownloadWorker).isDownloading(galleryID))
|
||||
notificationManager.notify(galleryID, notification[galleryID].build())
|
||||
|
||||
if (clients.size() >= preferences.getInt("max_download", 4))
|
||||
continue
|
||||
|
||||
Log.i("PUPILD", "QUEUED $galleryID #${clients.size()+1}")
|
||||
Log.i("PUPILD", "QUEUED $galleryID")
|
||||
|
||||
worker.put(galleryID, download(galleryID))
|
||||
queue.poll()
|
||||
|
||||
@@ -212,3 +212,6 @@ fun Uri.toFile(context: Context): File? {
|
||||
|
||||
return File(context.getExternalFilesDir(null)?.canonicalPath?.substringBeforeLast("/Android/data") ?: return null, folderName)
|
||||
}
|
||||
|
||||
fun File.isParentOf(another: File) =
|
||||
another.absolutePath.startsWith(this.absolutePath)
|
||||
8
app/src/main/res/drawable/cancel.xml
Normal file
8
app/src/main/res/drawable/cancel.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<!-- drawable/cancel.xml -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path android:fillColor="#fff" android:pathData="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12C4,13.85 4.63,15.55 5.68,16.91L16.91,5.68C15.55,4.63 13.85,4 12,4M12,20A8,8 0 0,0 20,12C20,10.15 19.37,8.45 18.32,7.09L7.09,18.32C8.45,19.37 10.15,20 12,20Z" />
|
||||
</vector>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 68 KiB |
@@ -82,6 +82,13 @@
|
||||
android:layout_margin="16dp"
|
||||
app:menu_colorNormal="@color/colorAccent">
|
||||
|
||||
<com.github.clans.fab.FloatingActionButton
|
||||
android:id="@+id/main_fab_cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:fab_label="@string/main_fab_cancel"
|
||||
app:fab_size="mini"/>
|
||||
|
||||
<com.github.clans.fab.FloatingActionButton
|
||||
android:id="@+id/main_fab_jump"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -25,8 +25,9 @@
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintHeight_max="2000dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
@@ -63,11 +64,12 @@
|
||||
|
||||
<com.github.chrisbanes.photoview.PhotoView
|
||||
android:id="@+id/image"
|
||||
android:contentDescription="@string/reader_imageview_description"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="fitCenter"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
android:paddingBottom="8dp"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item android:id="@+id/main_menu_thin"
|
||||
android:title="@string/main_menu_thin"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/main_menu_sort"
|
||||
android:title="@string/main_menu_sort">
|
||||
|
||||
@@ -130,4 +130,6 @@
|
||||
<string name="proxy_dialog_error">エラー</string>
|
||||
<string name="proxy_dialog_addr_hint">サーバーアドレス</string>
|
||||
<string name="proxy_dialog_server">サーバー</string>
|
||||
<string name="main_menu_thin">簡単モード</string>
|
||||
<string name="main_fab_cancel">すべてのダウンロードキャンセル</string>
|
||||
</resources>
|
||||
@@ -130,4 +130,6 @@
|
||||
<string name="proxy_dialog_error">잘못된 값</string>
|
||||
<string name="proxy_dialog_addr_hint">서버 주소</string>
|
||||
<string name="proxy_dialog_server">서버</string>
|
||||
<string name="main_menu_thin">간단히 보기 모드</string>
|
||||
<string name="main_fab_cancel">다운로드 모두 취소</string>
|
||||
</resources>
|
||||
@@ -11,6 +11,6 @@
|
||||
|
||||
<dimen name="thumbnail_margin">8dp</dimen>
|
||||
|
||||
<dimen name="galleryblock_thumbnail_thin">50dp</dimen>
|
||||
<dimen name="galleryblock_thumbnail_thin">100dp</dimen>
|
||||
<dimen name="galleryblock_thumbnail_normal">150dp</dimen>
|
||||
</resources>
|
||||
@@ -53,6 +53,8 @@
|
||||
<string name="main_drawer_group_contact_email">Email me!</string>
|
||||
<string name="main_drawer_grouop_contact_discord">Discord</string>
|
||||
|
||||
<string name="main_menu_thin">Toggle Thin Mode</string>
|
||||
|
||||
<string name="main_menu_sort">Sort</string>
|
||||
<string name="main_menu_sort_newest">Newest</string>
|
||||
<string name="main_menu_sort_popular">Popular</string>
|
||||
@@ -61,6 +63,7 @@
|
||||
<string name="main_jump_message">Current page: %1$d\nMaximum page: %2$d</string>
|
||||
<string name="main_open_gallery_by_id">Open Gallery by ID</string>
|
||||
<string name="reader_failed_to_find_gallery">Failed to open gallery</string>
|
||||
<string name="main_fab_cancel">Cancel all downloads</string>
|
||||
|
||||
<string name="main_move">Move to page %1$d</string>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ buildscript {
|
||||
maven { url 'https://maven.fabric.io/public' }
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.3'
|
||||
classpath 'com.android.tools.build:gradle:3.6.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
|
||||
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
|
||||
|
||||
@@ -15,4 +15,3 @@ kotlin.code.style=official
|
||||
android.enableJetifier=true
|
||||
org.gradle.jvmargs=-Xmx1024M -Dkotlin.daemon.jvm.options\="-Xmx1024M"
|
||||
android.useAndroidX=true
|
||||
android.enableR8.fullMode=true
|
||||
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
#Fri Aug 23 08:21:15 KST 2019
|
||||
#Tue Feb 25 09:55:23 KST 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.net.URL
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
|
||||
const val hiyobi = "hiyobi.me"
|
||||
const val primary_img_domain = "cdn.hiyobi.me"
|
||||
const val user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36"
|
||||
|
||||
var cookie: String = ""
|
||||
@@ -87,7 +88,7 @@ fun createImgList(galleryID: Int, reader: Reader, lowQuality: Boolean = false) =
|
||||
if (lowQuality)
|
||||
reader.galleryInfo.files.map {
|
||||
val name = it.name.replace(Regex("""\.[^/.]+$"""), "")
|
||||
Images("$protocol//$hiyobi/data_r/$galleryID/$name.jpg", galleryID, it.name)
|
||||
Images("$protocol//$primary_img_domain/data_r/$galleryID/$name.jpg", galleryID, it.name)
|
||||
}
|
||||
else
|
||||
reader.galleryInfo.files.map { Images("$protocol//$hiyobi/data/$galleryID/${it.name}", galleryID, it.name) }
|
||||
reader.galleryInfo.files.map { Images("$protocol//$primary_img_domain/data/$galleryID/${it.name}", galleryID, it.name) }
|
||||
Reference in New Issue
Block a user