diff --git a/app/build.gradle b/app/build.gradle index 48bc5882..f805b686 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -38,7 +38,7 @@ android { minSdkVersion 16 targetSdkVersion 30 versionCode 63 - versionName "5.1.6-hotfix7" + versionName "5.1.6-hotfix7-alpha5" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true } @@ -77,7 +77,7 @@ android { dependencies { implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"]) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.0-M1" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.0" implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.0" implementation "androidx.appcompat:appcompat:1.2.0" @@ -85,7 +85,7 @@ dependencies { implementation "androidx.fragment:fragment-ktx:1.3.0-beta01" implementation "androidx.preference:preference-ktx:1.1.1" implementation "androidx.recyclerview:recyclerview:1.1.0" - implementation "androidx.constraintlayout:constraintlayout:2.0.2" + implementation "androidx.constraintlayout:constraintlayout:2.0.4" implementation "androidx.gridlayout:gridlayout:1.0.0" implementation "androidx.biometric:biometric:1.0.1" implementation "androidx.work:work-runtime-ktx:2.4.0" @@ -94,8 +94,8 @@ dependencies { implementation "com.google.android.material:material:1.3.0-alpha03" - implementation "com.google.firebase:firebase-core:17.5.1" - implementation "com.google.firebase:firebase-analytics:17.6.0" + implementation "com.google.firebase:firebase-core:18.0.0" + implementation "com.google.firebase:firebase-analytics:18.0.0" implementation "com.google.firebase:firebase-crashlytics:17.2.2" implementation "com.google.firebase:firebase-perf:19.0.9" @@ -127,7 +127,7 @@ dependencies { implementation "xyz.quaver:documentfilex:0.4-alpha02" implementation "xyz.quaver:floatingsearchview:1.0.7" - testImplementation "junit:junit:4.13" + testImplementation "junit:junit:4.13.1" androidTestImplementation "androidx.test.ext:junit:1.1.2" androidTestImplementation "androidx.test:rules:1.3.0" androidTestImplementation "androidx.test:runner:1.3.0" diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index 1a416ade..56b52b68 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -11,7 +11,7 @@ "type": "SINGLE", "filters": [], "versionCode": 63, - "versionName": "5.1.6-hotfix7", + "versionName": "5.1.6-hotfix7-alpha5", "outputFile": "app-release.apk" } ] diff --git a/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt b/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt index c6a829c5..f38ec3e0 100644 --- a/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt +++ b/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt @@ -45,7 +45,6 @@ import xyz.quaver.pupil.util.ellipsize import xyz.quaver.pupil.util.normalizeID import xyz.quaver.pupil.util.requestBuilders import java.io.IOException -import java.util.* import java.util.concurrent.ConcurrentHashMap import kotlin.math.ceil import kotlin.math.log10 @@ -203,6 +202,8 @@ class DownloadService : Service() { private val callback = object: Callback { override fun onFailure(call: Call, e: IOException) { + e.printStackTrace() + if (e.message?.contains("cancel", true) == false) { val galleryID = (call.request().tag() as Tag).galleryID @@ -235,6 +236,7 @@ class DownloadService : Service() { startId?.let { stopSelf(it) } } }.onFailure { + it.printStackTrace() cancel(galleryID) download(galleryID) } 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 76384193..e819cacd 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 @@ -46,7 +46,6 @@ import xyz.quaver.pupil.R import xyz.quaver.pupil.adapters.GalleryBlockAdapter import xyz.quaver.pupil.adapters.ThumbnailPageAdapter import xyz.quaver.pupil.favoriteTags -import xyz.quaver.pupil.histories import xyz.quaver.pupil.types.Tag import xyz.quaver.pupil.ui.ReaderActivity import xyz.quaver.pupil.ui.view.TagChip 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 94319ee3..50f1b862 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/misc.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/misc.kt @@ -23,9 +23,7 @@ import android.content.Context import android.content.Intent import android.os.Build import androidx.core.content.ContextCompat -import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.jsonArray -import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.* import okhttp3.OkHttpClient import okhttp3.Request import xyz.quaver.Code @@ -137,4 +135,7 @@ operator fun JsonElement.get(index: Int) = this.jsonArray[index] operator fun JsonElement.get(tag: String) = - this.jsonObject[tag] \ No newline at end of file + this.jsonObject[tag] + +val JsonElement.content + get() = this.jsonPrimitive.contentOrNull \ No newline at end of file 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 3c8d3894..dab3ba5f 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/update.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/update.kt @@ -32,6 +32,7 @@ import androidx.appcompat.app.AlertDialog import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.preference.PreferenceManager +import com.google.firebase.crashlytics.FirebaseCrashlytics import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -256,6 +257,13 @@ fun xyz.quaver.pupil.util.downloader.DownloadManager.migrate() { job?.cancel() job = CoroutineScope(Dispatchers.IO).launch { + val images = listOf( + "jpg", + "png", + "gif", + "webp" + ) + val downloadFolders = downloadFolder.listFiles { folder -> folder.isDirectory && !downloadFolderMap.values.contains(folder.name) }?.map { @@ -273,52 +281,56 @@ fun xyz.quaver.pupil.util.downloader.DownloadManager.migrate() { .setProgress(index, downloadFolders.size, false) notificationManager.notify(R.id.notification_id_import, notification.build()) - kotlin.runCatching { - val metadata = kotlin.runCatching { - folder.getChild(".metadata").readText()?.let { Json.parseToJsonElement(it).jsonObject } - }.getOrNull() + val metadata = kotlin.runCatching { + folder.getChild(".metadata").readText()?.let { Json.parseToJsonElement(it) } + }.getOrNull() - val galleryID = folder.name.toIntOrNull() ?: return@runCatching + val galleryID = metadata?.get("reader")?.get("galleryInfo")?.get("id")?.content?.toIntOrNull() + ?: folder.name.toIntOrNull() ?: return@forEachIndexed - val galleryBlock: GalleryBlock? = kotlin.runCatching { - metadata?.get("galleryBlock")?.let { Json.decodeFromJsonElement(it) } - }.getOrNull() ?: getGalleryBlock(galleryID) - val reader: Reader? = kotlin.runCatching { - metadata?.get("reader")?.let { Json.decodeFromJsonElement(it) } - }.getOrNull() ?: getReader(galleryID) + val galleryBlock: GalleryBlock? = kotlin.runCatching { + metadata?.get("galleryBlock")?.let { Json.decodeFromJsonElement(it) } + }.getOrNull() ?: kotlin.runCatching { + getGalleryBlock(galleryID) + }.getOrNull() ?: kotlin.runCatching { + xyz.quaver.hiyobi.getGalleryBlock(galleryID) + }.getOrNull() - metadata?.get("thumbnail")?.jsonPrimitive?.contentOrNull?.also { thumbnail -> - val file = folder.getChild(".thumbnail").also { - if (it.exists()) - it.delete() - it.createNewFile() - } + val reader: Reader? = kotlin.runCatching { + metadata?.get("reader")?.let { Json.decodeFromJsonElement(it) } + }.getOrNull() ?: kotlin.runCatching { + getReader(galleryID) + }.getOrNull() ?: kotlin.runCatching { + xyz.quaver.hiyobi.getReader(galleryID) + }.getOrNull() - file.writeBytes(Base64.decode(thumbnail, Base64.DEFAULT)) + metadata?.get("thumbnail")?.jsonPrimitive?.contentOrNull?.also { thumbnail -> + val file = folder.getChild(".thumbnail").also { + if (it.exists()) + it.delete() + it.createNewFile() } - val list: MutableList = - MutableList(reader!!.galleryInfo.files.size) { null } - - folder.listFiles { file -> - file?.nameWithoutExtension?.let { - Regex("""\d{5}""").matches(it) && it.toIntOrNull() != null - } == true - }?.forEach { - list[it.nameWithoutExtension.toInt()] = it.name - } - - folder.getChild(".metadata").also { if (it.exists()) it.delete(); it.createNewFile() }.writeText( - Json.encodeToString(Metadata(galleryBlock, reader, list)) - ) - - synchronized(Cache) { - Cache.delete(this@migrate, galleryID) - } - downloadFolderMap[galleryID] = folder.name - - downloadFolder.getChild(".download").let { if (!it.exists()) it.createNewFile(); it.writeText(Json.encodeToString(downloadFolderMap)) } + file.writeBytes(Base64.decode(thumbnail, Base64.DEFAULT)) } + + val list: MutableList = + MutableList(reader!!.galleryInfo.files.size) { null } + + folder.list { _, name -> + name?.substringAfterLast('.') in images + }?.sorted()?.take(list.size)?.forEachIndexed { i, name -> + list[i] = name + } + + folder.getChild(".metadata").also { if (it.exists()) it.delete(); it.createNewFile() }.writeText( + Json.encodeToString(Metadata(galleryBlock, reader, list)) + ) + + Cache.delete(this@migrate, galleryID) + downloadFolderMap[galleryID] = folder.name + + downloadFolder.getChild(".download").let { if (!it.exists()) it.createNewFile(); it.writeText(Json.encodeToString(downloadFolderMap)) } } notification