diff --git a/app/build.gradle b/app/build.gradle index 9c05dce61..bf3e4b9e9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -102,6 +102,12 @@ dependencies { implementation 'com.google.android.material:material:1.9.0' //noinspection LifecycleAnnotationProcessorWithJava8 kapt 'androidx.lifecycle:lifecycle-compiler:2.6.1' + + /** + * TODO: check + * https://issuetracker.google.com/issues/270245927 + * https://issuetracker.google.com/issues/280504155 + */ implementation 'androidx.work:work-runtime-ktx:2.8.1' //noinspection GradleDependency implementation('com.google.guava:guava:31.1-android') { diff --git a/app/src/main/java/org/koitharu/kotatsu/download/domain/DownloadState2.kt b/app/src/main/java/org/koitharu/kotatsu/download/domain/DownloadState.kt similarity index 59% rename from app/src/main/java/org/koitharu/kotatsu/download/domain/DownloadState2.kt rename to app/src/main/java/org/koitharu/kotatsu/download/domain/DownloadState.kt index f595a4f4e..fea793f6d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/download/domain/DownloadState2.kt +++ b/app/src/main/java/org/koitharu/kotatsu/download/domain/DownloadState.kt @@ -6,7 +6,7 @@ import org.koitharu.kotatsu.local.data.LocalManga import org.koitharu.kotatsu.parsers.model.Manga import java.util.Date -data class DownloadState2( +data class DownloadState( val manga: Manga, val isIndeterminate: Boolean, val isPaused: Boolean = false, @@ -46,6 +46,50 @@ data class DownloadState2( .putBoolean(DATA_PAUSED, isPaused) .build() + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as DownloadState + + if (manga != other.manga) return false + if (isIndeterminate != other.isIndeterminate) return false + if (isPaused != other.isPaused) return false + if (isStopped != other.isStopped) return false + if (error != other.error) return false + if (totalChapters != other.totalChapters) return false + if (currentChapter != other.currentChapter) return false + if (totalPages != other.totalPages) return false + if (currentPage != other.currentPage) return false + if (eta != other.eta) return false + if (localManga != other.localManga) return false + if (!downloadedChapters.contentEquals(other.downloadedChapters)) return false + if (timestamp != other.timestamp) return false + if (max != other.max) return false + if (progress != other.progress) return false + return percent == other.percent + } + + override fun hashCode(): Int { + var result = manga.hashCode() + result = 31 * result + isIndeterminate.hashCode() + result = 31 * result + isPaused.hashCode() + result = 31 * result + isStopped.hashCode() + result = 31 * result + (error?.hashCode() ?: 0) + result = 31 * result + totalChapters + result = 31 * result + currentChapter + result = 31 * result + totalPages + result = 31 * result + currentPage + result = 31 * result + eta.hashCode() + result = 31 * result + (localManga?.hashCode() ?: 0) + result = 31 * result + downloadedChapters.contentHashCode() + result = 31 * result + timestamp.hashCode() + result = 31 * result + max + result = 31 * result + progress + result = 31 * result + percent.hashCode() + return result + } + companion object { private const val DATA_MANGA_ID = "manga_id" diff --git a/app/src/main/java/org/koitharu/kotatsu/download/ui/list/DownloadsViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/download/ui/list/DownloadsViewModel.kt index be25d762f..f34651e8d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/download/ui/list/DownloadsViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/download/ui/list/DownloadsViewModel.kt @@ -19,7 +19,7 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.domain.MangaDataRepository import org.koitharu.kotatsu.base.ui.BaseViewModel import org.koitharu.kotatsu.core.ui.DateTimeAgo -import org.koitharu.kotatsu.download.domain.DownloadState2 +import org.koitharu.kotatsu.download.domain.DownloadState import org.koitharu.kotatsu.download.ui.worker.DownloadWorker import org.koitharu.kotatsu.list.ui.model.EmptyState import org.koitharu.kotatsu.list.ui.model.ListModel @@ -173,21 +173,21 @@ class DownloadsViewModel @Inject constructor( private suspend fun WorkInfo.toUiModel(): DownloadItemModel? { val workData = if (outputData == Data.EMPTY) progress else outputData - val mangaId = DownloadState2.getMangaId(workData) + val mangaId = DownloadState.getMangaId(workData) if (mangaId == 0L) return null val manga = getManga(mangaId) ?: return null return DownloadItemModel( id = id, workState = state, manga = manga, - error = DownloadState2.getError(workData), - isIndeterminate = DownloadState2.isIndeterminate(workData), - isPaused = DownloadState2.isPaused(workData), - max = DownloadState2.getMax(workData), - progress = DownloadState2.getProgress(workData), - eta = DownloadState2.getEta(workData), - timestamp = DownloadState2.getTimestamp(workData), - totalChapters = DownloadState2.getDownloadedChapters(workData).size, + error = DownloadState.getError(workData), + isIndeterminate = DownloadState.isIndeterminate(workData), + isPaused = DownloadState.isPaused(workData), + max = DownloadState.getMax(workData), + progress = DownloadState.getProgress(workData), + eta = DownloadState.getEta(workData), + timestamp = DownloadState.getTimestamp(workData), + totalChapters = DownloadState.getDownloadedChapters(workData).size, ) } diff --git a/app/src/main/java/org/koitharu/kotatsu/download/ui/worker/DownloadNotificationFactory.kt b/app/src/main/java/org/koitharu/kotatsu/download/ui/worker/DownloadNotificationFactory.kt index 421c64f8e..a8c06e516 100644 --- a/app/src/main/java/org/koitharu/kotatsu/download/ui/worker/DownloadNotificationFactory.kt +++ b/app/src/main/java/org/koitharu/kotatsu/download/ui/worker/DownloadNotificationFactory.kt @@ -25,7 +25,7 @@ import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import org.koitharu.kotatsu.R import org.koitharu.kotatsu.details.ui.DetailsActivity -import org.koitharu.kotatsu.download.domain.DownloadState2 +import org.koitharu.kotatsu.download.domain.DownloadState import org.koitharu.kotatsu.download.ui.list.DownloadsActivity import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.MangaSource @@ -100,7 +100,7 @@ class DownloadNotificationFactory @AssistedInject constructor( builder.priority = NotificationCompat.PRIORITY_DEFAULT } - suspend fun create(state: DownloadState2?): Notification = mutex.withLock { + suspend fun create(state: DownloadState?): Notification = mutex.withLock { builder.setContentTitle(state?.manga?.title ?: context.getString(R.string.preparing_)) builder.setContentText(context.getString(R.string.manga_downloading_)) builder.setProgress(1, 0, true) diff --git a/app/src/main/java/org/koitharu/kotatsu/download/ui/worker/DownloadWorker.kt b/app/src/main/java/org/koitharu/kotatsu/download/ui/worker/DownloadWorker.kt index c0f45a453..49c285fa1 100644 --- a/app/src/main/java/org/koitharu/kotatsu/download/ui/worker/DownloadWorker.kt +++ b/app/src/main/java/org/koitharu/kotatsu/download/ui/worker/DownloadWorker.kt @@ -39,8 +39,7 @@ import org.koitharu.kotatsu.base.domain.MangaDataRepository import org.koitharu.kotatsu.core.network.CommonHeaders import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.download.domain.DownloadState2 -import org.koitharu.kotatsu.download.ui.service.PausingHandle +import org.koitharu.kotatsu.download.domain.DownloadState import org.koitharu.kotatsu.local.data.LocalManga import org.koitharu.kotatsu.local.data.LocalStorageChanges import org.koitharu.kotatsu.local.data.PagesCache @@ -52,6 +51,7 @@ import org.koitharu.kotatsu.parsers.model.MangaChapter import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.util.await import org.koitharu.kotatsu.parsers.util.mapToSet +import org.koitharu.kotatsu.utils.Throttler import org.koitharu.kotatsu.utils.WorkManagerHelper import org.koitharu.kotatsu.utils.ext.deleteAwait import org.koitharu.kotatsu.utils.ext.getDisplayMessage @@ -83,8 +83,8 @@ class DownloadWorker @AssistedInject constructor( private val notificationManager = appContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager @Volatile - private var lastPublishedState: DownloadState2? = null - private val currentState: DownloadState2 + private var lastPublishedState: DownloadState? = null + private val currentState: DownloadState get() = checkNotNull(lastPublishedState) private val pausingHandle = PausingHandle() @@ -98,7 +98,7 @@ class DownloadWorker @AssistedInject constructor( val manga = mangaDataRepository.findMangaById(mangaId) ?: return Result.failure() val chaptersIds = inputData.getLongArray(CHAPTERS_IDS)?.takeUnless { it.isEmpty() } val downloadedIds = getDoneChapters() - lastPublishedState = DownloadState2(manga, isIndeterminate = true) + lastPublishedState = DownloadState(manga, isIndeterminate = true) return try { downloadMangaImpl(chaptersIds, downloadedIds) Result.success(currentState.toWorkData()) @@ -291,7 +291,7 @@ class DownloadWorker @AssistedInject constructor( return file } - private suspend fun publishState(state: DownloadState2) { + private suspend fun publishState(state: DownloadState) { val previousState = currentState lastPublishedState = state if (previousState.isParticularProgress && state.isParticularProgress) { @@ -314,7 +314,7 @@ class DownloadWorker @AssistedInject constructor( private suspend fun getDoneChapters(): LongArray { val work = WorkManagerHelper(WorkManager.getInstance(applicationContext)).getWorkInfoById(id) ?: return LongArray(0) - return DownloadState2.getDownloadedChapters(work.progress) + return DownloadState.getDownloadedChapters(work.progress) } private fun getChapters( diff --git a/app/src/main/java/org/koitharu/kotatsu/download/ui/service/PausingHandle.kt b/app/src/main/java/org/koitharu/kotatsu/download/ui/worker/PausingHandle.kt similarity index 90% rename from app/src/main/java/org/koitharu/kotatsu/download/ui/service/PausingHandle.kt rename to app/src/main/java/org/koitharu/kotatsu/download/ui/worker/PausingHandle.kt index 791201668..6a660c2ab 100644 --- a/app/src/main/java/org/koitharu/kotatsu/download/ui/service/PausingHandle.kt +++ b/app/src/main/java/org/koitharu/kotatsu/download/ui/worker/PausingHandle.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.download.ui.service +package org.koitharu.kotatsu.download.ui.worker import androidx.annotation.AnyThread import kotlinx.coroutines.flow.MutableStateFlow diff --git a/app/src/main/java/org/koitharu/kotatsu/download/ui/worker/PausingReceiver.kt b/app/src/main/java/org/koitharu/kotatsu/download/ui/worker/PausingReceiver.kt index 5f01711f5..bad07e7df 100644 --- a/app/src/main/java/org/koitharu/kotatsu/download/ui/worker/PausingReceiver.kt +++ b/app/src/main/java/org/koitharu/kotatsu/download/ui/worker/PausingReceiver.kt @@ -7,7 +7,6 @@ import android.content.IntentFilter import android.net.Uri import android.os.PatternMatcher import androidx.core.app.PendingIntentCompat -import org.koitharu.kotatsu.download.ui.service.PausingHandle import org.koitharu.kotatsu.utils.ext.toUUIDOrNull import java.util.UUID diff --git a/app/src/main/java/org/koitharu/kotatsu/sync/domain/SyncHelper.kt b/app/src/main/java/org/koitharu/kotatsu/sync/domain/SyncHelper.kt index 60128fb84..3b84558d9 100644 --- a/app/src/main/java/org/koitharu/kotatsu/sync/domain/SyncHelper.kt +++ b/app/src/main/java/org/koitharu/kotatsu/sync/domain/SyncHelper.kt @@ -26,7 +26,7 @@ import org.koitharu.kotatsu.parsers.util.json.mapJSONTo import org.koitharu.kotatsu.sync.data.SyncAuthApi import org.koitharu.kotatsu.sync.data.SyncAuthenticator import org.koitharu.kotatsu.sync.data.SyncInterceptor -import org.koitharu.kotatsu.utils.GZipInterceptor +import org.koitharu.kotatsu.core.network.GZipInterceptor import org.koitharu.kotatsu.utils.ext.parseJsonOrNull import org.koitharu.kotatsu.utils.ext.toContentValues import org.koitharu.kotatsu.utils.ext.toJson diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/GZipInterceptor.kt b/app/src/main/java/org/koitharu/kotatsu/utils/GZipInterceptor.kt deleted file mode 100644 index 5da93ae8a..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/utils/GZipInterceptor.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.koitharu.kotatsu.utils - -import okhttp3.Interceptor -import okhttp3.Response -import org.koitharu.kotatsu.core.network.CommonHeaders.CONTENT_ENCODING - -class GZipInterceptor : Interceptor { - - override fun intercept(chain: Interceptor.Chain): Response { - val newRequest = chain.request().newBuilder() - newRequest.addHeader(CONTENT_ENCODING, "gzip") - return chain.proceed(newRequest.build()) - } -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/download/ui/worker/Throttler.kt b/app/src/main/java/org/koitharu/kotatsu/utils/Throttler.kt similarity index 86% rename from app/src/main/java/org/koitharu/kotatsu/download/ui/worker/Throttler.kt rename to app/src/main/java/org/koitharu/kotatsu/utils/Throttler.kt index 37f8fd6fd..b026cf15e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/download/ui/worker/Throttler.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/Throttler.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.download.ui.worker +package org.koitharu.kotatsu.utils import android.os.SystemClock diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/progress/PausingProgressJob.kt b/app/src/main/java/org/koitharu/kotatsu/utils/progress/PausingProgressJob.kt index e53806080..eba6501d9 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/progress/PausingProgressJob.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/progress/PausingProgressJob.kt @@ -3,7 +3,7 @@ package org.koitharu.kotatsu.utils.progress import androidx.annotation.AnyThread import kotlinx.coroutines.Job import kotlinx.coroutines.flow.StateFlow -import org.koitharu.kotatsu.download.ui.service.PausingHandle +import org.koitharu.kotatsu.download.ui.worker.PausingHandle class PausingProgressJob

( job: Job, @@ -23,4 +23,4 @@ class PausingProgressJob

( @AnyThread fun resume() = pausingHandle.resume() -} \ No newline at end of file +}