Concurrency issue fixed
Don't cancel download onPause Limit folder length to 127 characters
This commit is contained in:
@@ -37,7 +37,7 @@ android {
|
|||||||
applicationId "xyz.quaver.pupil"
|
applicationId "xyz.quaver.pupil"
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode 61
|
versionCode 62
|
||||||
versionName "5.1.3"
|
versionName "5.1.3"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
@@ -51,7 +51,6 @@ android {
|
|||||||
applicationIdSuffix ".debug"
|
applicationIdSuffix ".debug"
|
||||||
versionNameSuffix "-DEBUG"
|
versionNameSuffix "-DEBUG"
|
||||||
|
|
||||||
buildConfigField("Boolean", "CENSOR", "false")
|
|
||||||
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
|
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
|
||||||
|
|
||||||
ext.enableCrashlytics = false
|
ext.enableCrashlytics = false
|
||||||
@@ -61,7 +60,6 @@ android {
|
|||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
shrinkResources true
|
shrinkResources true
|
||||||
|
|
||||||
buildConfigField("Boolean", "CENSOR", "false")
|
|
||||||
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
|
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,7 +77,6 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
|
implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
|
||||||
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-coroutines-android:1.3.9"
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.0-RC2"
|
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.0-RC2"
|
||||||
|
|
||||||
|
|||||||
18
app/proguard-rules.pro
vendored
18
app/proguard-rules.pro
vendored
@@ -22,21 +22,6 @@
|
|||||||
|
|
||||||
-dontobfuscate
|
-dontobfuscate
|
||||||
|
|
||||||
-keep public class * implements com.bumptech.glide.module.GlideModule
|
|
||||||
-keep class * extends com.bumptech.glide.module.AppGlideModule {
|
|
||||||
<init>(...);
|
|
||||||
}
|
|
||||||
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
|
||||||
**[] $VALUES;
|
|
||||||
public *;
|
|
||||||
}
|
|
||||||
-keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder {
|
|
||||||
*** rewind();
|
|
||||||
}
|
|
||||||
|
|
||||||
-keep public class * extends com.bumptech.glide.module.AppGlideModule
|
|
||||||
-keep class com.bumptech.glide.GeneratedAppGlideModuleImpl
|
|
||||||
|
|
||||||
-keepattributes *Annotation*, InnerClasses
|
-keepattributes *Annotation*, InnerClasses
|
||||||
-dontnote kotlinx.serialization.SerializationKt
|
-dontnote kotlinx.serialization.SerializationKt
|
||||||
-keep,includedescriptorclasses class xyz.quaver.**$$serializer { *; } # <-- change package name to your app's
|
-keep,includedescriptorclasses class xyz.quaver.**$$serializer { *; } # <-- change package name to your app's
|
||||||
@@ -47,5 +32,4 @@
|
|||||||
kotlinx.serialization.KSerializer serializer(...);
|
kotlinx.serialization.KSerializer serializer(...);
|
||||||
}
|
}
|
||||||
-keep class xyz.quaver.pupil.ui.fragment.ManageFavoritesFragment
|
-keep class xyz.quaver.pupil.ui.fragment.ManageFavoritesFragment
|
||||||
-keep class xyz.quaver.pupil.ui.fragment.ManageStorageFragment
|
-keep class xyz.quaver.pupil.ui.fragment.ManageStorageFragment
|
||||||
-keep class xyz.quaver.pupil.util.Preferences
|
|
||||||
@@ -11,8 +11,8 @@
|
|||||||
"type": "SINGLE",
|
"type": "SINGLE",
|
||||||
"filters": [],
|
"filters": [],
|
||||||
"properties": [],
|
"properties": [],
|
||||||
"versionCode": 61,
|
"versionCode": 62,
|
||||||
"versionName": "5.1.2-hotfix3",
|
"versionName": "5.1.3",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"outputFile": "app-release.apk"
|
"outputFile": "app-release.apk"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import androidx.core.app.NotificationCompat
|
|||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import androidx.core.app.TaskStackBuilder
|
import androidx.core.app.TaskStackBuilder
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
@@ -46,6 +45,7 @@ import xyz.quaver.pupil.util.ellipsize
|
|||||||
import xyz.quaver.pupil.util.normalizeID
|
import xyz.quaver.pupil.util.normalizeID
|
||||||
import xyz.quaver.pupil.util.requestBuilders
|
import xyz.quaver.pupil.util.requestBuilders
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import java.util.*
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
import kotlin.math.log10
|
import kotlin.math.log10
|
||||||
@@ -88,7 +88,7 @@ class DownloadService : Service() {
|
|||||||
PendingIntent.FLAG_UPDATE_CURRENT),
|
PendingIntent.FLAG_UPDATE_CURRENT),
|
||||||
).build()
|
).build()
|
||||||
|
|
||||||
notification.put(galleryID, NotificationCompat.Builder(this, "download").apply {
|
notification[galleryID] = NotificationCompat.Builder(this, "download").apply {
|
||||||
setContentTitle(getString(R.string.reader_loading))
|
setContentTitle(getString(R.string.reader_loading))
|
||||||
setContentText(getString(R.string.reader_notification_text))
|
setContentText(getString(R.string.reader_notification_text))
|
||||||
setSmallIcon(R.drawable.ic_notification)
|
setSmallIcon(R.drawable.ic_notification)
|
||||||
@@ -96,7 +96,7 @@ class DownloadService : Service() {
|
|||||||
addAction(action)
|
addAction(action)
|
||||||
setProgress(0, 0, true)
|
setProgress(0, 0, true)
|
||||||
setOngoing(true)
|
setOngoing(true)
|
||||||
})
|
}
|
||||||
|
|
||||||
notify(galleryID)
|
notify(galleryID)
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,7 @@ class DownloadService : Service() {
|
|||||||
.setProgress(max, progress, false)
|
.setProgress(max, progress, false)
|
||||||
.setContentText("$progress/$max")
|
.setContentText("$progress/$max")
|
||||||
|
|
||||||
if (DownloadManager.getInstance(this).getDownloadFolder(galleryID) != null)
|
if (DownloadManager.getInstance(this).getDownloadFolder(galleryID) != null || galleryID == priority)
|
||||||
notification.let { notificationManager.notify(galleryID, it.build()) }
|
notification.let { notificationManager.notify(galleryID, it.build()) }
|
||||||
else
|
else
|
||||||
notificationManager.cancel(galleryID)
|
notificationManager.cancel(galleryID)
|
||||||
@@ -196,6 +196,7 @@ class DownloadService : Service() {
|
|||||||
* Float.POSITIVE_INFINITY -> Download completed
|
* Float.POSITIVE_INFINITY -> Download completed
|
||||||
*/
|
*/
|
||||||
val progress = ConcurrentHashMap<Int, MutableList<Float>>()
|
val progress = ConcurrentHashMap<Int, MutableList<Float>>()
|
||||||
|
var priority = 0
|
||||||
|
|
||||||
fun isCompleted(galleryID: Int) = progress[galleryID]?.toList()?.all { it == Float.POSITIVE_INFINITY } == true
|
fun isCompleted(galleryID: Int) = progress[galleryID]?.toList()?.all { it == Float.POSITIVE_INFINITY } == true
|
||||||
|
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ class MainActivity :
|
|||||||
if (v !is CardView)
|
if (v !is CardView)
|
||||||
return@listener false
|
return@listener false
|
||||||
|
|
||||||
val galleryID = galleries[position]
|
val galleryID = galleries.getOrNull(position) ?: return@listener true
|
||||||
|
|
||||||
GalleryDialog(this@MainActivity, galleryID).apply {
|
GalleryDialog(this@MainActivity, galleryID).apply {
|
||||||
onChipClickedHandler.add {
|
onChipClickedHandler.add {
|
||||||
|
|||||||
@@ -33,11 +33,9 @@ import android.view.animation.Animation
|
|||||||
import android.view.animation.AnticipateInterpolator
|
import android.view.animation.AnticipateInterpolator
|
||||||
import android.view.animation.OvershootInterpolator
|
import android.view.animation.OvershootInterpolator
|
||||||
import android.view.animation.TranslateAnimation
|
import android.view.animation.TranslateAnimation
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.preference.PreferenceManager
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.PagerSnapHelper
|
import androidx.recyclerview.widget.PagerSnapHelper
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
@@ -59,7 +57,6 @@ import xyz.quaver.Code
|
|||||||
import xyz.quaver.pupil.R
|
import xyz.quaver.pupil.R
|
||||||
import xyz.quaver.pupil.adapters.ReaderAdapter
|
import xyz.quaver.pupil.adapters.ReaderAdapter
|
||||||
import xyz.quaver.pupil.favorites
|
import xyz.quaver.pupil.favorites
|
||||||
import xyz.quaver.pupil.histories
|
|
||||||
import xyz.quaver.pupil.services.DownloadService
|
import xyz.quaver.pupil.services.DownloadService
|
||||||
import xyz.quaver.pupil.util.Preferences
|
import xyz.quaver.pupil.util.Preferences
|
||||||
import xyz.quaver.pupil.util.camera
|
import xyz.quaver.pupil.util.camera
|
||||||
@@ -67,8 +64,6 @@ import xyz.quaver.pupil.util.closeCamera
|
|||||||
import xyz.quaver.pupil.util.downloader.Cache
|
import xyz.quaver.pupil.util.downloader.Cache
|
||||||
import xyz.quaver.pupil.util.downloader.DownloadManager
|
import xyz.quaver.pupil.util.downloader.DownloadManager
|
||||||
import xyz.quaver.pupil.util.startCamera
|
import xyz.quaver.pupil.util.startCamera
|
||||||
import java.util.*
|
|
||||||
import kotlin.concurrent.schedule
|
|
||||||
|
|
||||||
class ReaderActivity : BaseActivity() {
|
class ReaderActivity : BaseActivity() {
|
||||||
|
|
||||||
@@ -88,6 +83,8 @@ class ReaderActivity : BaseActivity() {
|
|||||||
private val conn = object: ServiceConnection {
|
private val conn = object: ServiceConnection {
|
||||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
||||||
downloader = (service as DownloadService.Binder).service.also {
|
downloader = (service as DownloadService.Binder).service.also {
|
||||||
|
it.priority = 0
|
||||||
|
|
||||||
if (!it.progress.containsKey(galleryID))
|
if (!it.progress.containsKey(galleryID))
|
||||||
DownloadService.download(this@ReaderActivity, galleryID, true)
|
DownloadService.download(this@ReaderActivity, galleryID, true)
|
||||||
}
|
}
|
||||||
@@ -230,14 +227,16 @@ class ReaderActivity : BaseActivity() {
|
|||||||
if (downloader != null)
|
if (downloader != null)
|
||||||
unbindService(conn)
|
unbindService(conn)
|
||||||
|
|
||||||
if (!DownloadManager.getInstance(this).isDownloading(galleryID))
|
downloader?.priority = galleryID
|
||||||
DownloadService.cancel(this, galleryID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
|
|
||||||
update = false
|
update = false
|
||||||
|
|
||||||
|
if (!DownloadManager.getInstance(this).isDownloading(galleryID))
|
||||||
|
DownloadService.cancel(this, galleryID)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ import kotlinx.serialization.*
|
|||||||
import kotlinx.serialization.builtins.ListSerializer
|
import kotlinx.serialization.builtins.ListSerializer
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class SavedSet <T: Any> (private val file: File, private val any: T, private val set: MutableSet<T> = mutableSetOf()) : MutableSet<T> by set {
|
class SavedSet <T: Any> (private val file: File, private val any: T, private val set: MutableSet<T> = Collections.synchronizedSet(mutableSetOf())) : MutableSet<T> by set {
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
@OptIn(ExperimentalSerializationApi::class)
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
|
|||||||
@@ -93,14 +93,14 @@ fun GalleryBlock.formatDownloadFolder(): String =
|
|||||||
formatMap.entries.fold(it) { str, (k, v) ->
|
formatMap.entries.fold(it) { str, (k, v) ->
|
||||||
str.replace(k, v.invoke(this), true)
|
str.replace(k, v.invoke(this), true)
|
||||||
}
|
}
|
||||||
}.replace(Regex("""[*\\|"?><:/]"""), "")
|
}.replace(Regex("""[*\\|"?><:/]"""), "").ellipsize(127)
|
||||||
|
|
||||||
fun GalleryBlock.formatDownloadFolderTest(format: String): String =
|
fun GalleryBlock.formatDownloadFolderTest(format: String): String =
|
||||||
format.let {
|
format.let {
|
||||||
formatMap.entries.fold(it) { str, (k, v) ->
|
formatMap.entries.fold(it) { str, (k, v) ->
|
||||||
str.replace(k, v.invoke(this), true)
|
str.replace(k, v.invoke(this), true)
|
||||||
}
|
}
|
||||||
}.replace(Regex("""[*\\|"?><:/]"""), "")
|
}.replace(Regex("""[*\\|"?><:/]"""), "").ellipsize(127)
|
||||||
|
|
||||||
val Reader.requestBuilders: List<Request.Builder>
|
val Reader.requestBuilders: List<Request.Builder>
|
||||||
get() {
|
get() {
|
||||||
|
|||||||
Reference in New Issue
Block a user