diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index 3825b2b3..17470b3c 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -51,5 +51,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 7c267bee..fa0b6548 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -48,6 +48,7 @@ android {
}
}
kotlinOptions {
+ jvmTarget = JavaVersion.VERSION_1_8.toString()
freeCompilerArgs += '-Xuse-experimental=kotlin.Experimental'
}
compileOptions {
@@ -68,7 +69,6 @@ dependencies {
implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.gridlayout:gridlayout:1.0.0'
implementation "androidx.biometric:biometric:1.0.1"
- implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.fragment:fragment-ktx:1.2.5'
implementation "com.daimajia.swipelayout:library:1.2.0@aar"
implementation 'com.google.android.material:material:1.3.0-alpha02'
@@ -78,8 +78,12 @@ dependencies {
implementation 'com.google.firebase:firebase-perf:19.0.8'
implementation 'com.github.arimorty:floatingsearchview:2.1.1'
implementation 'com.github.clans:fab:1.6.4'
+ //noinspection GradleDependency
+ implementation 'com.squareup.okhttp3:okhttp:3.12.12'
implementation 'com.github.bumptech.glide:glide:4.11.0'
- implementation "com.github.bumptech.glide:okhttp3-integration:4.11.0"
+ implementation ("com.github.bumptech.glide:okhttp3-integration:4.11.0") {
+ transitive = false
+ }
implementation 'com.github.bumptech.glide:annotations:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
kapt 'com.github.bumptech.glide:compiler:4.11.0'
@@ -92,7 +96,7 @@ dependencies {
implementation 'com.andrognito.patternlockview:patternlockview:1.0.0'
//implementation 'com.andrognito.pinlockview:pinlockview:2.1.0'
implementation "ru.noties.markwon:core:3.1.0"
- implementation ("xyz.quaver:libpupil:1.0") {
+ implementation ("xyz.quaver:libpupil:1.1") {
exclude group: 'org.jetbrains.kotlinx', module: 'kotlinx-serialization-core-jvm'
}
testImplementation 'junit:junit:4.13'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index bff446d8..ee5f51b2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -37,8 +37,11 @@
+
+
diff --git a/app/src/main/java/xyz/quaver/pupil/Pupil.kt b/app/src/main/java/xyz/quaver/pupil/Pupil.kt
index 3e1207fa..1151b7e9 100644
--- a/app/src/main/java/xyz/quaver/pupil/Pupil.kt
+++ b/app/src/main/java/xyz/quaver/pupil/Pupil.kt
@@ -18,6 +18,7 @@
package xyz.quaver.pupil
+import android.app.Application
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
@@ -25,7 +26,6 @@ import android.content.Context
import android.os.Build
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.ContextCompat
-import androidx.multidex.MultiDexApplication
import androidx.preference.PreferenceManager
import com.google.android.gms.common.GooglePlayServicesNotAvailableException
import com.google.android.gms.common.GooglePlayServicesRepairableException
@@ -35,16 +35,37 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
-import xyz.quaver.proxy
+import okhttp3.Dispatcher
+import okhttp3.Interceptor
+import okhttp3.OkHttpClient
+import okhttp3.Response
import xyz.quaver.pupil.util.GalleryList
-import xyz.quaver.pupil.util.getProxy
+import xyz.quaver.pupil.util.getProxyInfo
+import xyz.quaver.setClient
import java.io.File
import java.util.*
+import java.util.concurrent.TimeUnit
+import kotlin.reflect.KClass
-class Pupil : MultiDexApplication() {
+typealias PupilInterceptor = (Interceptor.Chain) -> Response
- lateinit var histories: GalleryList
- lateinit var favorites: GalleryList
+lateinit var histories: GalleryList
+ private set
+lateinit var favorites: GalleryList
+ private set
+
+val interceptors = mutableMapOf, PupilInterceptor>()
+
+lateinit var clientBuilder: OkHttpClient.Builder
+
+var clientHolder: OkHttpClient? = null
+val client: OkHttpClient
+ get() = clientHolder ?: clientBuilder.build().also {
+ clientHolder = it
+ setClient(it)
+ }
+
+class Pupil : Application() {
init {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
@@ -63,7 +84,19 @@ class Pupil : MultiDexApplication() {
FirebaseCrashlytics.getInstance().setUserId(userID)
- proxy = getProxy(this)
+ val proxyInfo = getProxyInfo(this)
+
+ clientBuilder = OkHttpClient.Builder()
+ .connectTimeout(0, TimeUnit.SECONDS)
+ .readTimeout(0, TimeUnit.SECONDS)
+ .proxy(proxyInfo.proxy())
+ .proxyAuthenticator(proxyInfo.authenticator())
+ .addInterceptor { chain ->
+ val request = chain.request()
+ val tag = request.tag() ?: return@addInterceptor chain.proceed(request)
+
+ interceptors[tag::class]?.invoke(chain) ?: chain.proceed(request)
+ }
try {
preference.getString("dl_location", null).also {
@@ -112,6 +145,13 @@ class Pupil : MultiDexApplication() {
lockscreenVisibility = Notification.VISIBILITY_SECRET
})
+ manager.createNotificationChannel(NotificationChannel("downloader", getString(R.string.channel_downloader), NotificationManager.IMPORTANCE_LOW).apply {
+ description = getString(R.string.channel_downloader_description)
+ enableLights(false)
+ enableVibration(false)
+ lockscreenVisibility = Notification.VISIBILITY_SECRET
+ })
+
manager.createNotificationChannel(NotificationChannel("update", getString(R.string.channel_update), NotificationManager.IMPORTANCE_HIGH).apply {
description = getString(R.string.channel_update_description)
enableLights(true)
@@ -127,7 +167,6 @@ class Pupil : MultiDexApplication() {
})
}
- AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
AppCompatDelegate.setDefaultNightMode(when (preference.getBoolean("dark_mode", false)) {
true -> AppCompatDelegate.MODE_NIGHT_YES
false -> AppCompatDelegate.MODE_NIGHT_NO
diff --git a/app/src/main/java/xyz/quaver/pupil/PupilGlideModule.kt b/app/src/main/java/xyz/quaver/pupil/PupilGlideModule.kt
index da85e719..a46bf974 100644
--- a/app/src/main/java/xyz/quaver/pupil/PupilGlideModule.kt
+++ b/app/src/main/java/xyz/quaver/pupil/PupilGlideModule.kt
@@ -35,7 +35,7 @@ class PupilGlideModule : AppGlideModule() {
registry.append(
GlideUrl::class.java,
InputStream::class.java,
- OkHttpUrlLoader.Factory(DownloadWorker.getInstance(context).client)
+ OkHttpUrlLoader.Factory(client)
)
}
diff --git a/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt b/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt
index 4a41afb2..5de9354b 100644
--- a/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt
+++ b/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt
@@ -52,6 +52,7 @@ import xyz.quaver.hitomi.getReader
import xyz.quaver.pupil.BuildConfig
import xyz.quaver.pupil.Pupil
import xyz.quaver.pupil.R
+import xyz.quaver.pupil.favorites
import xyz.quaver.pupil.types.Tag
import xyz.quaver.pupil.util.GalleryList
import xyz.quaver.pupil.util.download.Cache
@@ -68,8 +69,6 @@ class GalleryBlockAdapter(private val glide: RequestManager, private val galleri
PREV
}
- private lateinit var favorites: GalleryList
-
val timer = Timer()
var isThin = false
@@ -257,9 +256,6 @@ class GalleryBlockAdapter(private val glide: RequestManager, private val galleri
}
}
- if (!::favorites.isInitialized)
- favorites = (context.applicationContext as Pupil).favorites
-
with(galleryblock_favorite) {
setImageResource(if (favorites.contains(galleryBlock.id)) R.drawable.ic_star_filled else R.drawable.ic_star_empty)
setOnClickListener {
diff --git a/app/src/main/java/xyz/quaver/pupil/BroadcastReciever.kt b/app/src/main/java/xyz/quaver/pupil/reciever/UpdateBroadcastReciever.kt
similarity index 93%
rename from app/src/main/java/xyz/quaver/pupil/BroadcastReciever.kt
rename to app/src/main/java/xyz/quaver/pupil/reciever/UpdateBroadcastReciever.kt
index 2456da45..7787e713 100644
--- a/app/src/main/java/xyz/quaver/pupil/BroadcastReciever.kt
+++ b/app/src/main/java/xyz/quaver/pupil/reciever/UpdateBroadcastReciever.kt
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-package xyz.quaver.pupil
+package xyz.quaver.pupil.reciever
import android.app.DownloadManager
import android.app.PendingIntent
@@ -29,15 +29,10 @@ import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.FileProvider
import androidx.preference.PreferenceManager
+import xyz.quaver.pupil.R
import java.io.File
-class BroadcastReciever : BroadcastReceiver() {
-
- companion object {
- const val ACTION_CANCEL_IMPORT = "ACTION_CANCEL_IMPORT"
-
- const val EXTRA_IMPORT_NOTIFICATION_ID = "EXTRA_IMPORT_NOTIFICATION_ID"
- }
+class UpdateBroadcastReciever : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
context ?: return
diff --git a/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt b/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt
new file mode 100644
index 00000000..95212beb
--- /dev/null
+++ b/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt
@@ -0,0 +1,155 @@
+/*
+ * Pupil, Hitomi.la viewer for Android
+ * Copyright (C) 2020 tom5079
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package xyz.quaver.pupil.services
+
+import android.app.Service
+import android.content.Context
+import android.content.ContextWrapper
+import android.content.Intent
+import android.os.Binder
+import android.os.IBinder
+import android.util.SparseArray
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.Interceptor
+import okhttp3.ResponseBody
+import okio.*
+import xyz.quaver.pupil.R
+
+private typealias ProgressListener = (Any?, Long, Long, Boolean) -> Unit
+
+class Cache(context: Context) : ContextWrapper(context) {
+
+
+
+}
+
+class DownloadService : Service() {
+
+ //region Notification
+ private val notificationManager by lazy {
+ NotificationManagerCompat.from(this)
+ }
+
+ private val serviceNotification by lazy {
+ NotificationCompat.Builder(this, "downloader")
+ .setContentTitle(getString(R.string.downloader_running))
+ .setProgress(0, 0, false)
+ .setSmallIcon(R.drawable.ic_notification)
+ .setOngoing(true)
+ }
+ //endregion
+
+ //region ProgressListener
+ @Suppress("UNCHECKED_CAST")
+ private val progressListener: ProgressListener = listener@{ tag, bytesRead, contentLength, done ->
+ val (galleryID, index) = (tag as? Pair) ?: return@listener
+
+ if (!done && progress[galleryID]?.get(index)?.isFinite() == true)
+ progress[galleryID]?.set(index, bytesRead * 100F / contentLength)
+ }
+
+ private class ProgressResponseBody(
+ val tag: Any?,
+ val responseBody: ResponseBody,
+ val progressListener : ProgressListener
+ ) : ResponseBody() {
+ private var bufferedSource : BufferedSource? = null
+
+ override fun contentLength() = responseBody.contentLength()
+ override fun contentType() = responseBody.contentType()
+
+ override fun source(): BufferedSource {
+ if (bufferedSource == null)
+ bufferedSource = Okio.buffer(source(responseBody.source()))
+
+ return bufferedSource!!
+ }
+
+ private fun source(source: Source) = object: ForwardingSource(source) {
+ var totalBytesRead = 0L
+
+ override fun read(sink: Buffer, byteCount: Long): Long {
+ val bytesRead = super.read(sink, byteCount)
+
+ totalBytesRead += if (bytesRead == -1L) 0L else bytesRead
+ progressListener.invoke(tag, totalBytesRead, responseBody.contentLength(), bytesRead == -1L)
+
+ return bytesRead
+ }
+ }
+ }
+
+ val interceptor = Interceptor { chain ->
+ val request = chain.request()
+ var response = chain.proceed(request)
+
+ var retry = 5
+ while (!response.isSuccessful && retry > 0) {
+ response = chain.proceed(request)
+ retry--
+ }
+
+ response.newBuilder()
+ .body(response.body()?.let {
+ ProgressResponseBody(request.tag(), it, progressListener)
+ }).build()
+ }
+ //endregion
+
+ /**
+ * KEY
+ * primary galleryID
+ * secondary index
+ * PRIMARY VALUE
+ * MutableList -> Download in progress
+ * null -> Loading / Gallery doesn't exist
+ * SECONDARY VALUE
+ * 0 <= value < 100 -> Download in progress
+ * Float.POSITIVE_INFINITY -> Download completed
+ */
+ val progress = SparseArray?>()
+
+ override fun onCreate() {
+ startForeground(R.id.downloader_notification_id, serviceNotification.build())
+ }
+
+ override fun onDestroy() {
+
+ }
+
+
+ inner class Binder : android.os.Binder() {
+ val service = this@DownloadService
+ }
+
+ private val binder = Binder()
+ override fun onBind(p0: Intent?) = binder
+
+ fun load(galleryID: Int) {
+
+ }
+
+ fun download(galleryID: Int) = CoroutineScope(Dispatchers.IO).launch {
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt b/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt
index 51916851..3bbc8701 100644
--- a/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt
+++ b/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt
@@ -22,7 +22,9 @@ import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.graphics.drawable.Animatable
+import android.net.Proxy
import android.net.Uri
+import android.os.Build
import android.os.Bundle
import android.text.*
import android.text.style.AlignmentSpan
@@ -59,9 +61,11 @@ import xyz.quaver.hitomi.GalleryBlock
import xyz.quaver.hitomi.doSearch
import xyz.quaver.hitomi.getGalleryIDsFromNozomi
import xyz.quaver.hitomi.getSuggestionsForQuery
-import xyz.quaver.pupil.Pupil
import xyz.quaver.pupil.R
import xyz.quaver.pupil.adapters.GalleryBlockAdapter
+import xyz.quaver.pupil.favorites
+import xyz.quaver.pupil.histories
+import xyz.quaver.pupil.services.DownloadService
import xyz.quaver.pupil.types.TagSuggestion
import xyz.quaver.pupil.types.Tags
import xyz.quaver.pupil.ui.dialog.GalleryDialog
@@ -110,9 +114,6 @@ class MainActivity : AppCompatActivity() {
private var loadingJob: Job? = null
private var currentPage = 0
- private lateinit var histories: GalleryList
- private lateinit var favorites: GalleryList
-
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -147,11 +148,6 @@ class MainActivity : AppCompatActivity() {
}
}
- with(application as Pupil) {
- this@MainActivity.histories = histories
- this@MainActivity.favorites = favorites
- }
-
if (intent.action == Intent.ACTION_VIEW) {
intent.dataString?.let { url ->
restore(favorites, url,
@@ -166,6 +162,15 @@ class MainActivity : AppCompatActivity() {
setContentView(R.layout.activity_main)
+ Intent(this, DownloadService::class.java).let {
+ when {
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ->
+ startForegroundService(it)
+ else ->
+ startService(it)
+ }
+ }
+
checkUpdate(this)
initView()
diff --git a/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt b/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt
index 1370b36a..dc9dbaf9 100644
--- a/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt
+++ b/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt
@@ -46,6 +46,8 @@ import xyz.quaver.Code
import xyz.quaver.pupil.Pupil
import xyz.quaver.pupil.R
import xyz.quaver.pupil.adapters.ReaderAdapter
+import xyz.quaver.pupil.favorites
+import xyz.quaver.pupil.histories
import xyz.quaver.pupil.util.GalleryList
import xyz.quaver.pupil.util.download.Cache
import xyz.quaver.pupil.util.download.DownloadWorker
@@ -78,16 +80,12 @@ class ReaderActivity : AppCompatActivity() {
private var menu: Menu? = null
- private lateinit var favorites: GalleryList
-
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
title = getString(R.string.reader_loading)
supportActionBar?.setDisplayHomeAsUpEnabled(false)
- favorites = (application as Pupil).favorites
-
window.setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE)
@@ -96,7 +94,7 @@ class ReaderActivity : AppCompatActivity() {
handleIntent(intent)
- (application as Pupil).histories.add(galleryID)
+ histories.add(galleryID)
FirebaseCrashlytics.getInstance().setCustomKey("GalleryID", galleryID)
if (galleryID == 0) {
diff --git a/app/src/main/java/xyz/quaver/pupil/ui/SettingsActivity.kt b/app/src/main/java/xyz/quaver/pupil/ui/SettingsActivity.kt
index f2a43b3b..98f4f592 100644
--- a/app/src/main/java/xyz/quaver/pupil/ui/SettingsActivity.kt
+++ b/app/src/main/java/xyz/quaver/pupil/ui/SettingsActivity.kt
@@ -35,6 +35,7 @@ import kotlinx.serialization.json.Json
import net.rdrei.android.dirchooser.DirectoryChooserActivity
import xyz.quaver.pupil.Pupil
import xyz.quaver.pupil.R
+import xyz.quaver.pupil.favorites
import xyz.quaver.pupil.ui.fragment.LockSettingsFragment
import xyz.quaver.pupil.ui.fragment.SettingsFragment
import xyz.quaver.pupil.util.*
@@ -100,7 +101,7 @@ class SettingsActivity : AppCompatActivity() {
inputStream.readBytes().toString(Charset.defaultCharset())
}
- (application as Pupil).favorites.addAll(Json.decodeFromString>(str).also {
+ favorites.addAll(Json.decodeFromString>(str).also {
Snackbar.make(
window.decorView,
getString(R.string.settings_restore_success, it.size),
diff --git a/app/src/main/java/xyz/quaver/pupil/ui/dialog/GalleryDialog.kt b/app/src/main/java/xyz/quaver/pupil/ui/dialog/GalleryDialog.kt
index 6f7f5775..ed2d58a7 100644
--- a/app/src/main/java/xyz/quaver/pupil/ui/dialog/GalleryDialog.kt
+++ b/app/src/main/java/xyz/quaver/pupil/ui/dialog/GalleryDialog.kt
@@ -48,6 +48,7 @@ import xyz.quaver.pupil.Pupil
import xyz.quaver.pupil.R
import xyz.quaver.pupil.adapters.GalleryBlockAdapter
import xyz.quaver.pupil.adapters.ThumbnailPageAdapter
+import xyz.quaver.pupil.histories
import xyz.quaver.pupil.types.Tag
import xyz.quaver.pupil.ui.ReaderActivity
import xyz.quaver.pupil.util.ItemClickSupport
@@ -81,7 +82,7 @@ class GalleryDialog(context: Context, private val glide: RequestManager, private
context.startActivity(Intent(context, ReaderActivity::class.java).apply {
putExtra("galleryID", galleryID)
})
- (context.applicationContext as Pupil).histories.add(galleryID)
+ histories.add(galleryID)
}
}
@@ -264,7 +265,7 @@ class GalleryDialog(context: Context, private val glide: RequestManager, private
context.startActivity(Intent(context, ReaderActivity::class.java).apply {
putExtra("galleryID", galleries[position].id)
})
- (context.applicationContext as Pupil).histories.add(galleries[position].id)
+ histories.add(galleries[position].id)
}
onItemLongClickListener = { _, position, _ ->
GalleryDialog(
diff --git a/app/src/main/java/xyz/quaver/pupil/ui/dialog/ProxyDialog.kt b/app/src/main/java/xyz/quaver/pupil/ui/dialog/ProxyDialog.kt
index 0eccffc4..275e52fb 100644
--- a/app/src/main/java/xyz/quaver/pupil/ui/dialog/ProxyDialog.kt
+++ b/app/src/main/java/xyz/quaver/pupil/ui/dialog/ProxyDialog.kt
@@ -31,8 +31,10 @@ import androidx.preference.PreferenceManager
import kotlinx.android.synthetic.main.dialog_proxy.view.*
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
-import xyz.quaver.proxy
import xyz.quaver.pupil.R
+import xyz.quaver.pupil.client
+import xyz.quaver.pupil.clientBuilder
+import xyz.quaver.pupil.clientHolder
import xyz.quaver.pupil.util.ProxyInfo
import xyz.quaver.pupil.util.getProxyInfo
import java.net.Proxy
@@ -117,12 +119,15 @@ class ProxyDialog(context: Context) : Dialog(context) {
}
ProxyInfo(type, addr, port, username, password).let {
-
PreferenceManager.getDefaultSharedPreferences(context).edit().putString("proxy",
Json.encodeToString(it)
).apply()
- proxy = it.proxy()
+ clientBuilder
+ .proxy(it.proxy())
+ .proxyAuthenticator(it.authenticator())
+ clientHolder = null
+ client
}
dismiss()
diff --git a/app/src/main/java/xyz/quaver/pupil/ui/fragment/ManageFavoritesFragment.kt b/app/src/main/java/xyz/quaver/pupil/ui/fragment/ManageFavoritesFragment.kt
index b04222f9..8fc6b8b8 100644
--- a/app/src/main/java/xyz/quaver/pupil/ui/fragment/ManageFavoritesFragment.kt
+++ b/app/src/main/java/xyz/quaver/pupil/ui/fragment/ManageFavoritesFragment.kt
@@ -30,6 +30,8 @@ import com.google.android.material.snackbar.Snackbar
import okhttp3.*
import xyz.quaver.pupil.Pupil
import xyz.quaver.pupil.R
+import xyz.quaver.pupil.client
+import xyz.quaver.pupil.favorites
import xyz.quaver.pupil.util.restore
import java.io.File
import java.io.IOException
@@ -52,7 +54,7 @@ class ManageFavoritesFragment : PreferenceFragmentCompat() {
.build()
).build()
- OkHttpClient().newCall(request).enqueue(object: Callback {
+ client.newCall(request).enqueue(object: Callback {
override fun onFailure(call: Call, e: IOException) {
val view = view ?: return
Snackbar.make(view, R.string.settings_backup_failed, Snackbar.LENGTH_LONG).show()
@@ -79,7 +81,6 @@ class ManageFavoritesFragment : PreferenceFragmentCompat() {
.setTitle(R.string.settings_restore_title)
.setView(editText)
.setPositiveButton(android.R.string.ok) { _, _ ->
- val favorites = (activity?.application as? Pupil)?.favorites ?: return@setPositiveButton
restore(favorites, editText.text.toString(),
onFailure = onFailure@{
val view = view ?: return@onFailure
diff --git a/app/src/main/java/xyz/quaver/pupil/ui/fragment/SettingsFragment.kt b/app/src/main/java/xyz/quaver/pupil/ui/fragment/SettingsFragment.kt
index a486f289..fe8f4f13 100644
--- a/app/src/main/java/xyz/quaver/pupil/ui/fragment/SettingsFragment.kt
+++ b/app/src/main/java/xyz/quaver/pupil/ui/fragment/SettingsFragment.kt
@@ -40,6 +40,7 @@ import net.rdrei.android.dirchooser.DirectoryChooserActivity
import net.rdrei.android.dirchooser.DirectoryChooserConfig
import xyz.quaver.pupil.Pupil
import xyz.quaver.pupil.R
+import xyz.quaver.pupil.histories
import xyz.quaver.pupil.ui.LockActivity
import xyz.quaver.pupil.ui.SettingsActivity
import xyz.quaver.pupil.ui.dialog.DefaultQueryDialog
@@ -143,8 +144,6 @@ class SettingsFragment :
}.show()
}
"clear_history" -> {
- val histories = (requireContext().applicationContext as Pupil).histories
-
AlertDialog.Builder(requireContext()).apply {
setTitle(R.string.warning)
setMessage(R.string.settings_clear_history_alert_message)
@@ -220,10 +219,10 @@ class SettingsFragment :
when (key) {
"proxy" -> {
- summary = getProxyInfo(requireContext()).type.name
+ summary = context?.let { getProxyInfo(it).type.name }
}
"dl_location" -> {
- summary = getDownloadDirectory(requireContext()).canonicalPath
+ summary = context?.let { getDownloadDirectory(it).canonicalPath }
}
}
}
@@ -286,7 +285,6 @@ class SettingsFragment :
onPreferenceClickListener = this@SettingsFragment
}
"clear_history" -> {
- val histories = (requireActivity().application as Pupil).histories
summary = getString(R.string.settings_clear_history_summary, histories.size)
onPreferenceClickListener = this@SettingsFragment
diff --git a/app/src/main/java/xyz/quaver/pupil/util/download/Cache.kt b/app/src/main/java/xyz/quaver/pupil/util/download/Cache.kt
index ff99c185..a0011718 100644
--- a/app/src/main/java/xyz/quaver/pupil/util/download/Cache.kt
+++ b/app/src/main/java/xyz/quaver/pupil/util/download/Cache.kt
@@ -28,14 +28,13 @@ import kotlinx.coroutines.*
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
-import okhttp3.Dispatcher
import xyz.quaver.Code
import xyz.quaver.hitomi.GalleryBlock
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.readBytes
import java.io.BufferedInputStream
import java.io.File
import java.io.FileOutputStream
@@ -91,11 +90,12 @@ class Cache(context: Context) : ContextWrapper(context) {
@Suppress("BlockingMethodInNonBlockingContext")
val thumbnail = if (metadata?.thumbnail == null)
withContext(Dispatchers.IO) {
- val thumbnails = getGalleryBlock(galleryID)?.thumbnails
+ val thumbnail = getGalleryBlock(galleryID)?.thumbnails?.firstOrNull() ?: return@withContext null
try {
- Base64.encodeToString(URL(thumbnails?.firstOrNull()).openConnection(proxy).getInputStream().use {
- it.readBytes()
- }, Base64.DEFAULT)
+ val data = URL(thumbnail).readBytes().apply {
+ if (isEmpty()) return@withContext null
+ }
+ Base64.encodeToString(data, Base64.DEFAULT)
} catch (e: Exception) {
null
}
@@ -178,7 +178,7 @@ class Cache(context: Context) : ContextWrapper(context) {
retval = try {
withContext(Dispatchers.IO) {
withTimeoutOrNull(1000) {
- source.value.invoke()
+ source.value.invoke()
}
}
} catch (e: Exception) {
diff --git a/app/src/main/java/xyz/quaver/pupil/util/download/DownloadWorker.kt b/app/src/main/java/xyz/quaver/pupil/util/download/DownloadWorker.kt
index 264bdf3a..cbc07dc3 100644
--- a/app/src/main/java/xyz/quaver/pupil/util/download/DownloadWorker.kt
+++ b/app/src/main/java/xyz/quaver/pupil/util/download/DownloadWorker.kt
@@ -40,13 +40,13 @@ import xyz.quaver.hitomi.imageUrlFromImage
import xyz.quaver.hiyobi.cookie
import xyz.quaver.hiyobi.createImgList
import xyz.quaver.hiyobi.user_agent
-import xyz.quaver.proxy
import xyz.quaver.pupil.R
+import xyz.quaver.pupil.client
+import xyz.quaver.pupil.interceptors
import xyz.quaver.pupil.ui.ReaderActivity
import java.io.File
import java.io.IOException
import java.util.concurrent.LinkedBlockingQueue
-import java.util.concurrent.TimeUnit
@OptIn(ExperimentalCoroutinesApi::class)
class DownloadWorker private constructor(context: Context) : ContextWrapper(context) {
@@ -86,7 +86,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
}
private fun source(source: Source) = object: ForwardingSource(source) {
-
var totalBytesRead = 0L
override fun read(sink: Buffer, byteCount: Long): Long {
@@ -100,6 +99,24 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
}
}
+
+ init {
+ interceptors[Pair::class] = { chain ->
+ val request = chain.request()
+ var response = chain.proceed(request)
+
+ var retry = 5
+ while (!response.isSuccessful && retry > 0) {
+ response = chain.proceed(request)
+ retry--
+ }
+
+ response.newBuilder()
+ .body(response.body()?.let {
+ ProgressResponseBody(request.tag(), it, progressListener)
+ }).build()
+ }
+ }
//endregion
//region Singleton
@@ -135,34 +152,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
private val loop = loop()
private val worker = SparseArray()
- val interceptor = Interceptor { chain ->
- val request = chain.request()
- var response = chain.proceed(request)
-
- var retry = 5
- while (!response.isSuccessful && retry > 0) {
- response = chain.proceed(request)
- retry--
- }
-
- response.newBuilder()
- .body(response.body()?.let {
- ProgressResponseBody(request.tag(), it, progressListener)
- }).build()
- }
-
- val client : OkHttpClient =
- OkHttpClient.Builder()
- .connectTimeout(0, TimeUnit.SECONDS)
- .addInterceptor(interceptor)
- .readTimeout(0, TimeUnit.SECONDS)
- .dispatcher(Dispatcher().apply {
- maxRequests = 4
- maxRequestsPerHost = 4
- })
- .proxy(proxy)
- .build()
-
fun stop() {
queue.clear()
@@ -300,8 +289,8 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
val ext = call.request().url().encodedPath().split('.').last()
try {
- response.body().use {
- Cache(this@DownloadWorker).putImage(galleryID, i, ext, it!!.byteStream())
+ response.body()!!.use {
+ Cache(this@DownloadWorker).putImage(galleryID, i, ext, it.byteStream())
}
progress[galleryID]?.set(i, Float.POSITIVE_INFINITY)
diff --git a/app/src/main/java/xyz/quaver/pupil/util/misc.kt b/app/src/main/java/xyz/quaver/pupil/util/misc.kt
index ecbb908b..9beb641a 100644
--- a/app/src/main/java/xyz/quaver/pupil/util/misc.kt
+++ b/app/src/main/java/xyz/quaver/pupil/util/misc.kt
@@ -53,7 +53,7 @@ fun byteToString(byte: Long, precision : Int = 1) : String {
}
-/*
+/**
* Convert android generated ID to requestCode
* to prevent java.lang.IllegalArgumentException: Can only use lower 16 bits for requestCode
*
diff --git a/app/src/main/java/xyz/quaver/pupil/util/proxy.kt b/app/src/main/java/xyz/quaver/pupil/util/proxy.kt
index b6dc406d..061fc280 100644
--- a/app/src/main/java/xyz/quaver/pupil/util/proxy.kt
+++ b/app/src/main/java/xyz/quaver/pupil/util/proxy.kt
@@ -23,8 +23,7 @@ import androidx.preference.PreferenceManager
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
-import okhttp3.Authenticator
-import okhttp3.Credentials
+import okhttp3.*
import java.net.InetSocketAddress
import java.net.Proxy
diff --git a/app/src/main/java/xyz/quaver/pupil/util/update.kt b/app/src/main/java/xyz/quaver/pupil/util/update.kt
index 02424fb8..3efaa876 100644
--- a/app/src/main/java/xyz/quaver/pupil/util/update.kt
+++ b/app/src/main/java/xyz/quaver/pupil/util/update.kt
@@ -35,6 +35,7 @@ import okhttp3.*
import ru.noties.markwon.Markwon
import xyz.quaver.pupil.BuildConfig
import xyz.quaver.pupil.R
+import xyz.quaver.pupil.client
import java.io.File
import java.io.IOException
import java.net.URL
@@ -187,7 +188,7 @@ fun restore(favorites: GalleryList, url: String, onFailure: ((Exception) -> Unit
.get()
.build()
- OkHttpClient().newCall(request).enqueue(object: Callback {
+ client.newCall(request).enqueue(object: Callback {
override fun onFailure(call: Call, e: IOException) {
onFailure?.invoke(e)
}
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index fb8e76bd..e6309d0f 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -140,4 +140,7 @@
ブックマーク管理
エラーが発生しました
バックアップ共有
+ ダウンローダ
+ ダウンローダの状態を表示
+ ダウンローダー起動中
\ No newline at end of file
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index dcd8e9da..b29c0d3a 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -140,4 +140,7 @@
즐겨찾기 관리
업로드 실패
백업 공유
+ 다운로더
+ 다운로더 작동 여부 표시
+ 다운로더 작동중…
\ No newline at end of file
diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml
index 5a1d51a9..7e73441a 100644
--- a/app/src/main/res/values/ids.xml
+++ b/app/src/main/res/values/ids.xml
@@ -10,4 +10,7 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 4c97916b..61e7191a 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -29,6 +29,9 @@
Download
Shows download status
+ Downloader
+ Shows downloader status
+
Update
Shows update progress
@@ -103,6 +106,9 @@
Downloading…
Download complete
+
+ Downloader running…
+
Settings