From 9f41116241c7cbf568458d9aab026fcbf553d957 Mon Sep 17 00:00:00 2001 From: tom5079 Date: Mon, 22 Jun 2020 09:48:04 +0900 Subject: [PATCH 01/12] Auto-Retry Bug fix --- app/build.gradle | 4 +- .../quaver/pupil/ExampleInstrumentedTest.kt | 2 +- .../quaver/pupil/adapters/ReaderAdapter.kt | 39 ++------ .../java/xyz/quaver/pupil/ui/MainActivity.kt | 4 +- .../xyz/quaver/pupil/ui/ReaderActivity.kt | 9 +- .../xyz/quaver/pupil/util/download/Cache.kt | 13 ++- .../pupil/util/download/DownloadWorker.kt | 88 ++++--------------- app/src/main/res/values-ko/strings.xml | 2 +- app/src/main/res/values/strings.xml | 2 +- 9 files changed, 46 insertions(+), 117 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 5d545827..a5e7ece0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -19,8 +19,8 @@ android { applicationId "xyz.quaver.pupil" minSdkVersion 16 targetSdkVersion 29 - versionCode 54 - versionName "4.18.1" + versionCode 55 + versionName "4.18.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true vectorDrawables.useSupportLibrary = true diff --git a/app/src/androidTest/java/xyz/quaver/pupil/ExampleInstrumentedTest.kt b/app/src/androidTest/java/xyz/quaver/pupil/ExampleInstrumentedTest.kt index d747e481..b3661f2f 100644 --- a/app/src/androidTest/java/xyz/quaver/pupil/ExampleInstrumentedTest.kt +++ b/app/src/androidTest/java/xyz/quaver/pupil/ExampleInstrumentedTest.kt @@ -99,7 +99,7 @@ class ExampleInstrumentedTest { while(worker.progress.indexOfKey(galleryID) < 0 || worker.progress[galleryID] != null) { Log.i("PUPILD", worker.progress[galleryID]?.joinToString(" ") ?: "null") - if (worker.progress[galleryID]?.all { !it.isFinite() } == true) + if (worker.progress[galleryID]?.all { it.isInfinite() } == true) break } diff --git a/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt b/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt index a6505838..97157dda 100644 --- a/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt +++ b/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt @@ -18,6 +18,7 @@ package xyz.quaver.pupil.adapters +import android.app.Activity import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -28,9 +29,6 @@ import com.bumptech.glide.RequestManager import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.model.GlideUrl import com.bumptech.glide.load.model.LazyHeaders -import com.google.android.material.snackbar.Snackbar -import com.google.firebase.crashlytics.FirebaseCrashlytics -import kotlinx.android.synthetic.main.activity_reader.view.* import kotlinx.android.synthetic.main.item_reader.view.* import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -50,7 +48,8 @@ import kotlin.concurrent.schedule import kotlin.math.roundToInt class ReaderAdapter(private val glide: RequestManager, - private val galleryID: Int) : RecyclerView.Adapter() { + private val galleryID: Int, + private val activity: Activity) : RecyclerView.Adapter() { var reader: Reader? = null val timer = Timer() @@ -149,33 +148,13 @@ class ReaderAdapter(private val glide: RequestManager, glide.clear(holder.view.image) - if (progress?.isNaN() == true) { - FirebaseCrashlytics.getInstance().recordException( - DownloadWorker.getInstance(holder.view.context).exception[galleryID]?.get(position)!! - ) + holder.view.reader_item_progressbar.progress = + if (progress?.isInfinite() == true) + 100 + else + progress?.roundToInt() ?: 0 - glide - .load(R.drawable.image_broken_variant) - .into(holder.view.image) - - Snackbar.make(holder.view.reader_layout, R.string.reader_error_retry, Snackbar.LENGTH_SHORT).apply { - setAction(android.R.string.no) { } - setAction(android.R.string.yes) { - downloadWorker!!.cancel(galleryID) - downloadWorker!!.queue.add(galleryID) - } - }.show() - - return - } else { - holder.view.reader_item_progressbar.progress = - if (progress?.isInfinite() == true) - 100 - else - progress?.roundToInt() ?: 0 - - holder.view.image.setImageDrawable(null) - } + holder.view.image.setImageDrawable(null) timer.schedule(1000) { CoroutineScope(Dispatchers.Main).launch { 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 2a1aa3b0..4af3f620 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt @@ -440,8 +440,10 @@ class MainActivity : AppCompatActivity() { if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("cache_disable", false)) Toast.makeText(context, R.string.settings_download_when_cache_disable_warning, Toast.LENGTH_SHORT).show() else { - if (Cache(context).isDownloading(galleryID)) //download in progress + if (worker.progress.indexOfKey(galleryID) >= 0 && Cache(context).isDownloading(galleryID)) { //download in progress + Cache(context).setDownloading(galleryID, false) worker.cancel(galleryID) + } else { Cache(context).setDownloading(galleryID, true) 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 c4ce1917..f8c46611 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt @@ -264,6 +264,7 @@ class ReaderActivity : AppCompatActivity() { private fun initDownloader() { val worker = DownloadWorker.getInstance(this).apply { + cancel(galleryID) queue.add(galleryID) } @@ -280,7 +281,7 @@ class ReaderActivity : AppCompatActivity() { runOnUiThread { reader_download_progressbar.max = reader_recyclerview.adapter?.itemCount ?: 0 - reader_download_progressbar.progress = worker.progress[galleryID]?.count { !it.isFinite() } ?: 0 + reader_download_progressbar.progress = worker.progress[galleryID]?.count { it.isInfinite() } ?: 0 reader_progressbar.max = reader_recyclerview.adapter?.itemCount ?: 0 if (title == getString(R.string.reader_loading)) { @@ -305,7 +306,7 @@ class ReaderActivity : AppCompatActivity() { } } - if (worker.progress[galleryID]?.all { !it.isFinite() } == true) { //Download finished + if (worker.progress[galleryID]?.all { it.isInfinite() } == true) { //Download finished reader_download_progressbar.visibility = View.GONE animateDownloadFAB(false) @@ -316,7 +317,7 @@ class ReaderActivity : AppCompatActivity() { private fun initView() { with(reader_recyclerview) { - adapter = ReaderAdapter(Glide.with(this@ReaderActivity), galleryID).apply { + adapter = ReaderAdapter(Glide.with(this@ReaderActivity), galleryID, this@ReaderActivity).apply { onItemClickListener = { if (isScroll) { isScroll = false @@ -428,7 +429,7 @@ class ReaderActivity : AppCompatActivity() { icon?.registerAnimationCallback(object : Animatable2Compat.AnimationCallback() { override fun onAnimationEnd(drawable: Drawable?) { val worker = DownloadWorker.getInstance(context) - if (worker.progress[galleryID]?.all { !it.isFinite() } == true) // If download is finished, stop animating + if (worker.progress[galleryID]?.all { it.isInfinite() } == true) // If download is finished, stop animating post { setImageResource(R.drawable.ic_download) labelText = getString(R.string.reader_fab_download_cancel) 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 51389012..3b208f97 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 @@ -21,7 +21,6 @@ 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.google.firebase.crashlytics.FirebaseCrashlytics @@ -69,7 +68,7 @@ class Cache(context: Context) : ContextWrapper(context) { // Search in this order // Download -> Cache fun getCachedGallery(galleryID: Int) = getCachedGallery(this, galleryID).also { - if (!it.exists() && !preference.getBoolean("cache_disable", false)) + if (!it.exists()) it.mkdirs() } @@ -289,17 +288,17 @@ class Cache(context: Context) : ContextWrapper(context) { if (download.isParentOf(cache)) return@launch - Log.i("PUPILD", "MOVING ${cache.canonicalPath} --> ${download.canonicalPath}") + FirebaseCrashlytics.getInstance().log("MOVING ${cache.canonicalPath} --> ${download.canonicalPath}") cache.copyRecursively(download, true) { file, err -> - Log.i("PUPILD", "MOVING ERROR ${file.canonicalPath} ${err.message}") + FirebaseCrashlytics.getInstance().log("MOVING ERROR ${file.canonicalPath} ${err.message}") OnErrorAction.SKIP } - Log.i("PUPILD", "MOVED ${cache.canonicalPath}") + FirebaseCrashlytics.getInstance().log("MOVED ${cache.canonicalPath}") - Log.i("PUPILD", "DELETING ${cache.canonicalPath}") + FirebaseCrashlytics.getInstance().log("DELETING ${cache.canonicalPath}") cache.deleteRecursively() - Log.i("PUPILD", "DELETED ${cache.canonicalPath}") + FirebaseCrashlytics.getInstance().log("DELETED ${cache.canonicalPath}") } } 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 4ff09b62..63a9ca9c 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 @@ -128,21 +128,8 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont * SECONDARY VALUE * 0 <= value < 100 -> Download in progress * Float.POSITIVE_INFINITY -> Download completed - * Float.NaN -> Exception */ val progress = SparseArray?>() - /* - * KEY - * primary galleryID - * secondary index - * PRIMARY VALUE - * MutableList -> Download in progress / Loading - * null -> Gallery doesn't exist - * SECONDARY VALUE - * Throwable -> Exception - * null -> Download in progress / Loading - */ - val exception = SparseArray?>() val notification = SparseArray() private val loop = loop() @@ -194,7 +181,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont } progress.clear() - exception.clear() notification.clear() notificationManager.cancelAll() } @@ -210,15 +196,11 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont } progress.remove(galleryID) - exception.remove(galleryID) notification.remove(galleryID) notificationManager.cancel(galleryID) - - if (progress.indexOfKey(galleryID) >= 0) - Cache(this@DownloadWorker).setDownloading(galleryID, false) } - fun isCompleted(galleryID: Int) = progress[galleryID]?.all { !it.isFinite() } == true + fun isCompleted(galleryID: Int) = progress[galleryID]?.all { it.isInfinite() } == true private fun queueDownload(galleryID: Int, reader: Reader, index: Int, callback: Callback) { val lowQuality = preferences.getBoolean("low_quality", false) @@ -248,8 +230,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont }.build() client.newCall(request).enqueue(callback) - - Log.i("PUPILD", "DOWNLOADING ($galleryID, $index) from ${request.url()}") } private fun download(galleryID: Int) = CoroutineScope(Dispatchers.IO).launch { @@ -258,7 +238,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont //gallery doesn't exist if (reader == null) { progress.put(galleryID, null) - exception.put(galleryID, null) Cache(this@DownloadWorker).setDownloading(galleryID, false) return@launch @@ -272,7 +251,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont else 0F }.toMutableList()) - exception.put(galleryID, reader.galleryInfo.files.map { null }.toMutableList()) if (notification[galleryID] == null) initNotification(galleryID) @@ -294,30 +272,21 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont for (i in reader.galleryInfo.files.indices) { val callback = object : Callback { override fun onFailure(call: Call, e: IOException) { + if (e.message?.contains("cancel", true) != false) + return + Log.i("PUPILD", "FAIL ${call.request().tag()} (${e.message})") - if (e.message?.contains("cancel", true) != true) - FirebaseCrashlytics.getInstance().recordException(e) - - progress[galleryID]?.set(i, Float.NaN) - exception[galleryID]?.set(i, e) - - notify(galleryID) - - CoroutineScope(Dispatchers.IO).launch { - if (isCompleted(galleryID)) { - with(Cache(this@DownloadWorker)) { - if (isDownloading(galleryID)) { - moveToDownload(galleryID) - setDownloading(galleryID, false) - } - } - } + FirebaseCrashlytics.getInstance().apply { + log("FAIL ${call.request().tag()} (${e.message})") + setCustomKey("POS", "FAIL") + recordException(e) } + + cancel(galleryID) + queue.add(galleryID) } override fun onResponse(call: Call, response: Response) { - Log.i("PUPILD", "OK ${call.request().tag()}") - val ext = call.request().url().encodedPath().split('.').last() try { @@ -338,47 +307,28 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont } } } - - Log.i("PUPILD", "SUCCESS ${call.request().tag()}") } catch (e: Exception) { - - progress[galleryID]?.set(i, Float.NaN) - exception[galleryID]?.set(i, e) - - notify(galleryID) - - CoroutineScope(Dispatchers.IO).launch { - if (isCompleted(galleryID)) { - with(Cache(this@DownloadWorker)) { - if (isDownloading(galleryID)) { - moveToDownload(galleryID) - setDownloading(galleryID, false) - } - } - } + FirebaseCrashlytics.getInstance().apply { + setCustomKey("POS", "FAIL ON OK") + recordException(e) } File(Cache(this@DownloadWorker).getCachedGallery(galleryID), "%05d.$ext".format(i)).delete() - Log.i("PUPILD", "FAIL ON OK ${call.request().tag()} (${e.message})") + cancel(galleryID) + queue.add(galleryID) } } } - if (progress[galleryID]?.get(i)?.isFinite() == true) { + if (progress[galleryID]?.get(i)?.isFinite() == true) queueDownload(galleryID, reader, i, callback) - Log.i("PUPILD", "$galleryID QUEUED $i") - } else { - Log.i("PUPILD", "$galleryID SKIPPED $i (${progress[galleryID]?.get(i)})") - } } } private fun notify(galleryID: Int) { val max = progress[galleryID]?.size ?: 0 - val progress = progress[galleryID]?.count { !it.isFinite() } ?: 0 - - Log.i("PUPILD", "NOTIFY $galleryID ${isCompleted(galleryID)} $progress/$max") + val progress = progress[galleryID]?.count { it.isInfinite() } ?: 0 if (isCompleted(galleryID)) { notification[galleryID] @@ -434,8 +384,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont if (Cache(this@DownloadWorker).isDownloading(galleryID)) notificationManager.notify(galleryID, notification[galleryID].build()) - Log.i("PUPILD", "QUEUED $galleryID") - worker.put(galleryID, download(galleryID)) queue.poll() } diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index fb18e2a7..4c065d0b 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -148,6 +148,6 @@ 캐시를 활성화 해야 다운로드를 진행할 수 있습니다 유저 ID 유저 ID를 클립보드에 복사했습니다 - 다운로드 에러가 발생했습니다. 재시도 하시겠습니까? + 다운로드 에러가 발생했습니. 재시도 하시겠습니까? 재시도 \ 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 531e9997..f1765704 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -121,7 +121,7 @@ Download complete Download error - Download Error occurred. Retry? + Download Error. Retry? Help From d763f5dca08868c1d3b30b9504255f9b73b1cb53 Mon Sep 17 00:00:00 2001 From: tom5079 Date: Mon, 22 Jun 2020 09:52:25 +0900 Subject: [PATCH 02/12] App built --- app/release/output.json | 4 ++-- .../java/xyz/quaver/pupil/util/download/DownloadWorker.kt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/release/output.json b/app/release/output.json index 967b8923..b6d220aa 100644 --- a/app/release/output.json +++ b/app/release/output.json @@ -11,8 +11,8 @@ "type": "SINGLE", "filters": [], "properties": [], - "versionCode": 54, - "versionName": "54", + "versionCode": 55, + "versionName": "55", "enabled": true, "outputFile": "app-release.apk" } 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 63a9ca9c..d91cc987 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 @@ -309,6 +309,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont } } catch (e: Exception) { FirebaseCrashlytics.getInstance().apply { + log("FAIL ON OK ${call.request().tag()} (${e.message})") setCustomKey("POS", "FAIL ON OK") recordException(e) } From de7f552e5c2feb3166ede9d9ef17ae1862220ecf Mon Sep 17 00:00:00 2001 From: tom5079 Date: Tue, 23 Jun 2020 18:40:43 +0900 Subject: [PATCH 03/12] Pupil-95 Search tag icon not visible in light theme --- app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt | 6 +++++- app/src/main/res/drawable/account_group.xml | 2 +- app/src/main/res/drawable/account_star.xml | 2 +- app/src/main/res/drawable/book_open.xml | 2 +- app/src/main/res/drawable/brush.xml | 2 +- app/src/main/res/drawable/gender_female.xml | 2 +- app/src/main/res/drawable/gender_male.xml | 2 +- app/src/main/res/drawable/tag.xml | 2 +- app/src/main/res/drawable/translate.xml | 2 +- 9 files changed, 13 insertions(+), 9 deletions(-) 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 4af3f620..12b46b9b 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt @@ -26,6 +26,7 @@ import android.net.Uri import android.os.Bundle import android.text.* import android.text.style.AlignmentSpan +import android.util.TypedValue import android.view.KeyEvent import android.view.MotionEvent import android.view.View @@ -845,6 +846,9 @@ class MainActivity : AppCompatActivity() { val tag = "${item.n}:${item.s.replace(Regex("\\s"), "_")}" + val color = TypedValue() + theme.resolveAttribute(R.attr.colorControlNormal, color, true) + leftIcon.setImageDrawable( ResourcesCompat.getDrawable( resources, @@ -858,7 +862,7 @@ class MainActivity : AppCompatActivity() { "artist" -> R.drawable.brush else -> R.drawable.tag }, - null) + context.theme) ) with(suggestionView.findViewById(R.id.right_icon)) { diff --git a/app/src/main/res/drawable/account_group.xml b/app/src/main/res/drawable/account_group.xml index 9e5f4d81..595e7702 100644 --- a/app/src/main/res/drawable/account_group.xml +++ b/app/src/main/res/drawable/account_group.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/account_star.xml b/app/src/main/res/drawable/account_star.xml index dc8e4492..c445fc99 100644 --- a/app/src/main/res/drawable/account_star.xml +++ b/app/src/main/res/drawable/account_star.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/book_open.xml b/app/src/main/res/drawable/book_open.xml index 66c81594..5f3501e6 100644 --- a/app/src/main/res/drawable/book_open.xml +++ b/app/src/main/res/drawable/book_open.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/brush.xml b/app/src/main/res/drawable/brush.xml index 87b7c4c3..063d3a9c 100644 --- a/app/src/main/res/drawable/brush.xml +++ b/app/src/main/res/drawable/brush.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/gender_female.xml b/app/src/main/res/drawable/gender_female.xml index 6620153b..5a8e39f7 100644 --- a/app/src/main/res/drawable/gender_female.xml +++ b/app/src/main/res/drawable/gender_female.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/gender_male.xml b/app/src/main/res/drawable/gender_male.xml index eb3750bb..70a8d342 100644 --- a/app/src/main/res/drawable/gender_male.xml +++ b/app/src/main/res/drawable/gender_male.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/tag.xml b/app/src/main/res/drawable/tag.xml index 47689267..9fd5c9f0 100644 --- a/app/src/main/res/drawable/tag.xml +++ b/app/src/main/res/drawable/tag.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/translate.xml b/app/src/main/res/drawable/translate.xml index f357ae5f..ab8da74b 100644 --- a/app/src/main/res/drawable/translate.xml +++ b/app/src/main/res/drawable/translate.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file From 090ec0e4afa9b73ad03081bb911dd2ff0f184863 Mon Sep 17 00:00:00 2001 From: tom5079 Date: Mon, 22 Jun 2020 09:48:04 +0900 Subject: [PATCH 04/12] Auto-Retry Bug fix --- app/build.gradle | 4 +- .../quaver/pupil/ExampleInstrumentedTest.kt | 2 +- .../quaver/pupil/adapters/ReaderAdapter.kt | 39 ++------ .../java/xyz/quaver/pupil/ui/MainActivity.kt | 4 +- .../xyz/quaver/pupil/ui/ReaderActivity.kt | 9 +- .../xyz/quaver/pupil/util/download/Cache.kt | 13 ++- .../pupil/util/download/DownloadWorker.kt | 88 ++++--------------- app/src/main/res/values-ko/strings.xml | 2 +- app/src/main/res/values/strings.xml | 2 +- 9 files changed, 46 insertions(+), 117 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 5d545827..a5e7ece0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -19,8 +19,8 @@ android { applicationId "xyz.quaver.pupil" minSdkVersion 16 targetSdkVersion 29 - versionCode 54 - versionName "4.18.1" + versionCode 55 + versionName "4.18.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true vectorDrawables.useSupportLibrary = true diff --git a/app/src/androidTest/java/xyz/quaver/pupil/ExampleInstrumentedTest.kt b/app/src/androidTest/java/xyz/quaver/pupil/ExampleInstrumentedTest.kt index d747e481..b3661f2f 100644 --- a/app/src/androidTest/java/xyz/quaver/pupil/ExampleInstrumentedTest.kt +++ b/app/src/androidTest/java/xyz/quaver/pupil/ExampleInstrumentedTest.kt @@ -99,7 +99,7 @@ class ExampleInstrumentedTest { while(worker.progress.indexOfKey(galleryID) < 0 || worker.progress[galleryID] != null) { Log.i("PUPILD", worker.progress[galleryID]?.joinToString(" ") ?: "null") - if (worker.progress[galleryID]?.all { !it.isFinite() } == true) + if (worker.progress[galleryID]?.all { it.isInfinite() } == true) break } diff --git a/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt b/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt index a6505838..97157dda 100644 --- a/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt +++ b/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt @@ -18,6 +18,7 @@ package xyz.quaver.pupil.adapters +import android.app.Activity import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -28,9 +29,6 @@ import com.bumptech.glide.RequestManager import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.model.GlideUrl import com.bumptech.glide.load.model.LazyHeaders -import com.google.android.material.snackbar.Snackbar -import com.google.firebase.crashlytics.FirebaseCrashlytics -import kotlinx.android.synthetic.main.activity_reader.view.* import kotlinx.android.synthetic.main.item_reader.view.* import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -50,7 +48,8 @@ import kotlin.concurrent.schedule import kotlin.math.roundToInt class ReaderAdapter(private val glide: RequestManager, - private val galleryID: Int) : RecyclerView.Adapter() { + private val galleryID: Int, + private val activity: Activity) : RecyclerView.Adapter() { var reader: Reader? = null val timer = Timer() @@ -149,33 +148,13 @@ class ReaderAdapter(private val glide: RequestManager, glide.clear(holder.view.image) - if (progress?.isNaN() == true) { - FirebaseCrashlytics.getInstance().recordException( - DownloadWorker.getInstance(holder.view.context).exception[galleryID]?.get(position)!! - ) + holder.view.reader_item_progressbar.progress = + if (progress?.isInfinite() == true) + 100 + else + progress?.roundToInt() ?: 0 - glide - .load(R.drawable.image_broken_variant) - .into(holder.view.image) - - Snackbar.make(holder.view.reader_layout, R.string.reader_error_retry, Snackbar.LENGTH_SHORT).apply { - setAction(android.R.string.no) { } - setAction(android.R.string.yes) { - downloadWorker!!.cancel(galleryID) - downloadWorker!!.queue.add(galleryID) - } - }.show() - - return - } else { - holder.view.reader_item_progressbar.progress = - if (progress?.isInfinite() == true) - 100 - else - progress?.roundToInt() ?: 0 - - holder.view.image.setImageDrawable(null) - } + holder.view.image.setImageDrawable(null) timer.schedule(1000) { CoroutineScope(Dispatchers.Main).launch { 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 2a1aa3b0..4af3f620 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt @@ -440,8 +440,10 @@ class MainActivity : AppCompatActivity() { if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("cache_disable", false)) Toast.makeText(context, R.string.settings_download_when_cache_disable_warning, Toast.LENGTH_SHORT).show() else { - if (Cache(context).isDownloading(galleryID)) //download in progress + if (worker.progress.indexOfKey(galleryID) >= 0 && Cache(context).isDownloading(galleryID)) { //download in progress + Cache(context).setDownloading(galleryID, false) worker.cancel(galleryID) + } else { Cache(context).setDownloading(galleryID, true) 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 c4ce1917..f8c46611 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt @@ -264,6 +264,7 @@ class ReaderActivity : AppCompatActivity() { private fun initDownloader() { val worker = DownloadWorker.getInstance(this).apply { + cancel(galleryID) queue.add(galleryID) } @@ -280,7 +281,7 @@ class ReaderActivity : AppCompatActivity() { runOnUiThread { reader_download_progressbar.max = reader_recyclerview.adapter?.itemCount ?: 0 - reader_download_progressbar.progress = worker.progress[galleryID]?.count { !it.isFinite() } ?: 0 + reader_download_progressbar.progress = worker.progress[galleryID]?.count { it.isInfinite() } ?: 0 reader_progressbar.max = reader_recyclerview.adapter?.itemCount ?: 0 if (title == getString(R.string.reader_loading)) { @@ -305,7 +306,7 @@ class ReaderActivity : AppCompatActivity() { } } - if (worker.progress[galleryID]?.all { !it.isFinite() } == true) { //Download finished + if (worker.progress[galleryID]?.all { it.isInfinite() } == true) { //Download finished reader_download_progressbar.visibility = View.GONE animateDownloadFAB(false) @@ -316,7 +317,7 @@ class ReaderActivity : AppCompatActivity() { private fun initView() { with(reader_recyclerview) { - adapter = ReaderAdapter(Glide.with(this@ReaderActivity), galleryID).apply { + adapter = ReaderAdapter(Glide.with(this@ReaderActivity), galleryID, this@ReaderActivity).apply { onItemClickListener = { if (isScroll) { isScroll = false @@ -428,7 +429,7 @@ class ReaderActivity : AppCompatActivity() { icon?.registerAnimationCallback(object : Animatable2Compat.AnimationCallback() { override fun onAnimationEnd(drawable: Drawable?) { val worker = DownloadWorker.getInstance(context) - if (worker.progress[galleryID]?.all { !it.isFinite() } == true) // If download is finished, stop animating + if (worker.progress[galleryID]?.all { it.isInfinite() } == true) // If download is finished, stop animating post { setImageResource(R.drawable.ic_download) labelText = getString(R.string.reader_fab_download_cancel) 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 51389012..3b208f97 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 @@ -21,7 +21,6 @@ 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.google.firebase.crashlytics.FirebaseCrashlytics @@ -69,7 +68,7 @@ class Cache(context: Context) : ContextWrapper(context) { // Search in this order // Download -> Cache fun getCachedGallery(galleryID: Int) = getCachedGallery(this, galleryID).also { - if (!it.exists() && !preference.getBoolean("cache_disable", false)) + if (!it.exists()) it.mkdirs() } @@ -289,17 +288,17 @@ class Cache(context: Context) : ContextWrapper(context) { if (download.isParentOf(cache)) return@launch - Log.i("PUPILD", "MOVING ${cache.canonicalPath} --> ${download.canonicalPath}") + FirebaseCrashlytics.getInstance().log("MOVING ${cache.canonicalPath} --> ${download.canonicalPath}") cache.copyRecursively(download, true) { file, err -> - Log.i("PUPILD", "MOVING ERROR ${file.canonicalPath} ${err.message}") + FirebaseCrashlytics.getInstance().log("MOVING ERROR ${file.canonicalPath} ${err.message}") OnErrorAction.SKIP } - Log.i("PUPILD", "MOVED ${cache.canonicalPath}") + FirebaseCrashlytics.getInstance().log("MOVED ${cache.canonicalPath}") - Log.i("PUPILD", "DELETING ${cache.canonicalPath}") + FirebaseCrashlytics.getInstance().log("DELETING ${cache.canonicalPath}") cache.deleteRecursively() - Log.i("PUPILD", "DELETED ${cache.canonicalPath}") + FirebaseCrashlytics.getInstance().log("DELETED ${cache.canonicalPath}") } } 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 4ff09b62..63a9ca9c 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 @@ -128,21 +128,8 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont * SECONDARY VALUE * 0 <= value < 100 -> Download in progress * Float.POSITIVE_INFINITY -> Download completed - * Float.NaN -> Exception */ val progress = SparseArray?>() - /* - * KEY - * primary galleryID - * secondary index - * PRIMARY VALUE - * MutableList -> Download in progress / Loading - * null -> Gallery doesn't exist - * SECONDARY VALUE - * Throwable -> Exception - * null -> Download in progress / Loading - */ - val exception = SparseArray?>() val notification = SparseArray() private val loop = loop() @@ -194,7 +181,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont } progress.clear() - exception.clear() notification.clear() notificationManager.cancelAll() } @@ -210,15 +196,11 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont } progress.remove(galleryID) - exception.remove(galleryID) notification.remove(galleryID) notificationManager.cancel(galleryID) - - if (progress.indexOfKey(galleryID) >= 0) - Cache(this@DownloadWorker).setDownloading(galleryID, false) } - fun isCompleted(galleryID: Int) = progress[galleryID]?.all { !it.isFinite() } == true + fun isCompleted(galleryID: Int) = progress[galleryID]?.all { it.isInfinite() } == true private fun queueDownload(galleryID: Int, reader: Reader, index: Int, callback: Callback) { val lowQuality = preferences.getBoolean("low_quality", false) @@ -248,8 +230,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont }.build() client.newCall(request).enqueue(callback) - - Log.i("PUPILD", "DOWNLOADING ($galleryID, $index) from ${request.url()}") } private fun download(galleryID: Int) = CoroutineScope(Dispatchers.IO).launch { @@ -258,7 +238,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont //gallery doesn't exist if (reader == null) { progress.put(galleryID, null) - exception.put(galleryID, null) Cache(this@DownloadWorker).setDownloading(galleryID, false) return@launch @@ -272,7 +251,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont else 0F }.toMutableList()) - exception.put(galleryID, reader.galleryInfo.files.map { null }.toMutableList()) if (notification[galleryID] == null) initNotification(galleryID) @@ -294,30 +272,21 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont for (i in reader.galleryInfo.files.indices) { val callback = object : Callback { override fun onFailure(call: Call, e: IOException) { + if (e.message?.contains("cancel", true) != false) + return + Log.i("PUPILD", "FAIL ${call.request().tag()} (${e.message})") - if (e.message?.contains("cancel", true) != true) - FirebaseCrashlytics.getInstance().recordException(e) - - progress[galleryID]?.set(i, Float.NaN) - exception[galleryID]?.set(i, e) - - notify(galleryID) - - CoroutineScope(Dispatchers.IO).launch { - if (isCompleted(galleryID)) { - with(Cache(this@DownloadWorker)) { - if (isDownloading(galleryID)) { - moveToDownload(galleryID) - setDownloading(galleryID, false) - } - } - } + FirebaseCrashlytics.getInstance().apply { + log("FAIL ${call.request().tag()} (${e.message})") + setCustomKey("POS", "FAIL") + recordException(e) } + + cancel(galleryID) + queue.add(galleryID) } override fun onResponse(call: Call, response: Response) { - Log.i("PUPILD", "OK ${call.request().tag()}") - val ext = call.request().url().encodedPath().split('.').last() try { @@ -338,47 +307,28 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont } } } - - Log.i("PUPILD", "SUCCESS ${call.request().tag()}") } catch (e: Exception) { - - progress[galleryID]?.set(i, Float.NaN) - exception[galleryID]?.set(i, e) - - notify(galleryID) - - CoroutineScope(Dispatchers.IO).launch { - if (isCompleted(galleryID)) { - with(Cache(this@DownloadWorker)) { - if (isDownloading(galleryID)) { - moveToDownload(galleryID) - setDownloading(galleryID, false) - } - } - } + FirebaseCrashlytics.getInstance().apply { + setCustomKey("POS", "FAIL ON OK") + recordException(e) } File(Cache(this@DownloadWorker).getCachedGallery(galleryID), "%05d.$ext".format(i)).delete() - Log.i("PUPILD", "FAIL ON OK ${call.request().tag()} (${e.message})") + cancel(galleryID) + queue.add(galleryID) } } } - if (progress[galleryID]?.get(i)?.isFinite() == true) { + if (progress[galleryID]?.get(i)?.isFinite() == true) queueDownload(galleryID, reader, i, callback) - Log.i("PUPILD", "$galleryID QUEUED $i") - } else { - Log.i("PUPILD", "$galleryID SKIPPED $i (${progress[galleryID]?.get(i)})") - } } } private fun notify(galleryID: Int) { val max = progress[galleryID]?.size ?: 0 - val progress = progress[galleryID]?.count { !it.isFinite() } ?: 0 - - Log.i("PUPILD", "NOTIFY $galleryID ${isCompleted(galleryID)} $progress/$max") + val progress = progress[galleryID]?.count { it.isInfinite() } ?: 0 if (isCompleted(galleryID)) { notification[galleryID] @@ -434,8 +384,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont if (Cache(this@DownloadWorker).isDownloading(galleryID)) notificationManager.notify(galleryID, notification[galleryID].build()) - Log.i("PUPILD", "QUEUED $galleryID") - worker.put(galleryID, download(galleryID)) queue.poll() } diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index fb18e2a7..4c065d0b 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -148,6 +148,6 @@ 캐시를 활성화 해야 다운로드를 진행할 수 있습니다 유저 ID 유저 ID를 클립보드에 복사했습니다 - 다운로드 에러가 발생했습니다. 재시도 하시겠습니까? + 다운로드 에러가 발생했습니. 재시도 하시겠습니까? 재시도 \ 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 531e9997..f1765704 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -121,7 +121,7 @@ Download complete Download error - Download Error occurred. Retry? + Download Error. Retry? Help From 2367a97a542128bc540cb6a0d3d941dcdde59609 Mon Sep 17 00:00:00 2001 From: tom5079 Date: Mon, 22 Jun 2020 09:52:25 +0900 Subject: [PATCH 05/12] App built --- app/release/output.json | 4 ++-- .../java/xyz/quaver/pupil/util/download/DownloadWorker.kt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/release/output.json b/app/release/output.json index 967b8923..b6d220aa 100644 --- a/app/release/output.json +++ b/app/release/output.json @@ -11,8 +11,8 @@ "type": "SINGLE", "filters": [], "properties": [], - "versionCode": 54, - "versionName": "54", + "versionCode": 55, + "versionName": "55", "enabled": true, "outputFile": "app-release.apk" } 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 63a9ca9c..d91cc987 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 @@ -309,6 +309,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont } } catch (e: Exception) { FirebaseCrashlytics.getInstance().apply { + log("FAIL ON OK ${call.request().tag()} (${e.message})") setCustomKey("POS", "FAIL ON OK") recordException(e) } From adda8ab6406b8407c9bfb4bfc0cc61bf30af04cb Mon Sep 17 00:00:00 2001 From: tom5079 Date: Tue, 23 Jun 2020 18:40:43 +0900 Subject: [PATCH 06/12] Pupil-95 Search tag icon not visible in light theme --- app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt | 6 +++++- app/src/main/res/drawable/account_group.xml | 2 +- app/src/main/res/drawable/account_star.xml | 2 +- app/src/main/res/drawable/book_open.xml | 2 +- app/src/main/res/drawable/brush.xml | 2 +- app/src/main/res/drawable/gender_female.xml | 2 +- app/src/main/res/drawable/gender_male.xml | 2 +- app/src/main/res/drawable/tag.xml | 2 +- app/src/main/res/drawable/translate.xml | 2 +- 9 files changed, 13 insertions(+), 9 deletions(-) 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 4af3f620..12b46b9b 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt @@ -26,6 +26,7 @@ import android.net.Uri import android.os.Bundle import android.text.* import android.text.style.AlignmentSpan +import android.util.TypedValue import android.view.KeyEvent import android.view.MotionEvent import android.view.View @@ -845,6 +846,9 @@ class MainActivity : AppCompatActivity() { val tag = "${item.n}:${item.s.replace(Regex("\\s"), "_")}" + val color = TypedValue() + theme.resolveAttribute(R.attr.colorControlNormal, color, true) + leftIcon.setImageDrawable( ResourcesCompat.getDrawable( resources, @@ -858,7 +862,7 @@ class MainActivity : AppCompatActivity() { "artist" -> R.drawable.brush else -> R.drawable.tag }, - null) + context.theme) ) with(suggestionView.findViewById(R.id.right_icon)) { diff --git a/app/src/main/res/drawable/account_group.xml b/app/src/main/res/drawable/account_group.xml index 9e5f4d81..595e7702 100644 --- a/app/src/main/res/drawable/account_group.xml +++ b/app/src/main/res/drawable/account_group.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/account_star.xml b/app/src/main/res/drawable/account_star.xml index dc8e4492..c445fc99 100644 --- a/app/src/main/res/drawable/account_star.xml +++ b/app/src/main/res/drawable/account_star.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/book_open.xml b/app/src/main/res/drawable/book_open.xml index 66c81594..5f3501e6 100644 --- a/app/src/main/res/drawable/book_open.xml +++ b/app/src/main/res/drawable/book_open.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/brush.xml b/app/src/main/res/drawable/brush.xml index 87b7c4c3..063d3a9c 100644 --- a/app/src/main/res/drawable/brush.xml +++ b/app/src/main/res/drawable/brush.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/gender_female.xml b/app/src/main/res/drawable/gender_female.xml index 6620153b..5a8e39f7 100644 --- a/app/src/main/res/drawable/gender_female.xml +++ b/app/src/main/res/drawable/gender_female.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/gender_male.xml b/app/src/main/res/drawable/gender_male.xml index eb3750bb..70a8d342 100644 --- a/app/src/main/res/drawable/gender_male.xml +++ b/app/src/main/res/drawable/gender_male.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/tag.xml b/app/src/main/res/drawable/tag.xml index 47689267..9fd5c9f0 100644 --- a/app/src/main/res/drawable/tag.xml +++ b/app/src/main/res/drawable/tag.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/translate.xml b/app/src/main/res/drawable/translate.xml index f357ae5f..ab8da74b 100644 --- a/app/src/main/res/drawable/translate.xml +++ b/app/src/main/res/drawable/translate.xml @@ -4,5 +4,5 @@ android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + \ No newline at end of file From a8766a8bbe4b15022064e307b0c7ca8299d2d016 Mon Sep 17 00:00:00 2001 From: tom5079 Date: Tue, 23 Jun 2020 20:37:20 +0900 Subject: [PATCH 07/12] Drawer logo fixed --- app/src/main/res/drawable/side_nav_bar.png | Bin 18250 -> 68495 bytes app/src/main/res/layout/nav_header_main.xml | 5 +++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/drawable/side_nav_bar.png b/app/src/main/res/drawable/side_nav_bar.png index a399a2d5da3c41eaae16a68f73909a02938b91a5..727e1e9632ba3a8db52859628e68b39b6e87cf23 100644 GIT binary patch literal 68495 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 UXtEsx8G$cN%z5>K->n1w56IyP@&Et; literal 18250 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 Date: Sun, 5 Jul 2020 19:33:56 +0900 Subject: [PATCH 08/12] Version Update --- app/build.gradle | 4 ++-- app/src/main/res/layout/nav_header_main.xml | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index a5e7ece0..84e2251a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -19,8 +19,8 @@ android { applicationId "xyz.quaver.pupil" minSdkVersion 16 targetSdkVersion 29 - versionCode 55 - versionName "4.18.2" + versionCode 56 + versionName "4.19" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true vectorDrawables.useSupportLibrary = true diff --git a/app/src/main/res/layout/nav_header_main.xml b/app/src/main/res/layout/nav_header_main.xml index cf20425c..a413c18b 100644 --- a/app/src/main/res/layout/nav_header_main.xml +++ b/app/src/main/res/layout/nav_header_main.xml @@ -19,6 +19,7 @@ \ No newline at end of file + android:gravity="bottom" + tools:ignore="ContentDescription" /> \ No newline at end of file From 70608c3ed914ab2f71759191a0e952357ab0fab0 Mon Sep 17 00:00:00 2001 From: tom5079 Date: Sun, 5 Jul 2020 19:40:14 +0900 Subject: [PATCH 09/12] resolves #52 --- app/src/main/java/xyz/quaver/pupil/util/history.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/src/main/java/xyz/quaver/pupil/util/history.kt b/app/src/main/java/xyz/quaver/pupil/util/history.kt index cc80275e..b39f3507 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/history.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/history.kt @@ -67,6 +67,20 @@ class Histories(private val file: File) : ArrayList() { return true } + override fun addAll(elements: Collection): Boolean { + load() + + for (e in elements) { + if (contains(e)) + super.remove(e) + super.add(0, e) + } + + save() + + return true + } + override fun remove(element: Int): Boolean { load() val retval = super.remove(element) From 24b801b346bc649980df4ec1389bc9a6b98db7f0 Mon Sep 17 00:00:00 2001 From: tom5079 Date: Sun, 5 Jul 2020 19:45:55 +0900 Subject: [PATCH 10/12] resolves #52 --- app/src/main/java/xyz/quaver/pupil/util/history.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/xyz/quaver/pupil/util/history.kt b/app/src/main/java/xyz/quaver/pupil/util/history.kt index b39f3507..d50a970d 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/history.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/history.kt @@ -41,7 +41,7 @@ class Histories(private val file: File) : ArrayList() { fun load() : Histories { return apply { super.clear() - addAll( + super.addAll( json.parse( serializer, file.bufferedReader().use { it.readText() } From 47c9e8127e408b90dc79238ac3cb37efb8804453 Mon Sep 17 00:00:00 2001 From: tom5079 Date: Tue, 7 Jul 2020 10:21:30 +0900 Subject: [PATCH 11/12] Remove logic for resetting low quality setting --- app/src/main/java/xyz/quaver/pupil/Pupil.kt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/src/main/java/xyz/quaver/pupil/Pupil.kt b/app/src/main/java/xyz/quaver/pupil/Pupil.kt index 1a723eec..980903bd 100644 --- a/app/src/main/java/xyz/quaver/pupil/Pupil.kt +++ b/app/src/main/java/xyz/quaver/pupil/Pupil.kt @@ -71,13 +71,6 @@ class Pupil : MultiDexApplication() { preference.edit().remove("dl_location").apply() } - if (!preference.getBoolean("low_quality_reset", false)) { - preference.edit() - .putBoolean("low_quality", true) - .putBoolean("low_quality_reset", true) - .apply() - } - histories = Histories(File(ContextCompat.getDataDir(this), "histories.json")) favorites = Histories(File(ContextCompat.getDataDir(this), "favorites.json")) From 431e56a9f1ba1f9c14dcb91d276c87855807a9cc Mon Sep 17 00:00:00 2001 From: tom5079 Date: Sun, 12 Jul 2020 20:07:59 +0900 Subject: [PATCH 12/12] Version 4.18.3 --- app/build.gradle | 8 ++++---- app/release/output.json | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 84e2251a..b34e1029 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,7 +20,7 @@ android { minSdkVersion 16 targetSdkVersion 29 versionCode 56 - versionName "4.19" + versionName "4.18.3" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true vectorDrawables.useSupportLibrary = true @@ -65,9 +65,9 @@ dependencies { implementation 'androidx.multidex:multidex:2.0.1' implementation "com.daimajia.swipelayout:library:1.2.0@aar" implementation 'com.google.android.material:material:1.3.0-alpha01' - implementation 'com.google.firebase:firebase-core:17.4.3' - implementation 'com.google.firebase:firebase-analytics:17.4.3' - implementation 'com.google.firebase:firebase-crashlytics:17.1.0' + implementation 'com.google.firebase:firebase-core:17.4.4' + implementation 'com.google.firebase:firebase-analytics:17.4.4' + implementation 'com.google.firebase:firebase-crashlytics:17.1.1' implementation 'com.google.firebase:firebase-perf:19.0.7' implementation 'com.github.arimorty:floatingsearchview:2.1.1' implementation 'com.github.clans:fab:1.6.4' diff --git a/app/release/output.json b/app/release/output.json index b6d220aa..c2663150 100644 --- a/app/release/output.json +++ b/app/release/output.json @@ -11,8 +11,8 @@ "type": "SINGLE", "filters": [], "properties": [], - "versionCode": 55, - "versionName": "55", + "versionCode": 56, + "versionName": "56", "enabled": true, "outputFile": "app-release.apk" }