From 84c58fbe6c446f6697f866be4008957be89742f1 Mon Sep 17 00:00:00 2001 From: Finnley Somdahl <87634197+rebelonion@users.noreply.github.com> Date: Tue, 21 Nov 2023 20:34:34 -0600 Subject: [PATCH] downloading button cleanup --- app/build.gradle | 2 +- app/src/main/AndroidManifest.xml | 1 + .../download/manga/OfflineMangaFragment.kt | 17 ++++--- .../media/manga/MangaChapterAdapter.kt | 51 ++++++++++++++++--- .../dantotsu/media/manga/MangaReadFragment.kt | 15 ++---- .../manga/mangareader/ChapterLoaderDialog.kt | 2 +- .../manga/mangareader/MangaReaderActivity.kt | 4 +- app/src/main/res/drawable/ic_circle_add.xml | 10 ++++ .../main/res/drawable/ic_circle_cancel.xml | 10 ++++ app/src/main/res/drawable/ic_circle_check.xml | 10 ++++ app/src/main/res/drawable/ic_sync.xml | 10 ++++ .../res/layout/fragment_manga_offline.xml | 2 + 12 files changed, 108 insertions(+), 26 deletions(-) create mode 100644 app/src/main/res/drawable/ic_circle_add.xml create mode 100644 app/src/main/res/drawable/ic_circle_cancel.xml create mode 100644 app/src/main/res/drawable/ic_circle_check.xml create mode 100644 app/src/main/res/drawable/ic_sync.xml diff --git a/app/build.gradle b/app/build.gradle index 0ea1f761..eac864f1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -21,7 +21,7 @@ android { minSdk 23 targetSdk 34 versionCode ((System.currentTimeMillis() / 60000).toInteger()) - versionName "1.0.0-beta02" + versionName "1.0.0-beta03i" signingConfig signingConfigs.debug } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 991a97c2..6647fea0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ android:name="android.hardware.touchscreen" android:required="false" /> + diff --git a/app/src/main/java/ani/dantotsu/download/manga/OfflineMangaFragment.kt b/app/src/main/java/ani/dantotsu/download/manga/OfflineMangaFragment.kt index 887ae61a..4167a94e 100644 --- a/app/src/main/java/ani/dantotsu/download/manga/OfflineMangaFragment.kt +++ b/app/src/main/java/ani/dantotsu/download/manga/OfflineMangaFragment.kt @@ -32,6 +32,7 @@ import ani.dantotsu.navBarHeight import ani.dantotsu.px import ani.dantotsu.setSafeOnClickListener import ani.dantotsu.settings.SettingsDialogFragment +import ani.dantotsu.snackString import ani.dantotsu.statusBarHeight import com.google.android.material.card.MaterialCardView import com.google.android.material.imageview.ShapeableImageView @@ -84,12 +85,16 @@ class OfflineMangaFragment: Fragment() { gridView.setOnItemClickListener { parent, view, position, id -> // Get the OfflineMangaModel that was clicked val item = adapter.getItem(position) as OfflineMangaModel - val media = downloadManager.mangaDownloads.filter { it.title == item.title }.first() - startActivity( - Intent(requireContext(), MediaDetailsActivity::class.java) - .putExtra("media", getMedia(media)) - .putExtra("download", true) - ) + val media = downloadManager.mangaDownloads.filter { it.title == item.title }.firstOrNull() + media?.let { + startActivity( + Intent(requireContext(), MediaDetailsActivity::class.java) + .putExtra("media", getMedia(it)) + .putExtra("download", true) + ) + } ?: run { + snackString("no media found") + } } return view diff --git a/app/src/main/java/ani/dantotsu/media/manga/MangaChapterAdapter.kt b/app/src/main/java/ani/dantotsu/media/manga/MangaChapterAdapter.kt index 4480d7a6..cfce2642 100644 --- a/app/src/main/java/ani/dantotsu/media/manga/MangaChapterAdapter.kt +++ b/app/src/main/java/ani/dantotsu/media/manga/MangaChapterAdapter.kt @@ -1,8 +1,12 @@ package ani.dantotsu.media.manga +import android.util.TypedValue import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.view.animation.LinearInterpolator +import androidx.core.content.ContentProviderCompat.requireContext +import androidx.lifecycle.coroutineScope import androidx.recyclerview.widget.RecyclerView import ani.dantotsu.R import ani.dantotsu.databinding.ItemChapterListBinding @@ -10,8 +14,9 @@ import ani.dantotsu.databinding.ItemEpisodeCompactBinding import ani.dantotsu.media.Media import ani.dantotsu.setAnimation import ani.dantotsu.connections.updateProgress -import java.util.regex.Matcher -import java.util.regex.Pattern +import ani.dantotsu.currContext +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch class MangaChapterAdapter( private var type: Int, @@ -90,7 +95,7 @@ class MangaChapterAdapter( } } - fun removeDownload(chapterNumber: String) { + fun purgeDownload(chapterNumber: String) { activeDownloads.remove(chapterNumber) downloadedChapters.remove(chapterNumber) // Find the position of the chapter and notify only that item @@ -112,6 +117,9 @@ class MangaChapterAdapter( inner class ChapterListViewHolder(val binding: ItemChapterListBinding) : RecyclerView.ViewHolder(binding.root) { + private val activeCoroutines = mutableSetOf() + val typedValue1 = TypedValue() + val typedValue2 = TypedValue() fun bind(chapterNumber: String, progress: String?) { if (progress != null) { binding.itemChapterTitle.visibility = View.VISIBLE @@ -122,18 +130,49 @@ class MangaChapterAdapter( } if (activeDownloads.contains(chapterNumber)) { // Show spinner - binding.itemDownload.setImageResource(R.drawable.ic_round_refresh_24) + binding.itemDownload.setImageResource(R.drawable.ic_sync) + startOrContinueRotation(chapterNumber) } else if (downloadedChapters.contains(chapterNumber)) { // Show checkmark - binding.itemDownload.setImageResource(R.drawable.ic_check) + binding.itemDownload.setImageResource(R.drawable.ic_circle_check) + binding.itemDownload.setColorFilter(typedValue2.data) + binding.itemDownload.postDelayed({ + binding.itemDownload.setImageResource(R.drawable.ic_circle_cancel) + binding.itemDownload.setColorFilter(typedValue2.data) + }, 5000) } else { // Show download icon - binding.itemDownload.setImageResource(R.drawable.ic_round_download_24) + binding.itemDownload.setImageResource(R.drawable.ic_circle_add) } } + private fun startOrContinueRotation(chapterNumber: String) { + if (!isRotationCoroutineRunningFor(chapterNumber)) { + val scope = fragment.lifecycle.coroutineScope + scope.launch { + // Add chapter number to active coroutines set + activeCoroutines.add(chapterNumber) + while (activeDownloads.contains(chapterNumber)) { + binding.itemDownload.animate().rotationBy(360f).setDuration(1000).setInterpolator( + LinearInterpolator() + ).start() + delay(1000) + } + // Remove chapter number from active coroutines set + activeCoroutines.remove(chapterNumber) + } + } + } + + private fun isRotationCoroutineRunningFor(chapterNumber: String): Boolean { + return chapterNumber in activeCoroutines + } + init { + val theme = currContext()?.theme + theme?.resolveAttribute(com.google.android.material.R.attr.colorError, typedValue1, true) + theme?.resolveAttribute(com.google.android.material.R.attr.colorPrimary, typedValue2, true) itemView.setOnClickListener { if (0 <= bindingAdapterPosition && bindingAdapterPosition < arr.size) fragment.onMangaChapterClick(arr[bindingAdapterPosition].number) diff --git a/app/src/main/java/ani/dantotsu/media/manga/MangaReadFragment.kt b/app/src/main/java/ani/dantotsu/media/manga/MangaReadFragment.kt index 46f41f54..63aa6d1c 100644 --- a/app/src/main/java/ani/dantotsu/media/manga/MangaReadFragment.kt +++ b/app/src/main/java/ani/dantotsu/media/manga/MangaReadFragment.kt @@ -2,7 +2,6 @@ package ani.dantotsu.media.manga import android.annotation.SuppressLint import android.app.AlertDialog -import android.app.DownloadManager import android.content.BroadcastReceiver import android.content.Context import android.content.Intent @@ -16,7 +15,6 @@ import android.view.View import android.view.ViewGroup import android.widget.FrameLayout import android.widget.Toast -import androidx.annotation.RequiresApi import androidx.cardview.widget.CardView import androidx.core.content.ContextCompat import androidx.core.math.MathUtils.clamp @@ -42,7 +40,6 @@ import ani.dantotsu.parsers.HMangaSources import ani.dantotsu.parsers.MangaParser import ani.dantotsu.parsers.MangaSources import ani.dantotsu.settings.UserInterfaceSettings -import ani.dantotsu.settings.extensionprefs.AnimeSourcePreferencesFragment import ani.dantotsu.settings.extensionprefs.MangaSourcePreferencesFragment import ani.dantotsu.subcriptions.Notifications import ani.dantotsu.subcriptions.Notifications.Group.MANGA_GROUP @@ -51,8 +48,6 @@ import ani.dantotsu.subcriptions.SubscriptionHelper import ani.dantotsu.subcriptions.SubscriptionHelper.Companion.saveSubscription import com.google.android.material.appbar.AppBarLayout import com.google.android.material.navigationrail.NavigationRailView -import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource -import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension import eu.kanade.tachiyomi.extension.manga.model.MangaExtension import eu.kanade.tachiyomi.source.ConfigurableSource import kotlinx.coroutines.CoroutineScope @@ -405,7 +400,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener { // Create a download task val downloadTask = MangaDownloaderService.DownloadTask( - title = media.nameMAL ?: "", + title = media.nameMAL ?: media.nameRomaji, chapter = chapter.title!!, imageData = images, sourceMedia = media, @@ -445,7 +440,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener { fun onMangaChapterRemoveDownloadClick(i: String){ - downloadManager.removeDownload(Download(media.nameMAL!!, i, Download.Type.MANGA)) + downloadManager.removeDownload(Download(media.nameMAL?:media.nameRomaji, i, Download.Type.MANGA)) chapterAdapter.deleteDownload(i) } fun onMangaChapterStopDownloadClick(i: String) { @@ -456,8 +451,8 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener { requireContext().sendBroadcast(cancelIntent) // Remove the download from the manager and update the UI - downloadManager.removeDownload(Download(media.nameMAL!!, i, Download.Type.MANGA)) - chapterAdapter.stopDownload(i) + downloadManager.removeDownload(Download(media.nameMAL?:media.nameRomaji, i, Download.Type.MANGA)) + chapterAdapter.purgeDownload(i) } private val downloadStatusReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { @@ -473,7 +468,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener { ACTION_DOWNLOAD_FAILED -> { val chapterNumber = intent.getStringExtra(EXTRA_CHAPTER_NUMBER) chapterNumber?.let { - chapterAdapter.removeDownload(it) + chapterAdapter.purgeDownload(it) } } ACTION_DOWNLOAD_PROGRESS -> { diff --git a/app/src/main/java/ani/dantotsu/media/manga/mangareader/ChapterLoaderDialog.kt b/app/src/main/java/ani/dantotsu/media/manga/mangareader/ChapterLoaderDialog.kt index 342203cd..3cf0c0e1 100644 --- a/app/src/main/java/ani/dantotsu/media/manga/mangareader/ChapterLoaderDialog.kt +++ b/app/src/main/java/ani/dantotsu/media/manga/mangareader/ChapterLoaderDialog.kt @@ -47,7 +47,7 @@ class ChapterLoaderDialog : BottomSheetDialogFragment() { loaded = true binding.selectorAutoText.text = chp.title lifecycleScope.launch(Dispatchers.IO) { - if(model.loadMangaChapterImages(chp, m.selected!!, m.nameMAL!!)) { + if(model.loadMangaChapterImages(chp, m.selected!!, m.nameMAL?:m.nameRomaji)) { val activity = currActivity() activity?.runOnUiThread { tryWith { dismiss() } diff --git a/app/src/main/java/ani/dantotsu/media/manga/mangareader/MangaReaderActivity.kt b/app/src/main/java/ani/dantotsu/media/manga/mangareader/MangaReaderActivity.kt index dd81e617..a5682716 100644 --- a/app/src/main/java/ani/dantotsu/media/manga/mangareader/MangaReaderActivity.kt +++ b/app/src/main/java/ani/dantotsu/media/manga/mangareader/MangaReaderActivity.kt @@ -317,7 +317,7 @@ ThemeManager(this).applyTheme() } } - scope.launch(Dispatchers.IO) { model.loadMangaChapterImages(chapter, media.selected!!, media.nameMAL!!) } + scope.launch(Dispatchers.IO) { model.loadMangaChapterImages(chapter, media.selected!!, media.nameMAL?:media.nameRomaji) } } private val snapHelper = PagerSnapHelper() @@ -706,7 +706,7 @@ ThemeManager(this).applyTheme() model.loadMangaChapterImages( chapters[chaptersArr.getOrNull(currentChapterIndex + 1) ?: return@launch]!!, media.selected!!, - media.nameMAL!!, + media.nameMAL?:media.nameRomaji, false ) loading = false diff --git a/app/src/main/res/drawable/ic_circle_add.xml b/app/src/main/res/drawable/ic_circle_add.xml new file mode 100644 index 00000000..4f65263e --- /dev/null +++ b/app/src/main/res/drawable/ic_circle_add.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_circle_cancel.xml b/app/src/main/res/drawable/ic_circle_cancel.xml new file mode 100644 index 00000000..72bb239b --- /dev/null +++ b/app/src/main/res/drawable/ic_circle_cancel.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_circle_check.xml b/app/src/main/res/drawable/ic_circle_check.xml new file mode 100644 index 00000000..ea65d8d2 --- /dev/null +++ b/app/src/main/res/drawable/ic_circle_check.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_sync.xml b/app/src/main/res/drawable/ic_sync.xml new file mode 100644 index 00000000..4ad75e53 --- /dev/null +++ b/app/src/main/res/drawable/ic_sync.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/fragment_manga_offline.xml b/app/src/main/res/layout/fragment_manga_offline.xml index 3972cd2a..279da4b9 100644 --- a/app/src/main/res/layout/fragment_manga_offline.xml +++ b/app/src/main/res/layout/fragment_manga_offline.xml @@ -97,6 +97,8 @@ android:layout_height="0dp" android:layout_weight="1" android:numColumns="auto_fit" + android:paddingLeft="8dp" + android:paddingRight="8dp" android:columnWidth="108dp" android:verticalSpacing="10dp" android:horizontalSpacing="10dp"