From a8c22de6012b302f80d06cf175327b0179c1c3c7 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Sun, 18 Oct 2020 20:11:08 +0300 Subject: [PATCH] Reduce memory usage --- .../kotatsu/core/db/entity/MangaWithTags.kt | 5 ++-- .../core/db/entity/TrackLogWithManga.kt | 3 ++- .../core/parser/site/ChanRepository.kt | 17 +++++++++----- .../core/parser/site/DesuMeRepository.kt | 18 +++++++-------- .../core/parser/site/GroupleRepository.kt | 13 ++++++----- .../core/parser/site/HenChanRepository.kt | 5 ++-- .../core/parser/site/MangaLibRepository.kt | 12 ++++++---- .../core/parser/site/MangaTownRepository.kt | 17 +++++++------- .../core/parser/site/NudeMoonRepository.kt | 5 ++-- .../kotatsu/core/prefs/AppSettings.kt | 5 ++-- .../domain/favourites/FavouritesRepository.kt | 9 ++++---- .../domain/history/HistoryRepository.kt | 3 ++- .../kotatsu/domain/local/MangaIndex.kt | 6 ++--- .../kotatsu/ui/download/DownloadService.kt | 2 +- .../FavouriteCategoriesPresenter.kt | 3 ++- .../ui/settings/sources/SourcesAdapter.kt | 3 ++- .../kotatsu/utils/ext/CollectionExt.kt | 23 ++++++++++++++++++- .../koitharu/kotatsu/utils/ext/FragmentExt.kt | 2 +- .../org/koitharu/kotatsu/utils/ext/JsonExt.kt | 11 +++++++++ .../koitharu/kotatsu/utils/ext/StringExt.kt | 3 ++- .../org/koitharu/kotatsu/utils/ext/ViewExt.kt | 4 ++-- 21 files changed, 109 insertions(+), 60 deletions(-) diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaWithTags.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaWithTags.kt index 922b0949a..950fbdf33 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaWithTags.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaWithTags.kt @@ -3,6 +3,7 @@ package org.koitharu.kotatsu.core.db.entity import androidx.room.Embedded import androidx.room.Junction import androidx.room.Relation +import org.koitharu.kotatsu.utils.ext.mapToSet data class MangaWithTags( @Embedded val manga: MangaEntity, @@ -14,7 +15,7 @@ data class MangaWithTags( val tags: List ) { - fun toManga() = manga.toManga(tags.map { + fun toManga() = manga.toManga(tags.mapToSet { it.toMangaTag() - }.toSet()) + }) } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/TrackLogWithManga.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/TrackLogWithManga.kt index 8b9849c66..e32bcde6a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/TrackLogWithManga.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/TrackLogWithManga.kt @@ -4,6 +4,7 @@ import androidx.room.Embedded import androidx.room.Junction import androidx.room.Relation import org.koitharu.kotatsu.core.model.TrackingLogItem +import org.koitharu.kotatsu.utils.ext.mapToSet import java.util.* data class TrackLogWithManga( @@ -24,7 +25,7 @@ data class TrackLogWithManga( fun toTrackingLogItem() = TrackingLogItem( id = trackLog.id, chapters = trackLog.chapters.split('\n').filterNot { x -> x.isEmpty() }, - manga = manga.toManga(tags.map { x -> x.toMangaTag() }.toSet()), + manga = manga.toManga(tags.mapToSet { x -> x.toMangaTag() }), createdAt = Date(trackLog.createdAt) ) } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ChanRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ChanRepository.kt index 45cdaf662..7dc4a5cb8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ChanRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ChanRepository.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.core.parser.site +import androidx.collection.arraySetOf import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* @@ -13,7 +14,11 @@ abstract class ChanRepository(loaderContext: MangaLoaderContext) : RemoteMangaRe protected abstract val defaultDomain: String - override val sortOrders = setOf(SortOrder.NEWEST, SortOrder.POPULARITY, SortOrder.ALPHABETICAL) + override val sortOrders = arraySetOf( + SortOrder.NEWEST, + SortOrder.POPULARITY, + SortOrder.ALPHABETICAL + ) override suspend fun getList( offset: Int, @@ -51,13 +56,13 @@ abstract class ChanRepository(loaderContext: MangaLoaderContext) : RemoteMangaRe coverUrl = row.selectFirst("div.manga_images")?.selectFirst("img") ?.attr("src")?.withDomain(domain).orEmpty(), tags = safe { - row.selectFirst("div.genre")?.select("a")?.map { + row.selectFirst("div.genre")?.select("a")?.mapToSet { MangaTag( title = it.text(), key = it.attr("href").substringAfterLast('/').urlEncoded(), source = source ) - }?.toSet() + } }.orEmpty(), source = source ) @@ -118,17 +123,17 @@ abstract class ChanRepository(loaderContext: MangaLoaderContext) : RemoteMangaRe val doc = loaderContext.httpGet("https://$domain/catalog").parseHtml() val root = doc.body().selectFirst("div.main_fon").getElementById("side") .select("ul").last() - return root.select("li.sidetag").map { li -> + return root.select("li.sidetag").mapToSet { li -> val a = li.children().last() MangaTag( title = a.text().capitalize(), key = a.attr("href").substringAfterLast('/'), source = source ) - }.toSet() + } } - override fun onCreatePreferences() = setOf(R.string.key_parser_domain) + override fun onCreatePreferences() = arraySetOf(R.string.key_parser_domain) private fun getSortKey(sortOrder: SortOrder?) = when (sortOrder ?: sortOrders.minByOrNull { it.ordinal }) { diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/DesuMeRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/DesuMeRepository.kt index 2c6056ce2..b119b4203 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/DesuMeRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/DesuMeRepository.kt @@ -1,20 +1,18 @@ package org.koitharu.kotatsu.core.parser.site +import androidx.collection.arraySetOf import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.core.parser.RemoteMangaRepository import org.koitharu.kotatsu.domain.MangaLoaderContext -import org.koitharu.kotatsu.utils.ext.map -import org.koitharu.kotatsu.utils.ext.mapIndexed -import org.koitharu.kotatsu.utils.ext.parseHtml -import org.koitharu.kotatsu.utils.ext.parseJson +import org.koitharu.kotatsu.utils.ext.* class DesuMeRepository(loaderContext: MangaLoaderContext) : RemoteMangaRepository(loaderContext) { override val source = MangaSource.DESUME - override val sortOrders = setOf( + override val sortOrders = arraySetOf( SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, @@ -76,13 +74,13 @@ class DesuMeRepository(loaderContext: MangaLoaderContext) : RemoteMangaRepositor val json = loaderContext.httpGet(url).parseJson().getJSONObject("response") ?: throw ParseException("Invalid response") return manga.copy( - tags = json.getJSONArray("genres").map { + tags = json.getJSONArray("genres").mapToSet { MangaTag( key = it.getString("text"), title = it.getString("russian"), source = manga.source ) - }.toSet(), + }, description = json.getString("description"), chapters = json.getJSONObject("chapters").getJSONArray("list").mapIndexed { i, it -> val chid = it.getLong("id") @@ -113,16 +111,16 @@ class DesuMeRepository(loaderContext: MangaLoaderContext) : RemoteMangaRepositor val domain = conf.getDomain(DOMAIN) val doc = loaderContext.httpGet("https://$domain/manga/").parseHtml() val root = doc.body().getElementById("animeFilter").selectFirst(".catalog-genres") - return root.select("li").map { + return root.select("li").mapToSet { MangaTag( source = source, key = it.selectFirst("input").attr("data-genre"), title = it.selectFirst("label").text() ) - }.toSet() + } } - override fun onCreatePreferences() = setOf(R.string.key_parser_domain) + override fun onCreatePreferences() = arraySetOf(R.string.key_parser_domain) private fun getSortKey(sortOrder: SortOrder?) = when (sortOrder) { diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/GroupleRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/GroupleRepository.kt index b209378ec..5a198127b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/GroupleRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/GroupleRepository.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.core.parser.site +import androidx.collection.arraySetOf import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* @@ -12,7 +13,7 @@ abstract class GroupleRepository(loaderContext: MangaLoaderContext) : protected abstract val defaultDomain: String - override val sortOrders = setOf( + override val sortOrders = arraySetOf( SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.RATING //FIXME SortOrder.ALPHABETICAL @@ -70,13 +71,13 @@ abstract class GroupleRepository(loaderContext: MangaLoaderContext) : author = tileInfo?.selectFirst("a.person-link")?.text(), tags = safe { tileInfo?.select("a.element-link") - ?.map { + ?.mapToSet { MangaTag( title = it.text(), key = it.attr("href").substringAfterLast('/'), source = source ) - }?.toSet() + } }.orEmpty(), state = when { node.selectFirst("div.tags") @@ -153,16 +154,16 @@ abstract class GroupleRepository(loaderContext: MangaLoaderContext) : val doc = loaderContext.httpGet("https://$domain/list/genres/sort_name").parseHtml() val root = doc.body().getElementById("mangaBox").selectFirst("div.leftContent") .selectFirst("table.table") - return root.select("a.element-link").map { a -> + return root.select("a.element-link").mapToSet { a -> MangaTag( title = a.text().capitalize(), key = a.attr("href").substringAfterLast('/'), source = source ) - }.toSet() + } } - override fun onCreatePreferences() = setOf(R.string.key_parser_domain) + override fun onCreatePreferences() = arraySetOf(R.string.key_parser_domain) private fun getSortKey(sortOrder: SortOrder?) = when (sortOrder ?: sortOrders.minByOrNull { it.ordinal }) { diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HenChanRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HenChanRepository.kt index 61ff829f5..2ef8aed61 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HenChanRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HenChanRepository.kt @@ -4,6 +4,7 @@ import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.utils.ext.longHashCode +import org.koitharu.kotatsu.utils.ext.mapToSet import org.koitharu.kotatsu.utils.ext.parseHtml import org.koitharu.kotatsu.utils.ext.withDomain @@ -37,14 +38,14 @@ class HenChanRepository(loaderContext: MangaLoaderContext) : ChanRepository(load return manga.copy( description = root.getElementById("description")?.html()?.substringBeforeLast(" + ?.nextElementSibling()?.select("a")?.mapToSet { a -> MangaTag( title = a.text().capitalize(), key = a.attr("href").substringAfterLast('='), source = source ) - }?.toSet() ?: manga.tags, + } ?: manga.tags, description = info.getElementsMatchingOwnText("Описание")?.firstOrNull() ?.nextElementSibling()?.html(), chapters = chapters @@ -183,7 +185,7 @@ open class MangaLibRepository(loaderContext: MangaLoaderContext) : if (raw.startsWith("window.__DATA")) { val json = JSONObject(raw.substringAfter('=').substringBeforeLast(';')) val genres = json.getJSONObject("filters").getJSONArray("genres") - val result = HashSet(genres.length()) + val result = ArraySet(genres.length()) for (x in genres) { result += MangaTag( source = source, diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaTownRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaTownRepository.kt index 5493939a2..9afc34b87 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaTownRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaTownRepository.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.core.parser.site +import androidx.collection.arraySetOf import org.intellij.lang.annotations.Language import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.exceptions.ParseException @@ -13,7 +14,7 @@ class MangaTownRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposi override val source = MangaSource.MANGATOWN - override val sortOrders = setOf( + override val sortOrders = arraySetOf( SortOrder.ALPHABETICAL, SortOrder.RATING, SortOrder.POPULARITY, @@ -71,13 +72,13 @@ class MangaTownRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposi "completed" -> MangaState.FINISHED else -> null }, - tags = li.selectFirst("p.keyWord")?.select("a")?.mapNotNull tags@{ x -> + tags = li.selectFirst("p.keyWord")?.select("a")?.mapNotNullToSet tags@{ x -> MangaTag( title = x.attr("title"), key = x.attr("href").parseTagKey() ?: return@tags null, source = MangaSource.MANGATOWN ) - }?.toSet().orEmpty(), + }.orEmpty(), url = href ) } @@ -150,22 +151,22 @@ class MangaTownRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposi .getElementsContainingOwnText("Genres") .first() .nextElementSibling() - return root.select("li").mapNotNull { li -> - val a = li.selectFirst("a") ?: return@mapNotNull null + return root.select("li").mapNotNullToSet { li -> + val a = li.selectFirst("a") ?: return@mapNotNullToSet null val key = a.attr("href").parseTagKey() if (key.isNullOrEmpty()) { - return@mapNotNull null + return@mapNotNullToSet null } MangaTag( source = MangaSource.MANGATOWN, key = key, title = a.text() ) - }.toSet() + } } - override fun onCreatePreferences() = setOf(R.string.key_parser_domain, R.string.key_parser_ssl) + override fun onCreatePreferences() = arraySetOf(R.string.key_parser_domain, R.string.key_parser_ssl) private fun String.parseTagKey() = split('/').findLast { TAG_REGEX matches it } diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/NudeMoonRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/NudeMoonRepository.kt index 0797de493..a83d3f1ab 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/NudeMoonRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/NudeMoonRepository.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.core.parser.site +import androidx.collection.arraySetOf import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* @@ -12,7 +13,7 @@ class NudeMoonRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposit override val source = MangaSource.NUDEMOON - override val sortOrders = setOf(SortOrder.NEWEST, SortOrder.POPULARITY, SortOrder.RATING) + override val sortOrders = arraySetOf(SortOrder.NEWEST, SortOrder.POPULARITY, SortOrder.RATING) init { loaderContext.insertCookies( @@ -133,7 +134,7 @@ class NudeMoonRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposit } } - override fun onCreatePreferences() = setOf(R.string.key_parser_domain) + override fun onCreatePreferences() = arraySetOf(R.string.key_parser_domain) private fun getSortKey(sortOrder: SortOrder?) = when (sortOrder ?: sortOrders.minByOrNull { it.ordinal }) { diff --git a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt index 438603d56..e19d5394a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt @@ -5,6 +5,7 @@ import android.content.SharedPreferences import android.content.res.Resources import android.provider.Settings import androidx.appcompat.app.AppCompatDelegate +import androidx.collection.arraySetOf import androidx.core.content.edit import androidx.preference.PreferenceManager import org.koitharu.kotatsu.R @@ -44,7 +45,7 @@ class AppSettings private constructor(resources: Resources, private val prefs: S val readerPageSwitch by StringSetPreferenceDelegate( resources.getString(R.string.key_reader_switchers), - setOf(PAGE_SWITCH_TAPS) + arraySetOf(PAGE_SWITCH_TAPS) ) var isTrafficWarningEnabled by BoolPreferenceDelegate( @@ -89,7 +90,7 @@ class AppSettings private constructor(resources: Resources, private val prefs: S val trackSources by StringSetPreferenceDelegate( resources.getString(R.string.key_track_sources), - setOf(TRACK_FAVOURITES, TRACK_HISTORY) + arraySetOf(TRACK_FAVOURITES, TRACK_HISTORY) ) var appPassword by NullableStringPreferenceDelegate( diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/favourites/FavouritesRepository.kt b/app/src/main/java/org/koitharu/kotatsu/domain/favourites/FavouritesRepository.kt index b6444a3ff..6728c0741 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/favourites/FavouritesRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/domain/favourites/FavouritesRepository.kt @@ -11,27 +11,28 @@ import org.koitharu.kotatsu.core.db.entity.MangaEntity import org.koitharu.kotatsu.core.db.entity.TagEntity import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.utils.ext.mapToSet class FavouritesRepository(private val db: MangaDatabase) { suspend fun getAllManga(): List { val entities = db.favouritesDao.findAll() - return entities.map { it.manga.toManga(it.tags.map(TagEntity::toMangaTag).toSet()) } + return entities.map { it.manga.toManga(it.tags.mapToSet(TagEntity::toMangaTag)) } } suspend fun getAllManga(offset: Int): List { val entities = db.favouritesDao.findAll(offset, 20) - return entities.map { it.manga.toManga(it.tags.map(TagEntity::toMangaTag).toSet()) } + return entities.map { it.manga.toManga(it.tags.mapToSet(TagEntity::toMangaTag)) } } suspend fun getManga(categoryId: Long): List { val entities = db.favouritesDao.findAll(categoryId) - return entities.map { it.manga.toManga(it.tags.map(TagEntity::toMangaTag).toSet()) } + return entities.map { it.manga.toManga(it.tags.mapToSet(TagEntity::toMangaTag)) } } suspend fun getManga(categoryId: Long, offset: Int): List { val entities = db.favouritesDao.findAll(categoryId, offset, 20) - return entities.map { it.manga.toManga(it.tags.map(TagEntity::toMangaTag).toSet()) } + return entities.map { it.manga.toManga(it.tags.mapToSet(TagEntity::toMangaTag)) } } suspend fun getAllCategories(): List { diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/history/HistoryRepository.kt b/app/src/main/java/org/koitharu/kotatsu/domain/history/HistoryRepository.kt index 3dde43d1a..47efb59ac 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/history/HistoryRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/domain/history/HistoryRepository.kt @@ -13,6 +13,7 @@ import org.koitharu.kotatsu.core.db.entity.TagEntity import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaHistory import org.koitharu.kotatsu.domain.tracking.TrackingRepository +import org.koitharu.kotatsu.utils.ext.mapToSet class HistoryRepository(private val db: MangaDatabase) : KoinComponent { @@ -20,7 +21,7 @@ class HistoryRepository(private val db: MangaDatabase) : KoinComponent { suspend fun getList(offset: Int, limit: Int = 20): List { val entities = db.historyDao.findAll(offset, limit) - return entities.map { it.manga.toManga(it.tags.map(TagEntity::toMangaTag).toSet()) } + return entities.map { it.manga.toManga(it.tags.mapToSet(TagEntity::toMangaTag)) } } suspend fun addOrUpdate(manga: Manga, chapterId: Long, page: Int, scroll: Int) { diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/local/MangaIndex.kt b/app/src/main/java/org/koitharu/kotatsu/domain/local/MangaIndex.kt index 1306dfa24..4ce4dffd9 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/local/MangaIndex.kt +++ b/app/src/main/java/org/koitharu/kotatsu/domain/local/MangaIndex.kt @@ -8,7 +8,7 @@ import org.koitharu.kotatsu.core.model.MangaChapter import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.model.MangaTag import org.koitharu.kotatsu.utils.ext.getStringOrNull -import org.koitharu.kotatsu.utils.ext.map +import org.koitharu.kotatsu.utils.ext.mapToSet import org.koitharu.kotatsu.utils.ext.safe class MangaIndex(source: String?) { @@ -51,13 +51,13 @@ class MangaIndex(source: String?) { rating = json.getDouble("rating").toFloat(), coverUrl = json.getString("cover"), description = json.getStringOrNull("description"), - tags = json.getJSONArray("tags").map { x -> + tags = json.getJSONArray("tags").mapToSet { x -> MangaTag( title = x.getString("title"), key = x.getString("key"), source = source ) - }.toSet(), + }, chapters = getChapters(json.getJSONObject("chapters"), source) ) } diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/download/DownloadService.kt b/app/src/main/java/org/koitharu/kotatsu/ui/download/DownloadService.kt index b2d9626e2..4ac34bedb 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/download/DownloadService.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/download/DownloadService.kt @@ -56,7 +56,7 @@ class DownloadService : BaseService() { when (intent?.action) { ACTION_DOWNLOAD_START -> { val manga = intent.getParcelableExtra(EXTRA_MANGA) - val chapters = intent.getLongArrayExtra(EXTRA_CHAPTERS_IDS)?.toSet() + val chapters = intent.getLongArrayExtra(EXTRA_CHAPTERS_IDS)?.toArraySet() if (manga != null) { jobs[startId] = downloadManga(manga, chapters, startId) Toast.makeText(this, R.string.manga_downloading_, Toast.LENGTH_SHORT).show() diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/FavouriteCategoriesPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/FavouriteCategoriesPresenter.kt index 6a7dfefc1..7a9795095 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/FavouriteCategoriesPresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/FavouriteCategoriesPresenter.kt @@ -7,6 +7,7 @@ import org.koin.core.component.get import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.domain.favourites.FavouritesRepository import org.koitharu.kotatsu.ui.base.BasePresenter +import org.koitharu.kotatsu.utils.ext.mapToSet @InjectViewState class FavouriteCategoriesPresenter : BasePresenter() { @@ -29,7 +30,7 @@ class FavouriteCategoriesPresenter : BasePresenter() { fun loadMangaCategories(manga: Manga) { launchJob { val categories = repository.getCategories(manga.id) - viewState.onCheckedCategoriesChanged(categories.map { it.id.toInt() }.toSet()) + viewState.onCheckedCategoriesChanged(categories.mapToSet { it.id.toInt() }) } } diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/sources/SourcesAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/settings/sources/SourcesAdapter.kt index 5525ddd36..9bf9c6fa0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/sources/SourcesAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/settings/sources/SourcesAdapter.kt @@ -11,6 +11,7 @@ import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.domain.MangaProviderFactory import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener +import org.koitharu.kotatsu.utils.ext.mapToSet import org.koitharu.kotatsu.utils.ext.safe class SourcesAdapter(private val onItemClickListener: OnRecyclerItemClickListener) : @@ -44,7 +45,7 @@ class SourcesAdapter(private val onItemClickListener: OnRecyclerItemClickListene } else { hiddenItems.add(holder.requireData()) } - settings.hiddenSources = hiddenItems.map { x -> x.name }.toSet() + settings.hiddenSources = hiddenItems.mapToSet { x -> x.name } } holder.imageView_config.setOnClickListener { v -> onItemClickListener.onItemClick(holder.requireData(), holder.bindingAdapterPosition, v) diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/CollectionExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/CollectionExt.kt index 015530934..fe12dbd57 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/CollectionExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/CollectionExt.kt @@ -30,7 +30,28 @@ fun List.medianOrNull(): T? = when { inline fun Collection.mapToSet(transform: (T) -> R): Set { val destination = ArraySet(size) - for (item in this) + for (item in this) { destination.add(transform(item)) + } return destination +} + +inline fun Collection.mapNotNullToSet(transform: (T) -> R?): Set { + val destination = ArraySet(size) + for (item in this) { + destination.add(transform(item) ?: continue) + } + return destination +} + +fun LongArray.toArraySet(): Set { + return when (size) { + 0 -> emptySet() + 1 -> setOf(this[0]) + else -> ArraySet(size).also { set -> + for (item in this) { + set.add(item) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt index 4fd33bf01..94f99d8df 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt @@ -3,7 +3,7 @@ package org.koitharu.kotatsu.utils.ext import android.os.Bundle import androidx.fragment.app.Fragment -fun T.withArgs(size: Int, block: Bundle.() -> Unit): T { +inline fun T.withArgs(size: Int, block: Bundle.() -> Unit): T { val b = Bundle(size) b.block() this.arguments = b diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/JsonExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/JsonExt.kt index 6ae0ce40a..69823ffcb 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/JsonExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/JsonExt.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.utils.ext +import androidx.collection.ArraySet import org.json.JSONArray import org.json.JSONObject @@ -36,4 +37,14 @@ private class JSONIterator(private val array: JSONArray) : Iterator override fun next(): JSONObject = array.getJSONObject(index++) +} + +fun JSONArray.mapToSet(block: (JSONObject) -> T): Set { + val len = length() + val result = ArraySet(len) + for (i in 0 until len) { + val jo = getJSONObject(i) + result.add(block(jo)) + } + return result } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/StringExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/StringExt.kt index cf0bb4bbf..5d5770933 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/StringExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/StringExt.kt @@ -1,6 +1,7 @@ package org.koitharu.kotatsu.utils.ext import android.net.Uri +import androidx.collection.arraySetOf import java.math.BigInteger import java.net.URLEncoder import java.security.MessageDigest @@ -71,7 +72,7 @@ fun String.transliterate(skipMissing: Boolean): String { } fun String.toFileNameSafe() = this.transliterate(false) - .replace(Regex("[^a-z0-9_\\-]", setOf(RegexOption.IGNORE_CASE)), " ") + .replace(Regex("[^a-z0-9_\\-]", arraySetOf(RegexOption.IGNORE_CASE)), " ") .replace(Regex("\\s+"), "_") fun String.ellipsize(maxLength: Int) = if (this.length > maxLength) { diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt index c79e54c35..f9f502383 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt @@ -143,7 +143,7 @@ fun View.measureWidth(): Int { } else vw } -fun ViewPager2.doOnPageChanged(callback: (Int) -> Unit) { +inline fun ViewPager2.doOnPageChanged(crossinline callback: (Int) -> Unit) { registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { @@ -153,7 +153,7 @@ fun ViewPager2.doOnPageChanged(callback: (Int) -> Unit) { }) } -fun RecyclerView.doOnCurrentItemChanged(callback: (Int) -> Unit) { +inline fun RecyclerView.doOnCurrentItemChanged(crossinline callback: (Int) -> Unit) { addOnScrollListener(object : RecyclerView.OnScrollListener() { private var lastItem = -1