Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
626bb20edb | ||
|
|
d363869dab | ||
|
|
774f33c63d | ||
|
|
079427346a | ||
|
|
a1a3125834 |
@@ -16,7 +16,7 @@ android {
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 29
|
||||
versionCode gitCommits
|
||||
versionName '0.5-rc1'
|
||||
versionName '0.5-rc3'
|
||||
|
||||
kapt {
|
||||
arguments {
|
||||
@@ -72,6 +72,8 @@ dependencies {
|
||||
implementation 'androidx.preference:preference-ktx:1.1.1'
|
||||
implementation 'androidx.work:work-runtime-ktx:2.4.0-rc01'
|
||||
implementation 'com.google.android.material:material:1.3.0-alpha01'
|
||||
//noinspection LifecycleAnnotationProcessorWithJava8
|
||||
kapt 'androidx.lifecycle:lifecycle-compiler:2.3.0-alpha05'
|
||||
|
||||
implementation 'androidx.room:room-runtime:2.2.5'
|
||||
implementation 'androidx.room:room-ktx:2.2.5'
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.core.parser
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.webkit.MimeTypeMap
|
||||
import androidx.collection.ArraySet
|
||||
import androidx.core.net.toFile
|
||||
import androidx.core.net.toUri
|
||||
@@ -91,7 +92,7 @@ class LocalMangaRepository : MangaRepository, KoinComponent {
|
||||
coverUrl = zipUri(
|
||||
file,
|
||||
entryName = index.getCoverEntry()
|
||||
?: findFirstEntry(zip.entries())?.name.orEmpty()
|
||||
?: findFirstEntry(zip.entries(), isImage = true)?.name.orEmpty()
|
||||
),
|
||||
chapters = info.chapters?.map { c -> c.copy(url = fileUri) }
|
||||
)
|
||||
@@ -110,7 +111,7 @@ class LocalMangaRepository : MangaRepository, KoinComponent {
|
||||
title = title,
|
||||
url = fileUri,
|
||||
source = MangaSource.LOCAL,
|
||||
coverUrl = zipUri(file, findFirstEntry(zip.entries())?.name.orEmpty()),
|
||||
coverUrl = zipUri(file, findFirstEntry(zip.entries(), isImage = true)?.name.orEmpty()),
|
||||
chapters = chapters.sortedWith(AlphanumComparator()).mapIndexed { i, s ->
|
||||
MangaChapter(
|
||||
id = "$i$s".longHashCode(),
|
||||
@@ -136,11 +137,19 @@ class LocalMangaRepository : MangaRepository, KoinComponent {
|
||||
private fun zipUri(file: File, entryName: String) =
|
||||
Uri.fromParts("cbz", file.path, entryName).toString()
|
||||
|
||||
private fun findFirstEntry(entries: Enumeration<out ZipEntry>): ZipEntry? {
|
||||
private fun findFirstEntry(entries: Enumeration<out ZipEntry>, isImage: Boolean): ZipEntry? {
|
||||
val list = entries.toList()
|
||||
.filterNot { it.isDirectory }
|
||||
.sortedWith(compareBy(AlphanumComparator()) { x -> x.name })
|
||||
return list.firstOrNull()
|
||||
return if (isImage) {
|
||||
val map = MimeTypeMap.getSingleton()
|
||||
list.firstOrNull {
|
||||
map.getMimeTypeFromExtension(it.name.substringAfterLast('.'))
|
||||
?.startsWith("image/") == true
|
||||
}
|
||||
} else {
|
||||
list.firstOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
override val sortOrders = emptySet<SortOrder>()
|
||||
|
||||
@@ -18,7 +18,12 @@ class MangaSearchRepository : KoinComponent {
|
||||
var isEmitted = false
|
||||
for (source in sources) {
|
||||
val list = lists.getOrPut(source) {
|
||||
MangaProviderFactory.create(source).getList(0, query, SortOrder.POPULARITY)
|
||||
try {
|
||||
MangaProviderFactory.create(source).getList(0, query, SortOrder.POPULARITY)
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
emptyList<Manga>()
|
||||
}
|
||||
}
|
||||
if (i < list.size) {
|
||||
emit(list.subList(i, (i + batchSize).coerceAtMost(list.lastIndex)))
|
||||
|
||||
@@ -6,10 +6,8 @@ import org.koin.core.inject
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.core.db.entity.TrackEntity
|
||||
import org.koitharu.kotatsu.core.db.entity.TrackLogEntity
|
||||
import org.koitharu.kotatsu.core.model.Manga
|
||||
import org.koitharu.kotatsu.core.model.MangaChapter
|
||||
import org.koitharu.kotatsu.core.model.MangaTracking
|
||||
import org.koitharu.kotatsu.core.model.TrackingLogItem
|
||||
import org.koitharu.kotatsu.core.model.*
|
||||
import org.koitharu.kotatsu.domain.MangaProviderFactory
|
||||
import java.util.*
|
||||
|
||||
class TrackingRepository : KoinComponent {
|
||||
@@ -24,12 +22,16 @@ class TrackingRepository : KoinComponent {
|
||||
suspend fun getAllTracks(): List<MangaTracking> {
|
||||
val favourites = db.favouritesDao.findAllManga()
|
||||
val history = db.historyDao.findAllManga()
|
||||
val manga = (favourites + history).distinctBy { it.id }
|
||||
val mangas = (favourites + history).distinctBy { it.id }
|
||||
val tracks = db.tracksDao.findAll().groupBy { it.mangaId }
|
||||
return manga.map { m ->
|
||||
val track = tracks[m.id]?.singleOrNull()
|
||||
return mangas.mapNotNull { me ->
|
||||
var manga = me.toManga()
|
||||
if (manga.source == MangaSource.LOCAL) {
|
||||
manga = MangaProviderFactory.createLocal().getRemoteManga(manga) ?: return@mapNotNull null
|
||||
}
|
||||
val track = tracks[manga.id]?.singleOrNull()
|
||||
MangaTracking(
|
||||
manga = m.toManga(),
|
||||
manga = manga,
|
||||
knownChaptersCount = track?.totalChapters ?: -1,
|
||||
lastChapterId = track?.lastChapterId ?: 0L,
|
||||
lastNotifiedChapterId = track?.lastNotifiedChapterId ?: 0L,
|
||||
|
||||
@@ -77,9 +77,9 @@ class DownloadService : BaseService() {
|
||||
return launch(Dispatchers.IO) {
|
||||
mutex.lock()
|
||||
wakeLock.acquire(TimeUnit.HOURS.toMillis(1))
|
||||
notification.fillFrom(manga)
|
||||
notification.setCancelId(startId)
|
||||
withContext(Dispatchers.Main) {
|
||||
notification.fillFrom(manga)
|
||||
notification.setCancelId(startId)
|
||||
startForeground(DownloadNotification.NOTIFICATION_ID, notification())
|
||||
}
|
||||
val destination = settings.getStorageDir(this@DownloadService)
|
||||
@@ -94,10 +94,8 @@ class DownloadService : BaseService() {
|
||||
.build()
|
||||
).drawable
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
notification.setLargeIcon(cover)
|
||||
notification.update()
|
||||
}
|
||||
notification.setLargeIcon(cover)
|
||||
notification.update()
|
||||
val data = if (manga.chapters == null) repo.getDetails(manga) else manga
|
||||
output = MangaZip.findInDir(destination, data)
|
||||
output.prepare(data)
|
||||
@@ -141,31 +139,25 @@ class DownloadService : BaseService() {
|
||||
}
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
notification.setCancelId(0)
|
||||
notification.setPostProcessing()
|
||||
notification.update()
|
||||
}
|
||||
notification.setCancelId(0)
|
||||
notification.setPostProcessing()
|
||||
notification.update()
|
||||
output.compress()
|
||||
val result = MangaProviderFactory.createLocal().getFromFile(output.file)
|
||||
withContext(Dispatchers.Main) {
|
||||
notification.setDone(result)
|
||||
notification.dismiss()
|
||||
notification.update(manga.id.toInt().absoluteValue)
|
||||
}
|
||||
notification.setDone(result)
|
||||
notification.dismiss()
|
||||
notification.update(manga.id.toInt().absoluteValue)
|
||||
} catch (_: CancellationException) {
|
||||
withContext(Dispatchers.Main + NonCancellable) {
|
||||
withContext(NonCancellable) {
|
||||
notification.setCancelling()
|
||||
notification.setCancelId(0)
|
||||
notification.update()
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
withContext(Dispatchers.Main) {
|
||||
notification.setError(e)
|
||||
notification.setCancelId(0)
|
||||
notification.dismiss()
|
||||
notification.update(manga.id.toInt().absoluteValue)
|
||||
}
|
||||
notification.setError(e)
|
||||
notification.setCancelId(0)
|
||||
notification.dismiss()
|
||||
notification.update(manga.id.toInt().absoluteValue)
|
||||
} finally {
|
||||
withContext(NonCancellable) {
|
||||
jobs.remove(startId)
|
||||
|
||||
@@ -6,7 +6,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.2.0-alpha03'
|
||||
classpath 'com.android.tools.build:gradle:4.2.0-alpha04'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
||||
Reference in New Issue
Block a user