diff --git a/app/build.gradle b/app/build.gradle index 768db315..9c5b02f9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -21,7 +21,7 @@ android { minSdkVersion 16 targetSdkVersion 30 versionCode 60 - versionName "5.1-hotfix1" + versionName "5.1-hotfix2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true } @@ -104,9 +104,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.6") { - exclude group: 'org.jetbrains.kotlinx', module: 'kotlinx-serialization-core-jvm' - } + implementation 'xyz.quaver:libpupil:1.7.1' implementation "xyz.quaver:documentfilex:0.2.15" implementation "xyz.quaver:floatingsearchview:1.0.4" testImplementation 'junit:junit:4.13' diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index 9987c4a3..e6221dec 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -12,7 +12,7 @@ "filters": [], "properties": [], "versionCode": 60, - "versionName": "5.1-hotfix1", + "versionName": "5.1-hotfix2", "enabled": true, "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 36755a49..1fcacd4f 100644 --- a/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt +++ b/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt @@ -23,7 +23,6 @@ import android.app.PendingIntent import android.app.Service import android.content.Context import android.content.Intent -import android.util.SparseArray import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.core.app.TaskStackBuilder @@ -49,10 +48,9 @@ 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.concurrent.ConcurrentHashMap import kotlin.math.ceil -import kotlin.math.floor import kotlin.math.log10 -import kotlin.math.roundToInt private typealias ProgressListener = (DownloadService.Tag, Long, Long, Boolean) -> Unit class DownloadService : Service() { @@ -71,7 +69,7 @@ class DownloadService : Service() { .setOngoing(true) } - private val notification = SparseArray() + private val notification = ConcurrentHashMap() private fun initNotification(galleryID: Int) { val intent = Intent(this, ReaderActivity::class.java) @@ -199,7 +197,7 @@ class DownloadService : Service() { * 0 <= value < 100 -> Download in progress * Float.POSITIVE_INFINITY -> Download completed */ - val progress = SparseArray?>() + val progress = ConcurrentHashMap>() fun isCompleted(galleryID: Int) = progress[galleryID]?.toList()?.all { it == Float.POSITIVE_INFINITY } == true @@ -297,7 +295,7 @@ class DownloadService : Service() { } fun download(galleryID: Int, priority: Boolean = false, startId: Int? = null): Job = CoroutineScope(Dispatchers.IO).launch { - if (progress.indexOfKey(galleryID) >= 0) + if (progress.containsKey(galleryID)) cancel(galleryID) val cache = Cache.getInstance(this@DownloadService, galleryID) @@ -309,30 +307,18 @@ class DownloadService : Service() { // Gallery doesn't exist if (reader == null) { delete(galleryID) - progress.put(galleryID, null) + progress[galleryID] = mutableListOf() return@launch } - val list = MutableList(reader.galleryInfo.files.size) { 0F } + progress[galleryID] = MutableList(reader.galleryInfo.files.size) { 0F } cache.metadata.imageList?.let { - if (list.size != it.size) { - FirebaseCrashlytics.getInstance().log( - """ - GALLERYID: $galleryID - ${it.size} - ${list.size} - """.trimIndent() - ) - error("ImageList Size does not match") - } - it.forEachIndexed { index, image -> - list[index] = if (image != null) Float.POSITIVE_INFINITY else 0F + progress[galleryID]?.set(index, if (image != null) Float.POSITIVE_INFINITY else 0F) } } - progress.put(galleryID, list) - if (isCompleted(galleryID)) { if (DownloadManager.getInstance(this@DownloadService) .getDownloadFolder(galleryID) != null ) @@ -357,18 +343,8 @@ class DownloadService : Service() { } } - reader.requestBuilders.also { - if (it.size != list.size) { - FirebaseCrashlytics.getInstance().log( - """ - GALLERYID: $galleryID - ${it.size} - ${list.size} - """.trimIndent() - ) - error("Requests Size does not match") - } - }.forEachIndexed { index, it -> - if (!list[index].isInfinite()) { + reader.requestBuilders.forEachIndexed { index, it -> + if (progress[galleryID]?.get(index)?.isInfinite() == false) { val request = it.tag(Tag(galleryID, index, startId)).build() client.newCall(request).enqueue(callback) } 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 0a035d82..8a55ee02 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt @@ -621,7 +621,7 @@ class MainActivity : else -> { searchHistory.map { Suggestion(it) - }.takeLast(20) + FavoriteHistorySwitch(getString(R.string.search_show_tags)) + }.takeLast(10) + FavoriteHistorySwitch(getString(R.string.search_show_tags)) } }.reversed() 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 788f23c5..fb955a98 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt @@ -88,7 +88,10 @@ class ReaderActivity : BaseActivity() { var downloader: DownloadService? = null private val conn = object: ServiceConnection { override fun onServiceConnected(name: ComponentName?, service: IBinder?) { - downloader = (service as DownloadService.Binder).service + downloader = (service as DownloadService.Binder).service.also { + if (!it.progress.containsKey(galleryID)) + DownloadService.download(this@ReaderActivity, galleryID, true) + } } override fun onServiceDisconnected(name: ComponentName?) { @@ -166,7 +169,7 @@ class ReaderActivity : BaseActivity() { } } } else - initDownloader() + initDownloadListener() initView() } @@ -259,6 +262,9 @@ class ReaderActivity : BaseActivity() { if (downloader != null) unbindService(conn) + + if (!DownloadManager.getInstance(this).isDownloading(galleryID)) + DownloadService.cancel(this, galleryID) } override fun onDestroy() { @@ -266,9 +272,6 @@ class ReaderActivity : BaseActivity() { timer.cancel() (reader_recyclerview?.adapter as? ReaderAdapter)?.timer?.cancel() - - if (!DownloadManager.getInstance(this).isDownloading(galleryID)) - DownloadService.cancel(this, galleryID) } override fun onBackPressed() { @@ -303,16 +306,14 @@ class ReaderActivity : BaseActivity() { } } - private fun initDownloader() { - DownloadService.download(this, galleryID, true) - + private fun initDownloadListener() { timer.schedule(1000, 1000) { val downloader = downloader ?: return@schedule - if (downloader.progress.indexOfKey(galleryID) < 0) //loading + if (!downloader.progress.containsKey(galleryID)) //loading return@schedule - if (downloader.progress[galleryID] == null) { //Gallery not found + if (downloader.progress[galleryID]?.isEmpty() == true) { //Gallery not found timer.cancel() Snackbar .make(reader_layout, R.string.reader_failed_to_find_gallery, Snackbar.LENGTH_INDEFINITE) diff --git a/app/src/main/java/xyz/quaver/pupil/ui/dialog/DownloadFolderNameDialogFragment.kt b/app/src/main/java/xyz/quaver/pupil/ui/dialog/DownloadFolderNameDialogFragment.kt index 4f44348e..88a2c221 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/dialog/DownloadFolderNameDialogFragment.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/dialog/DownloadFolderNameDialogFragment.kt @@ -39,7 +39,7 @@ class DownloadFolderNameDialogFragment : DialogFragment() { @SuppressLint("InflateParams") private fun build(): View { - val galleryID = Cache.instances.let { if (it.size() == 0) 1199708 else it.keyAt((0 until it.size()).random()) } + val galleryID = Cache.instances.let { if (it.size == 0) 1199708 else it.keys.elementAt((0 until it.size).random()) } val galleryBlock = runBlocking { Cache.getInstance(requireContext(), galleryID).getGalleryBlock() } diff --git a/app/src/main/java/xyz/quaver/pupil/ui/view/TagChip.kt b/app/src/main/java/xyz/quaver/pupil/ui/view/TagChip.kt index 3dd05f8b..a482d898 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/view/TagChip.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/view/TagChip.kt @@ -45,23 +45,24 @@ class TagChip(context: Context, _tag: Tag) : Chip(context) { }.toMap() init { - chipIcon = when(tag.area) { + when(tag.area) { "male" -> { setChipBackgroundColorResource(R.color.material_blue_700) setTextColor(ContextCompat.getColor(context, android.R.color.white)) - ContextCompat.getDrawable(context, R.drawable.gender_male_white) + setCloseIconTintResource(android.R.color.white) + chipIcon = ContextCompat.getDrawable(context, R.drawable.gender_male_white) } "female" -> { setChipBackgroundColorResource(R.color.material_pink_600) setTextColor(ContextCompat.getColor(context, android.R.color.white)) - ContextCompat.getDrawable(context, R.drawable.gender_female_white) + setCloseIconTintResource(android.R.color.white) + chipIcon = ContextCompat.getDrawable(context, R.drawable.gender_female_white) } - else -> null - }.also { - if (favoriteTags.contains(tag)) - setChipBackgroundColorResource(R.color.material_orange_500) } + if (favoriteTags.contains(tag)) + setChipBackgroundColorResource(R.color.material_orange_500) + isCloseIconVisible = true closeIcon = ContextCompat.getDrawable(context, if (favoriteTags.contains(tag)) diff --git a/app/src/main/java/xyz/quaver/pupil/util/downloader/Cache.kt b/app/src/main/java/xyz/quaver/pupil/util/downloader/Cache.kt index 257a67d9..41dca009 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/downloader/Cache.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/downloader/Cache.kt @@ -20,7 +20,6 @@ package xyz.quaver.pupil.util.downloader import android.content.Context import android.content.ContextWrapper -import android.util.SparseArray import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -38,6 +37,7 @@ import xyz.quaver.io.util.* import xyz.quaver.pupil.client import xyz.quaver.pupil.util.Preferences import java.io.IOException +import java.util.concurrent.ConcurrentHashMap @Serializable data class Metadata( @@ -51,7 +51,7 @@ data class Metadata( class Cache private constructor(context: Context, val galleryID: Int) : ContextWrapper(context) { companion object { - val instances = SparseArray() + val instances = ConcurrentHashMap() fun getInstance(context: Context, galleryID: Int) = instances[galleryID] ?: synchronized(this) { @@ -61,7 +61,7 @@ class Cache private constructor(context: Context, val galleryID: Int) : ContextW @Synchronized fun delete(galleryID: Int) { instances[galleryID]?.cacheFolder?.deleteRecursively() - instances.delete(galleryID) + instances.remove(galleryID) } } 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 f269a326..0fd990df 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/update.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/update.kt @@ -160,7 +160,6 @@ fun checkUpdate(context: Context, force: Boolean = false) { val msg = extractReleaseNote(update, Locale.getDefault()) setMessage(Markwon.create(context).toMarkdown(msg)) setPositiveButton(android.R.string.ok) { _, _ -> - val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager //Cancel any download queued before