From a0018b5fb6d646cb0b2d0bf71999a91c2ed21b72 Mon Sep 17 00:00:00 2001 From: rebelonion <87634197+rebelonion@users.noreply.github.com> Date: Sun, 21 Jan 2024 01:40:44 -0600 Subject: [PATCH] pinned sources --- app/src/main/java/ani/dantotsu/App.kt | 4 +- .../main/java/ani/dantotsu/MainActivity.kt | 1 - .../manga/mangareader/MangaReaderActivity.kt | 2 +- .../java/ani/dantotsu/parsers/AnimeSources.kt | 27 +++++- .../java/ani/dantotsu/parsers/MangaSources.kt | 27 +++++- .../ani/dantotsu/settings/SettingsActivity.kt | 85 ++++++++++++++++++- app/src/main/res/drawable/ic_pin.xml | 9 ++ app/src/main/res/layout/activity_settings.xml | 80 +++++++++++++++++ app/src/main/res/values/strings.xml | 1 + 9 files changed, 226 insertions(+), 10 deletions(-) create mode 100644 app/src/main/res/drawable/ic_pin.xml diff --git a/app/src/main/java/ani/dantotsu/App.kt b/app/src/main/java/ani/dantotsu/App.kt index b9eba235..5b6869ea 100644 --- a/app/src/main/java/ani/dantotsu/App.kt +++ b/app/src/main/java/ani/dantotsu/App.kt @@ -97,13 +97,13 @@ class App : MultiDexApplication() { animeScope.launch { animeExtensionManager.findAvailableExtensions() logger("Anime Extensions: ${animeExtensionManager.installedExtensionsFlow.first()}") - AnimeSources.init(animeExtensionManager.installedExtensionsFlow) + AnimeSources.init(animeExtensionManager.installedExtensionsFlow, this@App) } val mangaScope = CoroutineScope(Dispatchers.Default) mangaScope.launch { mangaExtensionManager.findAvailableExtensions() logger("Manga Extensions: ${mangaExtensionManager.installedExtensionsFlow.first()}") - MangaSources.init(mangaExtensionManager.installedExtensionsFlow) + MangaSources.init(mangaExtensionManager.installedExtensionsFlow, this@App) } val novelScope = CoroutineScope(Dispatchers.Default) novelScope.launch { diff --git a/app/src/main/java/ani/dantotsu/MainActivity.kt b/app/src/main/java/ani/dantotsu/MainActivity.kt index 73ac4a2d..2be1a87d 100644 --- a/app/src/main/java/ani/dantotsu/MainActivity.kt +++ b/app/src/main/java/ani/dantotsu/MainActivity.kt @@ -338,7 +338,6 @@ class MainActivity : AppCompatActivity() { } } } - } 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 fe1c597b..c396088d 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 @@ -220,7 +220,7 @@ class MangaReaderActivity : AppCompatActivity() { val mangaSources = MangaSources val scope = lifecycleScope scope.launch(Dispatchers.IO) { - mangaSources.init(Injekt.get().installedExtensionsFlow) + mangaSources.init(Injekt.get().installedExtensionsFlow, this@MangaReaderActivity) } model.mangaReadSources = mangaSources } else { diff --git a/app/src/main/java/ani/dantotsu/parsers/AnimeSources.kt b/app/src/main/java/ani/dantotsu/parsers/AnimeSources.kt index dd3faaef..11a69c31 100644 --- a/app/src/main/java/ani/dantotsu/parsers/AnimeSources.kt +++ b/app/src/main/java/ani/dantotsu/parsers/AnimeSources.kt @@ -1,5 +1,6 @@ package ani.dantotsu.parsers +import android.content.Context import ani.dantotsu.Lazier import ani.dantotsu.lazyList import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension @@ -8,8 +9,12 @@ import kotlinx.coroutines.flow.first object AnimeSources : WatchSources() { override var list: List> = emptyList() + var pinnedAnimeSources: Set = emptySet() + + suspend fun init(fromExtensions: StateFlow>, context: Context) { + val sharedPrefs = context.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE) + pinnedAnimeSources = sharedPrefs.getStringSet("pinned_anime_sources", emptySet()) ?: emptySet() - suspend fun init(fromExtensions: StateFlow>) { // Initialize with the first value from StateFlow val initialExtensions = fromExtensions.first() list = createParsersFromExtensions(initialExtensions) + Lazier( @@ -19,19 +24,37 @@ object AnimeSources : WatchSources() { // Update as StateFlow emits new values fromExtensions.collect { extensions -> - list = createParsersFromExtensions(extensions) + Lazier( + list = sortPinnedAnimeSources(createParsersFromExtensions(extensions), pinnedAnimeSources) + Lazier( { OfflineAnimeParser() }, "Downloaded" ) } } + fun performReorderAnimeSources() { + //remove the downloaded source from the list to avoid duplicates + list = list.filter { it.name != "Downloaded" } + list = sortPinnedAnimeSources(list, pinnedAnimeSources) + Lazier( + { OfflineAnimeParser() }, + "Downloaded" + ) + } + private fun createParsersFromExtensions(extensions: List): List> { return extensions.map { extension -> val name = extension.name Lazier({ DynamicAnimeParser(extension) }, name) } } + + private fun sortPinnedAnimeSources(Sources: List>, pinnedAnimeSources: Set): List> { + //find the pinned sources + val pinnedSources = Sources.filter { pinnedAnimeSources.contains(it.name) } + //find the unpinned sources + val unpinnedSources = Sources.filter { !pinnedAnimeSources.contains(it.name) } + //put the pinned sources at the top of the list + return pinnedSources + unpinnedSources + } } diff --git a/app/src/main/java/ani/dantotsu/parsers/MangaSources.kt b/app/src/main/java/ani/dantotsu/parsers/MangaSources.kt index 3709ddaa..a6da1540 100644 --- a/app/src/main/java/ani/dantotsu/parsers/MangaSources.kt +++ b/app/src/main/java/ani/dantotsu/parsers/MangaSources.kt @@ -1,5 +1,6 @@ package ani.dantotsu.parsers +import android.content.Context import ani.dantotsu.Lazier import ani.dantotsu.lazyList import eu.kanade.tachiyomi.extension.manga.model.MangaExtension @@ -8,8 +9,12 @@ import kotlinx.coroutines.flow.first object MangaSources : MangaReadSources() { override var list: List> = emptyList() + var pinnedMangaSources: Set = emptySet() + + suspend fun init(fromExtensions: StateFlow>, context: Context) { + val sharedPrefs = context.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE) + pinnedMangaSources = sharedPrefs.getStringSet("pinned_manga_sources", emptySet()) ?: emptySet() - suspend fun init(fromExtensions: StateFlow>) { // Initialize with the first value from StateFlow val initialExtensions = fromExtensions.first() list = createParsersFromExtensions(initialExtensions) + Lazier( @@ -19,19 +24,37 @@ object MangaSources : MangaReadSources() { // Update as StateFlow emits new values fromExtensions.collect { extensions -> - list = createParsersFromExtensions(extensions) + Lazier( + list = sortPinnedMangaSources(createParsersFromExtensions(extensions), pinnedMangaSources) + Lazier( { OfflineMangaParser() }, "Downloaded" ) } } + fun performReorderMangaSources() { + //remove the downloaded source from the list to avoid duplicates + list = list.filter { it.name != "Downloaded" } + list = sortPinnedMangaSources(list, pinnedMangaSources) + Lazier( + { OfflineMangaParser() }, + "Downloaded" + ) + } + private fun createParsersFromExtensions(extensions: List): List> { return extensions.map { extension -> val name = extension.name Lazier({ DynamicMangaParser(extension) }, name) } } + + private fun sortPinnedMangaSources(Sources: List>, pinnedMangaSources: Set): List> { + //find the pinned sources + val pinnedSources = Sources.filter { pinnedMangaSources.contains(it.name) } + //find the unpinned sources + val unpinnedSources = Sources.filter { !pinnedMangaSources.contains(it.name) } + //put the pinned sources at the top of the list + return pinnedSources + unpinnedSources + } } object HMangaSources : MangaReadSources() { diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsActivity.kt b/app/src/main/java/ani/dantotsu/settings/SettingsActivity.kt index 3104bae9..d140224b 100644 --- a/app/src/main/java/ani/dantotsu/settings/SettingsActivity.kt +++ b/app/src/main/java/ani/dantotsu/settings/SettingsActivity.kt @@ -190,7 +190,6 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene .show(this, tag) } - //val animeSource = loadData("settings_def_anime_source_s")?.let { if (it >= AnimeSources.names.size) 0 else it } ?: 0 val animeSource = getSharedPreferences( "Dantotsu", Context.MODE_PRIVATE @@ -215,6 +214,47 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene binding.animeSource.clearFocus() } + binding.settingsPinnedAnimeSources.setOnClickListener { + val animeSourcesWithoutDownloadsSource = AnimeSources.list.filter { it.name != "Downloaded" } + val names = animeSourcesWithoutDownloadsSource.map { it.name } + val pinnedSourcesBoolean = animeSourcesWithoutDownloadsSource.map { it.name in AnimeSources.pinnedAnimeSources } + val pinnedSourcesOriginal = getSharedPreferences( + "Dantotsu", + Context.MODE_PRIVATE + ).getStringSet("pinned_anime_sources", null) + val pinnedSources = pinnedSourcesOriginal?.toMutableSet() ?: mutableSetOf() + val alertDialog = AlertDialog.Builder(this, R.style.MyPopup) + .setTitle("Pinned Anime Sources") + .setMultiChoiceItems( + names.toTypedArray(), + pinnedSourcesBoolean.toBooleanArray() + ) { _, which, isChecked -> + if (isChecked) { + pinnedSources.add(AnimeSources.names[which]) + } else { + pinnedSources.remove(AnimeSources.names[which]) + } + } + .setPositiveButton("OK") { dialog, _ -> + val oldDefaultSourceIndex = getSharedPreferences( + "Dantotsu", + Context.MODE_PRIVATE + ).getInt("settings_def_anime_source_s_r", 0) + val oldName = AnimeSources.names[oldDefaultSourceIndex] + getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).edit() + .putStringSet("pinned_anime_sources", pinnedSources).apply() + AnimeSources.pinnedAnimeSources = pinnedSources + AnimeSources.performReorderAnimeSources() + val newDefaultSourceIndex = AnimeSources.names.indexOf(oldName) + getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).edit() + .putInt("settings_def_anime_source_s_r", newDefaultSourceIndex).apply() + dialog.dismiss() + } + .create() + alertDialog.show() + alertDialog.window?.setDimAmount(0.8f) + } + binding.settingsPlayer.setOnClickListener { startActivity(Intent(this, PlayerSettingsActivity::class.java)) } @@ -324,7 +364,7 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene } .setNeutralButton("Reset") { dialog, _ -> networkPreferences.defaultUserAgent() - .set("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:110.0) Gecko/20100101 Firefox/110.0") // Reset to default or empty + .set("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:110.0) Gecko/20100101 Firefox/110.0") editText.setText("") dialog.dismiss() } @@ -427,6 +467,47 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene binding.mangaSource.clearFocus() } + binding.settingsPinnedMangaSources.setOnClickListener { + val mangaSourcesWithoutDownloadsSource = MangaSources.list.filter { it.name != "Downloaded" } + val names = mangaSourcesWithoutDownloadsSource.map { it.name } + val pinnedSourcesBoolean = mangaSourcesWithoutDownloadsSource.map { it.name in MangaSources.pinnedMangaSources } + val pinnedSourcesOriginal = getSharedPreferences( + "Dantotsu", + Context.MODE_PRIVATE + ).getStringSet("pinned_manga_sources", null) + val pinnedSources = pinnedSourcesOriginal?.toMutableSet() ?: mutableSetOf() + val alertDialog = AlertDialog.Builder(this, R.style.MyPopup) + .setTitle("Pinned Manga Sources") + .setMultiChoiceItems( + names.toTypedArray(), + pinnedSourcesBoolean.toBooleanArray() + ) { _, which, isChecked -> + if (isChecked) { + pinnedSources.add(MangaSources.names[which]) + } else { + pinnedSources.remove(MangaSources.names[which]) + } + } + .setPositiveButton("OK") { dialog, _ -> + val oldDefaultSourceIndex = getSharedPreferences( + "Dantotsu", + Context.MODE_PRIVATE + ).getInt("settings_def_manga_source_s_r", 0) + val oldName = MangaSources.names[oldDefaultSourceIndex] + getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).edit() + .putStringSet("pinned_manga_sources", pinnedSources).apply() + MangaSources.pinnedMangaSources = pinnedSources + MangaSources.performReorderMangaSources() + val newDefaultSourceIndex = MangaSources.names.indexOf(oldName) + getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).edit() + .putInt("settings_def_manga_source_s_r", newDefaultSourceIndex).apply() + dialog.dismiss() + } + .create() + alertDialog.show() + alertDialog.window?.setDimAmount(0.8f) + } + binding.settingsReader.setOnClickListener { startActivity(Intent(this, ReaderSettingsActivity::class.java)) } diff --git a/app/src/main/res/drawable/ic_pin.xml b/app/src/main/res/drawable/ic_pin.xml new file mode 100644 index 00000000..ecb8624f --- /dev/null +++ b/app/src/main/res/drawable/ic_pin.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 564e3fec..1c3d5f80 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -1176,6 +1176,46 @@ tools:ignore="LabelFor,TextContrastCheck,DuplicateSpeakableTextCheck" /> + + +