diff --git a/app/build.gradle b/app/build.gradle index 48249cea..5a64e6db 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -108,7 +108,7 @@ dependencies { exclude group: 'org.jetbrains.kotlinx', module: 'kotlinx-serialization-core-jvm' } implementation "xyz.quaver:documentfilex:0.2.15" - implementation "xyz.quaver:floatingsearchview:1.0.3" + implementation "xyz.quaver:floatingsearchview:1.0.4" testImplementation 'junit:junit:4.13' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test:rules:1.3.0' diff --git a/app/libs/recyclerviewfastscroller-release.aar b/app/libs/recyclerviewfastscroller-release.aar index d0f8ce00..896f7d6d 100644 Binary files a/app/libs/recyclerviewfastscroller-release.aar and b/app/libs/recyclerviewfastscroller-release.aar differ diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index 794f670a..3f844996 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -11,8 +11,8 @@ "type": "SINGLE", "filters": [], "properties": [], - "versionCode": 59, - "versionName": "5.0.3-hotfix2", + "versionCode": 60, + "versionName": "5.1", "enabled": true, "outputFile": "app-release.apk" } diff --git a/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt b/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt index 6d9862d2..ef080b6c 100644 --- a/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt +++ b/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt @@ -26,6 +26,7 @@ import android.view.View import android.view.ViewGroup import android.widget.LinearLayout import androidx.cardview.widget.CardView +import androidx.core.view.children import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.CircularProgressDrawable import androidx.vectordrawable.graphics.drawable.Animatable2Compat @@ -48,6 +49,7 @@ import xyz.quaver.hitomi.getReader import xyz.quaver.io.util.getChild import xyz.quaver.pupil.BuildConfig import xyz.quaver.pupil.R +import xyz.quaver.pupil.favoriteTags import xyz.quaver.pupil.favorites import xyz.quaver.pupil.types.Tag import xyz.quaver.pupil.ui.view.TagChip @@ -222,7 +224,18 @@ class GalleryBlockAdapter(private val glide: RequestManager, private val galleri galleryblock_tag_group.removeAllViews() CoroutineScope(Dispatchers.Default).launch { - galleryBlock.relatedTags.map { + galleryBlock.relatedTags.sortedBy { + val tag = Tag.parse(it) + + if (favoriteTags.contains(tag)) + -1 + else + when(Tag.parse(it).area) { + "female" -> 0 + "male" -> 1 + else -> 2 + } + }.map { TagChip(context, Tag.parse(it)).apply { setOnClickListener { view -> for (callback in onChipClickedHandler) 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 8e1d88f2..36755a49 100644 --- a/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt +++ b/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt @@ -43,13 +43,16 @@ import xyz.quaver.pupil.R import xyz.quaver.pupil.client import xyz.quaver.pupil.interceptors import xyz.quaver.pupil.ui.ReaderActivity -import xyz.quaver.pupil.util.Preferences import xyz.quaver.pupil.util.downloader.Cache import xyz.quaver.pupil.util.downloader.DownloadManager import xyz.quaver.pupil.util.ellipsize import xyz.quaver.pupil.util.normalizeID import xyz.quaver.pupil.util.requestBuilders import java.io.IOException +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() { @@ -218,10 +221,11 @@ class DownloadService : Service() { kotlin.runCatching { val image = response.also { if (it.code() != 200) throw IOException() }.body()?.use { it.bytes() } ?: throw Exception() + val padding = ceil(progress[galleryID]?.size?.let { log10(it.toFloat()) } ?: 0F).toInt() CoroutineScope(Dispatchers.IO).launch { kotlin.runCatching { - Cache.getInstance(this@DownloadService, galleryID).putImage(index, "$index.$ext", image) + Cache.getInstance(this@DownloadService, galleryID).putImage(index, "${index.toString().padStart(padding, '0')}.$ext", image) }.onSuccess { progress[galleryID]?.set(index, Float.POSITIVE_INFINITY) notify(galleryID) @@ -309,24 +313,26 @@ class DownloadService : Service() { return@launch } - progress.put(galleryID, MutableList(reader.galleryInfo.files.size) { 0F }) + val list = MutableList(reader.galleryInfo.files.size) { 0F } cache.metadata.imageList?.let { - if (progress[galleryID]?.size != it.size) { + if (list.size != it.size) { FirebaseCrashlytics.getInstance().log( """ GALLERYID: $galleryID - ${it.size} - ${progress[galleryID]?.size} + ${it.size} - ${list.size} """.trimIndent() ) error("ImageList Size does not match") } it.forEachIndexed { index, image -> - progress[galleryID]?.set(index, if (image != null) Float.POSITIVE_INFINITY else 0F) + list[index] = if (image != null) Float.POSITIVE_INFINITY else 0F } } + progress.put(galleryID, list) + if (isCompleted(galleryID)) { if (DownloadManager.getInstance(this@DownloadService) .getDownloadFolder(galleryID) != null ) @@ -352,17 +358,17 @@ class DownloadService : Service() { } reader.requestBuilders.also { - if (it.size != progress[galleryID]?.size) { + if (it.size != list.size) { FirebaseCrashlytics.getInstance().log( """ GALLERYID: $galleryID - ${it.size} - ${progress[galleryID]?.size} + ${it.size} - ${list.size} """.trimIndent() ) error("Requests Size does not match") } }.forEachIndexed { index, it -> - if (progress[galleryID]?.get(index)?.isInfinite() != true) { + if (!list[index].isInfinite()) { 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/ReaderActivity.kt b/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt index 3187b240..788f23c5 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt @@ -118,7 +118,6 @@ class ReaderActivity : BaseActivity() { private var cameraEnabled = false private var eyeType: Eye? = null - private var eyeCount: Int = 0 private var eyeTime: Long = 0L override fun onCreate(savedInstanceState: Bundle?) { @@ -248,6 +247,8 @@ class ReaderActivity : BaseActivity() { override fun onResume() { super.onResume() + bindService(Intent(this, DownloadService::class.java), conn, BIND_AUTO_CREATE) + if (cameraEnabled) startCamera(this, cameraCallback) } @@ -255,6 +256,9 @@ class ReaderActivity : BaseActivity() { override fun onPause() { super.onPause() closeCamera() + + if (downloader != null) + unbindService(conn) } override fun onDestroy() { @@ -265,9 +269,6 @@ class ReaderActivity : BaseActivity() { if (!DownloadManager.getInstance(this).isDownloading(galleryID)) DownloadService.cancel(this, galleryID) - - if (downloader != null) - unbindService(conn) } override fun onBackPressed() { @@ -304,7 +305,6 @@ class ReaderActivity : BaseActivity() { private fun initDownloader() { DownloadService.download(this, galleryID, true) - bindService(Intent(this, DownloadService::class.java), conn, BIND_AUTO_CREATE) timer.schedule(1000, 1000) { val downloader = downloader ?: return@schedule @@ -564,28 +564,23 @@ class ReaderActivity : BaseActivity() { // Both closed / opened !left.xor(right) -> { eyeType = null - eyeCount = 0 eyeTime = 0L } !left -> { if (eyeType != Eye.LEFT) { eyeType = Eye.LEFT - eyeCount = 0 eyeTime = System.currentTimeMillis() } - eyeCount++ } !right -> { if (eyeType != Eye.RIGHT) { eyeType = Eye.RIGHT - eyeCount = 0 eyeTime = System.currentTimeMillis() } - eyeCount++ } } - if (eyeCount > 3 && System.currentTimeMillis() - eyeTime > 500) { + if (eyeType != null && System.currentTimeMillis() - eyeTime > 100) { (this@ReaderActivity.reader_recyclerview.layoutManager as LinearLayoutManager).let { it.scrollToPositionWithOffset(when(eyeType!!) { Eye.RIGHT -> { @@ -597,9 +592,7 @@ class ReaderActivity : BaseActivity() { }, 0) } - eyeType = null - eyeCount = 0 - eyeTime = 0L + eyeTime = System.currentTimeMillis() + 500 } } diff --git a/app/src/main/java/xyz/quaver/pupil/ui/dialog/DownloadLocationDialogFragment.kt b/app/src/main/java/xyz/quaver/pupil/ui/dialog/DownloadLocationDialogFragment.kt index 0b4b1904..4708a470 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/dialog/DownloadLocationDialogFragment.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/dialog/DownloadLocationDialogFragment.kt @@ -37,6 +37,7 @@ import kotlinx.android.synthetic.main.item_download_folder.view.* import net.rdrei.android.dirchooser.DirectoryChooserActivity import net.rdrei.android.dirchooser.DirectoryChooserConfig import xyz.quaver.io.FileX +import xyz.quaver.io.util.toFile import xyz.quaver.pupil.R import xyz.quaver.pupil.util.Preferences import xyz.quaver.pupil.util.byteToString @@ -62,7 +63,7 @@ class DownloadLocationDialogFragment : DialogFragment() { context.contentResolver.takePersistableUriPermission(uri, takeFlags) if (kotlin.runCatching { FileX(context, uri).canWrite() }.getOrDefault(false)) { - entries[null]?.message?.text = uri.toString() + entries[null]?.location_available?.text = uri.toFile(context)?.canonicalPath Preferences["download_folder"] = uri.toString() } else { Snackbar.make( 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 6fe1b42a..76ef9827 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 @@ -45,6 +45,7 @@ import xyz.quaver.pupil.BuildConfig 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 @@ -141,7 +142,18 @@ class GalleryDialog(context: Context, private val glide: RequestManager, private listOf(gallery.language).map { Tag("language", it) }, gallery.series.map { Tag("series", it) }, gallery.characters.map { Tag("character", it) }, - gallery.tags.map { + gallery.tags.sortedBy { + val tag = Tag.parse(it) + + if (favoriteTags.contains(tag)) + -1 + else + when(Tag.parse(it).area) { + "female" -> 0 + "male" -> 1 + else -> 2 + } + }.map { Tag.parse(it).let { tag -> when { tag.area != null -> 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 e34747c8..257a67d9 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 @@ -200,24 +200,18 @@ class Cache private constructor(context: Context, val galleryID: Int) : ContextW fun moveToDownload() = CoroutineScope(Dispatchers.IO).launch { val downloadFolder = downloadFolder ?: return@launch - if (downloadFolder.getChild(".metadata").exists()) + val cacheMetadata = cacheFolder.getChild(".metadata") + val downloadMetadata = downloadFolder.getChild(".metadata") + + if (downloadMetadata.exists() || !cacheMetadata.exists()) return@launch - metadata.imageList?.forEach { imageName -> - imageName ?: return@forEach - val target = downloadFolder.getChild(imageName) - val source = cacheFolder.getChild(imageName) - - if (!source.exists() || target.exists()) - return@forEach - + if (cacheMetadata.exists()) { kotlin.runCatching { - if (!target.exists()) - target.createNewFile() + downloadMetadata.createNewFile() + downloadMetadata.writeText(Json.encodeToString(metadata)) - target.outputStream()?.use { target -> source.inputStream()?.use { source -> - source.copyTo(target) - } } + cacheMetadata.delete() } } @@ -236,19 +230,22 @@ class Cache private constructor(context: Context, val galleryID: Int) : ContextW } } - val cacheMetadata = cacheFolder.getChild(".metadata") - val downloadMetadata = downloadFolder.getChild(".metadata") + metadata.imageList?.forEach { imageName -> + imageName ?: return@forEach + val target = downloadFolder.getChild(imageName) + val source = cacheFolder.getChild(imageName) + + if (!source.exists() || target.exists()) + return@forEach - if (cacheMetadata.exists() && !downloadMetadata.exists()) { kotlin.runCatching { - if (!downloadMetadata.exists()) - downloadMetadata.createNewFile() + if (!target.exists()) + target.createNewFile() - downloadMetadata.writeText(Json.encodeToString(metadata)) - cacheMetadata.delete() + target.outputStream()?.use { target -> source.inputStream()?.use { source -> + source.copyTo(target) + } } } } - - cacheFolder.delete() } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main_content.xml b/app/src/main/res/layout/activity_main_content.xml index 34ad0fd2..201e31c7 100644 --- a/app/src/main/res/layout/activity_main_content.xml +++ b/app/src/main/res/layout/activity_main_content.xml @@ -139,7 +139,7 @@ app:leftActionMode="showHamburger" app:menu="@menu/main" app:dismissOnOutsideTouch="true" - app:close_search_on_keyboard_dismiss="true" + app:close_search_on_keyboard_dismiss="false" tools:ignore="NewApi" /> \ No newline at end of file diff --git a/app/src/main/res/values/dimen.xml b/app/src/main/res/values/dimen.xml index 616e6f93..14682b10 100644 --- a/app/src/main/res/values/dimen.xml +++ b/app/src/main/res/values/dimen.xml @@ -1,12 +1,12 @@ - + 16dp 16dp 100dp - 2000dp + 2000px 24dp 72dp