pinned sources

This commit is contained in:
rebelonion 2024-01-21 01:40:44 -06:00
parent 734c5d0571
commit a0018b5fb6
9 changed files with 226 additions and 10 deletions

View file

@ -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 {

View file

@ -338,7 +338,6 @@ class MainActivity : AppCompatActivity() {
}
}
}
}

View file

@ -220,7 +220,7 @@ class MangaReaderActivity : AppCompatActivity() {
val mangaSources = MangaSources
val scope = lifecycleScope
scope.launch(Dispatchers.IO) {
mangaSources.init(Injekt.get<MangaExtensionManager>().installedExtensionsFlow)
mangaSources.init(Injekt.get<MangaExtensionManager>().installedExtensionsFlow, this@MangaReaderActivity)
}
model.mangaReadSources = mangaSources
} else {

View file

@ -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<Lazier<BaseParser>> = emptyList()
var pinnedAnimeSources: Set<String> = emptySet()
suspend fun init(fromExtensions: StateFlow<List<AnimeExtension.Installed>>, context: Context) {
val sharedPrefs = context.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
pinnedAnimeSources = sharedPrefs.getStringSet("pinned_anime_sources", emptySet()) ?: emptySet()
suspend fun init(fromExtensions: StateFlow<List<AnimeExtension.Installed>>) {
// 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<AnimeExtension.Installed>): List<Lazier<BaseParser>> {
return extensions.map { extension ->
val name = extension.name
Lazier({ DynamicAnimeParser(extension) }, name)
}
}
private fun sortPinnedAnimeSources(Sources: List<Lazier<BaseParser>>, pinnedAnimeSources: Set<String>): List<Lazier<BaseParser>> {
//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
}
}

View file

@ -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<Lazier<BaseParser>> = emptyList()
var pinnedMangaSources: Set<String> = emptySet()
suspend fun init(fromExtensions: StateFlow<List<MangaExtension.Installed>>, context: Context) {
val sharedPrefs = context.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
pinnedMangaSources = sharedPrefs.getStringSet("pinned_manga_sources", emptySet()) ?: emptySet()
suspend fun init(fromExtensions: StateFlow<List<MangaExtension.Installed>>) {
// 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<MangaExtension.Installed>): List<Lazier<BaseParser>> {
return extensions.map { extension ->
val name = extension.name
Lazier({ DynamicMangaParser(extension) }, name)
}
}
private fun sortPinnedMangaSources(Sources: List<Lazier<BaseParser>>, pinnedMangaSources: Set<String>): List<Lazier<BaseParser>> {
//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() {

View file

@ -190,7 +190,6 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
.show(this, tag)
}
//val animeSource = loadData<Int>("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))
}

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FF000000"
android:pathData="m640,480 l80,80v80L520,640v240l-40,40 -40,-40v-240L240,640v-80l80,-80v-280h-40v-80h400v80h-40v280ZM354,560h252l-46,-46v-314L400,200v314l-46,46ZM480,560Z"/>
</vector>

View file

@ -1176,6 +1176,46 @@
tools:ignore="LabelFor,TextContrastCheck,DuplicateSpeakableTextCheck" />
</com.google.android.material.textfield.TextInputLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<Button
android:id="@+id/settingsPinnedAnimeSources"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginStart="-32dp"
android:layout_marginEnd="-32dp"
android:background="@drawable/ui_bg"
android:backgroundTint="?attr/colorSecondary"
android:backgroundTintMode="src_atop"
android:fontFamily="@font/poppins_bold"
android:insetTop="0dp"
android:insetBottom="0dp"
android:paddingStart="32dp"
android:paddingEnd="32dp"
android:text="@string/pinned_sources"
android:textAlignment="viewStart"
android:textAllCaps="false"
android:textColor="?attr/colorOnBackground"
app:cornerRadius="0dp"
app:icon="@drawable/ic_pin"
app:iconPadding="16dp"
app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:layout_marginBottom="8dp"
android:background="?android:attr/listDivider" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/settingsPreferDub"
android:layout_width="match_parent"
@ -1376,6 +1416,46 @@
tools:ignore="LabelFor,TextContrastCheck,DuplicateSpeakableTextCheck" />
</com.google.android.material.textfield.TextInputLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="-16dp"
android:background="?android:attr/listDivider" />
<Button
android:id="@+id/settingsPinnedMangaSources"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginStart="-32dp"
android:layout_marginEnd="-32dp"
android:background="@drawable/ui_bg"
android:backgroundTint="?attr/colorSecondary"
android:backgroundTintMode="src_atop"
android:fontFamily="@font/poppins_bold"
android:insetTop="0dp"
android:insetBottom="0dp"
android:paddingStart="32dp"
android:paddingEnd="32dp"
android:text="@string/pinned_sources"
android:textAlignment="viewStart"
android:textAllCaps="false"
android:textColor="?attr/colorOnBackground"
app:cornerRadius="0dp"
app:icon="@drawable/ic_pin"
app:iconPadding="16dp"
app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
android:layout_marginBottom="8dp"
android:background="?android:attr/listDivider" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"

View file

@ -653,5 +653,6 @@
<string name="purge_novel_downloads">Delete all Novel Downloads</string>
<string name="requires_android_12">Requires Android 12+</string>
<string name="share_username_in_crash_reports">Share username in crash reports</string>
<string name="pinned_sources">Pinned Sources</string>
</resources>