Compare commits

...

6 Commits

Author SHA1 Message Date
tom5079
fe02abc9e8 Bug fix 2020-09-08 20:04:12 +09:00
tom5079
59347ab317 Bug fix 2020-09-08 19:16:15 +09:00
tom5079
f408a91176 Bug fix 2020-09-07 10:00:10 +09:00
tom5079
6f6956ce27 Fixed DownloadLocationDialogFragment keep showing up when any button is clicked 2020-09-06 17:19:18 +09:00
tom5079
4ecad8eccc Fixed migration 2020-09-05 18:31:53 +09:00
tom5079
486fbe46a0 Fixed migration 2020-09-05 18:11:20 +09:00
24 changed files with 79 additions and 69 deletions

View File

@@ -56,5 +56,10 @@
<option name="name" value="MavenLocal" />
<option name="url" value="file:/$USER_HOME$/.m2/repository/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenLocal" />
<option name="name" value="MavenLocal" />
<option name="url" value="file:/$USER_HOME$/.m2/repository" />
</remote-repository>
</component>
</project>

View File

@@ -14,13 +14,13 @@ if (file("google-services.json").exists() && file("src/debug/google-services.jso
}
android {
compileSdkVersion 29
compileSdkVersion 30
defaultConfig {
applicationId "xyz.quaver.pupil"
minSdkVersion 16
targetSdkVersion 29
targetSdkVersion 30
versionCode 57
versionName "5.0-beta3"
versionName "5.0-beta6"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
@@ -63,7 +63,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-core:1.0.0-RC-HOTFIX1"
//implementation "org.jetbrains.kotlinx:kotlinx-serialization-core:1.0.0-RC"
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'androidx.preference:preference:1.1.1'
@@ -96,10 +96,10 @@ 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.3") {
implementation ("xyz.quaver:libpupil:1.5") {
exclude group: 'org.jetbrains.kotlinx', module: 'kotlinx-serialization-core-jvm'
}
implementation "xyz.quaver:documentfilex:0.2.14-alpha2"
implementation "xyz.quaver:documentfilex:0.2.14"
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test:rules:1.3.0'

Binary file not shown.

View File

@@ -21,6 +21,7 @@
#-renamesourcefileattribute SourceFile
-dontobfuscate
-dontoptimize
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep class * extends com.bumptech.glide.module.AppGlideModule {

View File

@@ -12,7 +12,7 @@
"filters": [],
"properties": [],
"versionCode": 57,
"versionName": "5.0-beta3",
"versionName": "5.0-beta6",
"enabled": true,
"outputFile": "app-release.apk"
}

View File

@@ -97,7 +97,7 @@ class Pupil : Application() {
try {
Preferences.get<String>("download_folder").also {
if (Build.VERSION.SDK_INT > 19)
if (it.startsWith("content") && Build.VERSION.SDK_INT > 19)
contentResolver.takePersistableUriPermission(
Uri.parse(it),
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION

View File

@@ -50,6 +50,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import xyz.quaver.hitomi.getReader
import xyz.quaver.io.util.getChild
import xyz.quaver.pupil.BuildConfig
import xyz.quaver.pupil.R
import xyz.quaver.pupil.favorites
@@ -92,11 +93,10 @@ class GalleryBlockAdapter(private val glide: RequestManager, private val galleri
val imageList = cache.metadata.imageList!!
progress = imageList.filterNotNull().size
max = imageList.size
if (visibility == View.GONE) {
if (visibility == View.GONE)
visibility = View.VISIBLE
max = imageList.size
}
if (progress == max) {
val downloadManager = DownloadManager.getInstance(context)
@@ -169,7 +169,10 @@ class GalleryBlockAdapter(private val glide: RequestManager, private val galleri
target: Target<Drawable>?,
isFirstResource: Boolean
): Boolean {
Cache.getInstance(context, galleryID).findFile(".thumbnail")?.let { if (it.exists()) it.delete() }
Cache.getInstance(context, galleryID).let {
it.cacheFolder.getChild(".thumbnail").let { if (it.exists()) it.delete() }
it.downloadFolder?.getChild(".thumbnail")?.let { if (it.exists()) it.delete() }
}
return false
}

View File

@@ -40,9 +40,7 @@ import xyz.quaver.Code
import xyz.quaver.hitomi.Reader
import xyz.quaver.hitomi.getReferer
import xyz.quaver.hitomi.imageUrlFromImage
import xyz.quaver.hiyobi.cookie
import xyz.quaver.hiyobi.createImgList
import xyz.quaver.hiyobi.user_agent
import xyz.quaver.io.util.readBytes
import xyz.quaver.pupil.R
import xyz.quaver.pupil.services.DownloadService
@@ -116,10 +114,7 @@ class ReaderAdapter(private val activity: ReaderActivity,
)
, LazyHeaders.Builder().addHeader("Referer", getReferer(galleryID)).build())
Code.HIYOBI ->
GlideUrl(createImgList(galleryID, reader!!, lowQuality)[position].path, LazyHeaders.Builder()
.addHeader("User-Agent", user_agent)
.addHeader("Cookie", cookie)
.build())
GlideUrl(createImgList(galleryID, reader!!, lowQuality)[position].path)
else -> null
}
holder.view.image.post {

View File

@@ -307,13 +307,18 @@ class DownloadService : Service() {
return@launch
}
if (progress.indexOfKey(galleryID) < 0)
progress.put(galleryID, MutableList(reader.galleryInfo.files.size) { 0F })
progress.put(galleryID, MutableList(reader.galleryInfo.files.size) { 0F })
cache.metadata.imageList?.forEachIndexed { index, image ->
progress[galleryID]?.set(index, if (image != null) Float.POSITIVE_INFINITY else 0F)
}
if (isCompleted(galleryID)) {
notificationManager.cancel(galleryID)
startId?.let { stopSelf(it) }
return@launch
}
notification[galleryID]?.setContentTitle(reader.galleryInfo.title?.ellipsize(30))
notify(galleryID)
@@ -328,9 +333,11 @@ class DownloadService : Service() {
}
}
reader.requestBuilders.filterIndexed { index, _ -> progress[galleryID]?.get(index)?.isInfinite() != true }.forEachIndexed { index, it ->
val request = it.tag(Tag(galleryID, index, startId)).build()
client.newCall(request).enqueue(callback)
reader.requestBuilders.forEachIndexed { index, it ->
if (progress[galleryID]?.get(index)?.isInfinite() != true) {
val request = it.tag(Tag(galleryID, index, startId)).build()
client.newCall(request).enqueue(callback)
}
}
queued.forEach { download(it) }
@@ -382,6 +389,8 @@ class DownloadService : Service() {
COMMAND_DELETE -> intent.getIntExtra(KEY_ID, -1).let { if (it > 0) delete(it, startId) }
}
startForeground(R.id.downloader_notification_id, serviceNotification.build())
return START_NOT_STICKY
}
@@ -393,7 +402,6 @@ class DownloadService : Service() {
override fun onBind(p0: Intent?) = binder
override fun onCreate() {
startForeground(R.id.downloader_notification_id, serviceNotification.build())
interceptors[Tag::class] = interceptor
}

View File

@@ -981,7 +981,7 @@ class MainActivity : AppCompatActivity() {
if (query.isNotEmpty() && mode != Mode.SEARCH) {
Snackbar.make(this@MainActivity.main_recyclerview, R.string.search_all, Snackbar.LENGTH_SHORT).apply {
setAction(android.R.string.yes) {
setAction(android.R.string.ok) {
cancelFetch()
clearGalleries()
currentPage = 0
@@ -1034,7 +1034,7 @@ class MainActivity : AppCompatActivity() {
val downloads = DownloadManager.getInstance(this@MainActivity).downloadFolderMap.keys.toList()
when {
query.isEmpty() -> downloads.also {
query.isEmpty() -> downloads.reversed().also {
totalItems = it.size
}
else -> {

View File

@@ -196,8 +196,8 @@ class ReaderActivity : AppCompatActivity() {
return true
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when(item?.itemId) {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when(item.itemId) {
R.id.reader_menu_page_indicator -> {
val view = LayoutInflater.from(this).inflate(R.layout.dialog_numberpicker, reader_layout, false)
with(view.dialog_number_picker) {

View File

@@ -68,8 +68,8 @@ class SettingsActivity : AppCompatActivity() {
super.onResume()
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when (item?.itemId) {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> onBackPressed()
}

View File

@@ -122,6 +122,9 @@ class DownloadLocationDialogFragment : DialogFragment() {
.setTitle(R.string.settings_download_folder)
.setView(build())
.setPositiveButton(requireContext().getText(android.R.string.ok)) { _, _ ->
if (Preferences["download_folder", ""].isEmpty())
Preferences["download_folder"] = context?.getExternalFilesDir(null)?.canonicalPath ?: ""
DownloadManager.getInstance(requireContext()).migrate()
}

View File

@@ -82,7 +82,7 @@ class MirrorDialog(context: Context) : AlertDialog(context) {
}
onItemMoved = {
Preferences["mirrors", it.joinToString(">")]
Preferences["mirrors"] = it.joinToString(">")
}
}
}

View File

@@ -74,11 +74,11 @@ class LockSettingsFragment : PreferenceFragmentCompat() {
setTitle(R.string.warning)
setMessage(R.string.settings_lock_remove_message)
setPositiveButton(android.R.string.yes) { _, _ ->
setPositiveButton(android.R.string.ok) { _, _ ->
lockManager.remove(Lock.Type.PATTERN)
onResume()
}
setNegativeButton(android.R.string.no) { _, _ -> }
setNegativeButton(android.R.string.cancel) { _, _ -> }
}.show()
} else {
val intent = Intent(requireContext(), LockActivity::class.java).apply {
@@ -107,11 +107,11 @@ class LockSettingsFragment : PreferenceFragmentCompat() {
setTitle(R.string.warning)
setMessage(R.string.settings_lock_remove_message)
setPositiveButton(android.R.string.yes) { _, _ ->
setPositiveButton(android.R.string.ok) { _, _ ->
lockManager.remove(Lock.Type.PIN)
onResume()
}
setNegativeButton(android.R.string.no) { _, _ -> }
setNegativeButton(android.R.string.cancel) { _, _ -> }
}.show()
} else {
val intent = Intent(requireContext(), LockActivity::class.java).apply {

View File

@@ -57,7 +57,7 @@ class ManageStorageFragment : PreferenceFragmentCompat(), Preference.OnPreferenc
AlertDialog.Builder(context).apply {
setTitle(R.string.warning)
setMessage(R.string.settings_clear_cache_alert_message)
setPositiveButton(android.R.string.yes) { _, _ ->
setPositiveButton(android.R.string.ok) { _, _ ->
if (dir.exists())
dir.deleteRecursively()
@@ -74,7 +74,7 @@ class ManageStorageFragment : PreferenceFragmentCompat(), Preference.OnPreferenc
}
}
}
setNegativeButton(android.R.string.no) { _, _ -> }
setNegativeButton(android.R.string.cancel) { _, _ -> }
}.show()
}
"delete_downloads" -> {
@@ -83,7 +83,7 @@ class ManageStorageFragment : PreferenceFragmentCompat(), Preference.OnPreferenc
AlertDialog.Builder(context).apply {
setTitle(R.string.warning)
setMessage(R.string.settings_clear_downloads_alert_message)
setPositiveButton(android.R.string.yes) { _, _ ->
setPositiveButton(android.R.string.ok) { _, _ ->
CoroutineScope(Dispatchers.IO).launch {
job?.cancel()
launch(Dispatchers.Main) {
@@ -109,18 +109,18 @@ class ManageStorageFragment : PreferenceFragmentCompat(), Preference.OnPreferenc
}
}
}
setNegativeButton(android.R.string.no) { _, _ -> }
setNegativeButton(android.R.string.cancel) { _, _ -> }
}.show()
}
"clear_history" -> {
AlertDialog.Builder(context).apply {
setTitle(R.string.warning)
setMessage(R.string.settings_clear_history_alert_message)
setPositiveButton(android.R.string.yes) { _, _ ->
setPositiveButton(android.R.string.ok) { _, _ ->
histories.clear()
summary = context.getString(R.string.settings_clear_history_summary, histories.size)
}
setNegativeButton(android.R.string.no) { _, _ -> }
setNegativeButton(android.R.string.cancel) { _, _ -> }
}.show()
}
else -> return false

View File

@@ -36,15 +36,17 @@ class GalleryList(private val file: File, private val list: MutableSet<Int> = mu
fun load() {
synchronized(this) {
list.clear()
list.addAll(
kotlin.runCatching {
Json.decodeFromString<List<Int>>(file.bufferedReader().use { it.readText() })
)
}.onSuccess {
list.addAll(it)
}
}
}
fun save() {
synchronized(this) {
file.writeText(Json.encodeToString(list))
file.writeText(Json.encodeToString(list.toList()))
}
}

View File

@@ -41,6 +41,7 @@ import java.io.FileOutputStream
import java.io.InputStream
import java.net.URL
@Suppress("DEPRECATION")
@Deprecated("Use downloader.Cache instead")
class Cache(context: Context) : ContextWrapper(context) {

View File

@@ -37,9 +37,7 @@ import xyz.quaver.Code
import xyz.quaver.hitomi.Reader
import xyz.quaver.hitomi.getReferer
import xyz.quaver.hitomi.imageUrlFromImage
import xyz.quaver.hiyobi.cookie
import xyz.quaver.hiyobi.createImgList
import xyz.quaver.hiyobi.user_agent
import xyz.quaver.pupil.R
import xyz.quaver.pupil.client
import xyz.quaver.pupil.interceptors
@@ -48,6 +46,7 @@ import java.io.File
import java.io.IOException
import java.util.concurrent.LinkedBlockingQueue
@Suppress("DEPRECATION")
@Deprecated("Use DownloadService instead")
@OptIn(ExperimentalCoroutinesApi::class)
class DownloadWorker private constructor(context: Context) : ContextWrapper(context) {
@@ -219,8 +218,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
}
Code.HIYOBI -> {
url(createImgList(galleryID, reader, lowQuality)[index].path)
addHeader("User-Agent", user_agent)
addHeader("Cookie", cookie)
}
else -> {
//shouldn't be called anyway

View File

@@ -22,6 +22,7 @@ import kotlinx.serialization.Serializable
import xyz.quaver.hitomi.GalleryBlock
import xyz.quaver.hitomi.Reader
@Suppress("DEPRECATION")
@Deprecated("Use downloader.Cache.Metadata instead")
@Serializable
data class Metadata(

View File

@@ -60,6 +60,7 @@ class Cache private constructor(context: Context, val galleryID: Int) : ContextW
instances[galleryID] ?: Cache(context, galleryID).also { instances.put(galleryID, it) }
}
@Synchronized
fun delete(galleryID: Int) {
instances[galleryID]?.cacheFolder?.deleteRecursively()
instances.delete(galleryID)
@@ -86,11 +87,11 @@ class Cache private constructor(context: Context, val galleryID: Int) : ContextW
}
fun findFile(fileName: String): FileX? =
cacheFolder.getChild(fileName).let {
downloadFolder?.let { downloadFolder -> downloadFolder.getChild(fileName).let {
if (it.exists()) it else null
} ?: downloadFolder?.let { downloadFolder -> downloadFolder.getChild(fileName).let {
} } ?: cacheFolder.getChild(fileName).let {
if (it.exists()) it else null
} }
}
@Suppress("BlockingMethodInNonBlockingContext")
fun setMetadata(change: (Metadata) -> Unit) {

View File

@@ -27,6 +27,7 @@ import java.io.FileOutputStream
import java.lang.reflect.Array
import java.net.URL
@Suppress("DEPRECATION")
@Deprecated("Use downloader.Cache instead")
fun getCachedGallery(context: Context, galleryID: Int) =
File(getDownloadDirectory(context), galleryID.toString()).let {
@@ -36,6 +37,7 @@ fun getCachedGallery(context: Context, galleryID: Int) =
File(context.cacheDir, "imageCache/$galleryID")
}
@Suppress("DEPRECATION")
@Deprecated("Use downloader.Cache instead")
fun getDownloadDirectory(context: Context) =
Preferences.get<String>("dl_location").let {
@@ -45,6 +47,7 @@ fun getDownloadDirectory(context: Context) =
context.getExternalFilesDir(null)!!
}
@Suppress("DEPRECATION")
@Deprecated("Use FileX instead")
fun File.isParentOf(another: File) =
another.absolutePath.startsWith(this.absolutePath)

View File

@@ -22,11 +22,6 @@ import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Build
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import okhttp3.OkHttpClient
import okhttp3.Request
import xyz.quaver.Code
@@ -34,11 +29,7 @@ import xyz.quaver.hitomi.GalleryBlock
import xyz.quaver.hitomi.Reader
import xyz.quaver.hitomi.getReferer
import xyz.quaver.hitomi.imageUrlFromImage
import xyz.quaver.hiyobi.cookie
import xyz.quaver.hiyobi.createImgList
import xyz.quaver.hiyobi.user_agent
import xyz.quaver.pupil.util.downloader.Cache
import xyz.quaver.pupil.util.downloader.Metadata
import java.util.*
import kotlin.collections.ArrayList
@@ -134,8 +125,6 @@ val Reader.requestBuilders: List<Request.Builder>
createImgList(galleryID, this, lowQuality).map {
Request.Builder()
.url(it.path)
.header("User-Agent", user_agent)
.header("Cookie", cookie)
}
}
}

View File

@@ -158,7 +158,7 @@ fun checkUpdate(context: Context, force: Boolean = false) {
setTitle(R.string.update_title)
val msg = extractReleaseNote(update, Locale.getDefault())
setMessage(Markwon.create(context).toMarkdown(msg))
setPositiveButton(android.R.string.yes) { _, _ ->
setPositiveButton(android.R.string.ok) { _, _ ->
val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
@@ -181,7 +181,7 @@ fun checkUpdate(context: Context, force: Boolean = false) {
Preferences["update_download_id"] = it
}
}
setNegativeButton(if (force) android.R.string.no else R.string.ignore_update) { _, _ ->
setNegativeButton(if (force) android.R.string.cancel else R.string.ignore_update) { _, _ ->
if (!force)
preferences.edit()
.putLong("ignore_update_until", System.currentTimeMillis() + 604800000)
@@ -310,15 +310,14 @@ fun xyz.quaver.pupil.util.downloader.DownloadManager.migrate() {
)
synchronized(Cache) {
Cache.instances.delete(galleryID)
Cache.delete(galleryID)
}
downloadFolderMap[galleryID] = folder.name
downloadFolder.getChild(".download").let { if (!it.exists()) it.createNewFile(); it.writeText(Json.encodeToString(downloadFolderMap)) }
}
}
downloadFolder.getChild(".download").let { if (!it.exists()) it.createNewFile() }
downloadFolder.getChild(".download").writeText(Json.encodeToString(downloadFolderMap))
notification
.setContentText(getText(R.string.import_old_galleries_notification_done))
.setProgress(0, 0, false)
@@ -326,6 +325,8 @@ fun xyz.quaver.pupil.util.downloader.DownloadManager.migrate() {
.mActions.clear()
notificationManager.notify(R.id.notification_id_import, notification.build())
unregisterReceiver(receiver)
kotlin.runCatching {
unregisterReceiver(receiver)
}
}
}