diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 00000000..d606a954
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 27356a0e..8a2bd452 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
*Pupil, Hitomi.la viewer for Android*

-[](https://github.com/tom5079/Pupil/releases/download/5.1.5/Pupil-v5.1.5-hotfix1.apk)
+[](https://github.com/tom5079/Pupil/releases/download/5.1.5-hotfix2/Pupil-v5.1.5-hotfix2.apk)
[](https://discord.gg/Stj4b5v)
# Features
diff --git a/app/build.gradle b/app/build.gradle
index b85c0462..79c232db 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -38,7 +38,7 @@ android {
minSdkVersion 16
targetSdkVersion 30
versionCode 63
- versionName "5.1.5-hotfix1"
+ versionName "5.1.5-hotfix2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
@@ -77,8 +77,8 @@ android {
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9"
- implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.0-RC2"
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.0-M1"
+ implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.0"
implementation "androidx.appcompat:appcompat:1.2.0"
implementation "androidx.activity:activity-ktx:1.2.0-beta01"
diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json
index 1000187d..b21cb189 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.5-hotfix1",
+ "versionName": "5.1.5-hotfix2",
"outputFile": "app-release.apk"
}
]
diff --git a/app/src/main/java/xyz/quaver/pupil/Pupil.kt b/app/src/main/java/xyz/quaver/pupil/Pupil.kt
index 314dc9fb..0faec406 100644
--- a/app/src/main/java/xyz/quaver/pupil/Pupil.kt
+++ b/app/src/main/java/xyz/quaver/pupil/Pupil.kt
@@ -18,7 +18,10 @@
package xyz.quaver.pupil
-import android.app.*
+import android.app.Application
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.net.Uri
diff --git a/app/src/main/java/xyz/quaver/pupil/ui/view/TagChipGroup.kt b/app/src/main/java/xyz/quaver/pupil/ui/view/TagChipGroup.kt
index c0004260..cb74eb77 100644
--- a/app/src/main/java/xyz/quaver/pupil/ui/view/TagChipGroup.kt
+++ b/app/src/main/java/xyz/quaver/pupil/ui/view/TagChipGroup.kt
@@ -24,10 +24,7 @@ import android.util.AttributeSet
import android.util.Log
import com.google.android.material.chip.Chip
import com.google.android.material.chip.ChipGroup
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.async
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.*
import xyz.quaver.pupil.R
import xyz.quaver.pupil.types.Tag
import xyz.quaver.pupil.types.Tags
@@ -71,10 +68,12 @@ class TagChipGroup @JvmOverloads constructor(context: Context, attr: AttributeSe
maxChipSize = attr.getInt(R.styleable.TagChipGroup_maxTag, Defaults.maxChipSize)
}
+ private var refreshJob: Job? = null
fun refresh() {
+ refreshJob?.cancel()
this.removeAllViews()
- CoroutineScope(Dispatchers.Main).launch {
+ refreshJob = CoroutineScope(Dispatchers.Main).launch {
tags.take(maxChipSize).map {
CoroutineScope(Dispatchers.Default).async {
TagChip(context, it).apply {
diff --git a/app/src/main/java/xyz/quaver/pupil/util/SavedSet.kt b/app/src/main/java/xyz/quaver/pupil/util/SavedSet.kt
index 24c71f2a..6e2c0987 100644
--- a/app/src/main/java/xyz/quaver/pupil/util/SavedSet.kt
+++ b/app/src/main/java/xyz/quaver/pupil/util/SavedSet.kt
@@ -24,7 +24,7 @@ import kotlinx.serialization.json.Json
import java.io.File
import java.util.*
-class SavedSet (private val file: File, private val any: T, private val set: MutableSet = Collections.synchronizedSet(mutableSetOf())) : MutableSet by set {
+class SavedSet (private val file: File, private val any: T, private val set: MutableSet = mutableSetOf()) : MutableSet by set {
@Suppress("UNCHECKED_CAST")
@OptIn(ExperimentalSerializationApi::class)
@@ -39,24 +39,23 @@ class SavedSet (private val file: File, private val any: T, private val
load()
}
+ @Synchronized
fun load() {
- synchronized(this) {
- set.clear()
- kotlin.runCatching {
- Json.decodeFromString(serializer, file.readText())
- }.onSuccess {
- set.addAll(it)
- }
+ set.clear()
+ kotlin.runCatching {
+ Json.decodeFromString(serializer, file.readText())
+ }.onSuccess {
+ set.addAll(it)
}
}
+ @Synchronized
@OptIn(ExperimentalSerializationApi::class)
fun save() {
- synchronized(this) {
- file.writeText(Json.encodeToString(serializer, set.toList()))
- }
+ file.writeText(Json.encodeToString(serializer, set.toList()))
}
+ @Synchronized
override fun add(element: T): Boolean {
load()
@@ -67,6 +66,7 @@ class SavedSet (private val file: File, private val any: T, private val
}
}
+ @Synchronized
override fun addAll(elements: Collection): Boolean {
load()
@@ -77,6 +77,7 @@ class SavedSet (private val file: File, private val any: T, private val
}
}
+ @Synchronized
override fun remove(element: T): Boolean {
load()
@@ -85,6 +86,7 @@ class SavedSet (private val file: File, private val any: T, private val
}
}
+ @Synchronized
override fun clear() {
set.clear()
save()
diff --git a/app/src/main/java/xyz/quaver/pupil/util/file.kt b/app/src/main/java/xyz/quaver/pupil/util/file.kt
index 159c0477..d889b3a1 100644
--- a/app/src/main/java/xyz/quaver/pupil/util/file.kt
+++ b/app/src/main/java/xyz/quaver/pupil/util/file.kt
@@ -55,10 +55,12 @@ fun cleanCache(context: Context) = CoroutineScope(Dispatchers.IO).launch {
while (cacheSize.invoke() > limit/2) {
val caches = cacheFolder.list() ?: return@withLock
- (histories.toList().firstOrNull {
- caches.contains(it.toString()) && !downloadManager.isDownloading(it)
- } ?: return@withLock).let {
- Cache.delete(context, it)
+ synchronized(histories) {
+ (histories.firstOrNull {
+ caches.contains(it.toString()) && !downloadManager.isDownloading(it)
+ } ?: return@withLock).let {
+ Cache.delete(context, it)
+ }
}
}
}
diff --git a/app/src/main/java/xyz/quaver/pupil/util/translation.kt b/app/src/main/java/xyz/quaver/pupil/util/translation.kt
index 7f68d607..18f8235e 100644
--- a/app/src/main/java/xyz/quaver/pupil/util/translation.kt
+++ b/app/src/main/java/xyz/quaver/pupil/util/translation.kt
@@ -42,11 +42,13 @@ var translations: Map = run {
@Suppress("BlockingMethodInNonBlockingContext")
fun updateTranslations() = CoroutineScope(Dispatchers.IO).launch {
translations = emptyMap()
- translations = Json.decodeFromString