diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 39c04cbe..c61e37dd 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -190,6 +190,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
1
}
} else {
- uiSettings.defaultStartUpTab
- }
+ uiSettings.defaultStartUpTab
+ }
binding.includedNavbar.navbarContainer.updateLayoutParams {
bottomMargin = navBarHeight
}
}
val offline = getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
- .getBoolean("offlineMode", false)
+ .getBoolean("offlineMode", false)
if (!isOnline(this)) {
snackString(this@MainActivity.getString(R.string.no_internet_connection))
startActivity(Intent(this, NoInternet::class.java))
} else {
- if (offline){
+ if (offline) {
snackString(this@MainActivity.getString(R.string.no_internet_connection))
startActivity(Intent(this, NoInternet::class.java))
- }
- else {
+ } else {
val model: AnilistHomeViewModel by viewModels()
model.genres.observe(this) { it ->
if (it != null) {
@@ -226,15 +225,16 @@ class MainActivity : AppCompatActivity() {
binding.mainProgressBar.visibility = View.GONE
val mainViewPager = binding.viewpager
mainViewPager.isUserInputEnabled = false
- mainViewPager.adapter = ViewPagerAdapter(supportFragmentManager, lifecycle)
+ mainViewPager.adapter =
+ ViewPagerAdapter(supportFragmentManager, lifecycle)
mainViewPager.setPageTransformer(ZoomOutPageTransformer(uiSettings))
navbar.setOnTabSelectListener(object :
- AnimatedBottomBar.OnTabSelectListener {
+ AnimatedBottomBar.OnTabSelectListener {
override fun onTabSelected(
- lastIndex: Int,
- lastTab: AnimatedBottomBar.Tab?,
- newIndex: Int,
- newTab: AnimatedBottomBar.Tab
+ lastIndex: Int,
+ lastTab: AnimatedBottomBar.Tab?,
+ newIndex: Int,
+ newTab: AnimatedBottomBar.Tab
) {
navbar.animate().translationZ(12f).setDuration(200).start()
selectedOption = newIndex
@@ -242,7 +242,12 @@ class MainActivity : AppCompatActivity() {
}
})
navbar.selectTabAt(selectedOption)
- mainViewPager.post { mainViewPager.setCurrentItem(selectedOption, false) }
+ mainViewPager.post {
+ mainViewPager.setCurrentItem(
+ selectedOption,
+ false
+ )
+ }
} else {
binding.mainProgressBar.visibility = View.GONE
}
@@ -262,8 +267,8 @@ class MainActivity : AppCompatActivity() {
if (media != null) {
media.cameFromContinue = cont
startActivity(
- Intent(this@MainActivity, MediaDetailsActivity::class.java)
- .putExtra("media", media as Serializable)
+ Intent(this@MainActivity, MediaDetailsActivity::class.java)
+ .putExtra("media", media as Serializable)
)
} else {
snackString(this@MainActivity.getString(R.string.anilist_not_found))
@@ -282,8 +287,8 @@ class MainActivity : AppCompatActivity() {
val md = "Open settings & click +Add Links & select Anilist & Mal urls"
addView(TextView(this@MainActivity).apply {
val markWon =
- Markwon.builder(this@MainActivity)
- .usePlugin(SoftBreakAddsNewLinePlugin.create()).build()
+ Markwon.builder(this@MainActivity)
+ .usePlugin(SoftBreakAddsNewLinePlugin.create()).build()
markWon.setMarkdown(this, md)
})
@@ -296,8 +301,8 @@ class MainActivity : AppCompatActivity() {
saveData("allow_opening_links", true, this@MainActivity)
tryWith(true) {
startActivity(
- Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS)
- .setData(Uri.parse("package:$packageName"))
+ Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS)
+ .setData(Uri.parse("package:$packageName"))
)
}
}
diff --git a/app/src/main/java/ani/dantotsu/media/MediaDetailsActivity.kt b/app/src/main/java/ani/dantotsu/media/MediaDetailsActivity.kt
index 3952e2cc..6a693ce1 100644
--- a/app/src/main/java/ani/dantotsu/media/MediaDetailsActivity.kt
+++ b/app/src/main/java/ani/dantotsu/media/MediaDetailsActivity.kt
@@ -10,7 +10,6 @@ import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
-import android.view.WindowManager
import android.view.animation.AccelerateDecelerateInterpolator
import android.widget.ImageView
import androidx.activity.viewModels
diff --git a/app/src/main/java/ani/dantotsu/media/anime/AnimeNameAdapter.kt b/app/src/main/java/ani/dantotsu/media/anime/AnimeNameAdapter.kt
index 6e69a17c..1a46e6c3 100644
--- a/app/src/main/java/ani/dantotsu/media/anime/AnimeNameAdapter.kt
+++ b/app/src/main/java/ani/dantotsu/media/anime/AnimeNameAdapter.kt
@@ -43,7 +43,8 @@ class AnimeNameAdapter {
text
}
return if (removedNumber.equals(text, true)) {
- val failedEpisodeNumberPattern: Regex = Regex(failedEpisodeNumberRegex, RegexOption.IGNORE_CASE)
+ val failedEpisodeNumberPattern: Regex =
+ Regex(failedEpisodeNumberRegex, RegexOption.IGNORE_CASE)
failedEpisodeNumberPattern.replace(removedNumber) { mr ->
mr.value.replaceFirst(mr.groupValues[1], "")
}.ifEmpty { removedNumber }
@@ -58,7 +59,8 @@ class AnimeNameAdapter {
text
}
return if (removedNumber.equals(text, true)) {
- val failedEpisodeNumberPattern: Regex = Regex(failedEpisodeNumberRegex, RegexOption.IGNORE_CASE)
+ val failedEpisodeNumberPattern: Regex =
+ Regex(failedEpisodeNumberRegex, RegexOption.IGNORE_CASE)
failedEpisodeNumberPattern.replace(removedNumber) { mr ->
mr.value.replaceFirst(mr.groupValues[1], "")
}.ifEmpty { removedNumber }
diff --git a/app/src/main/java/ani/dantotsu/media/anime/AnimeWatchAdapter.kt b/app/src/main/java/ani/dantotsu/media/anime/AnimeWatchAdapter.kt
index cf605c4e..b7d9c016 100644
--- a/app/src/main/java/ani/dantotsu/media/anime/AnimeWatchAdapter.kt
+++ b/app/src/main/java/ani/dantotsu/media/anime/AnimeWatchAdapter.kt
@@ -12,6 +12,7 @@ import android.widget.ImageButton
import android.widget.LinearLayout
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
+import androidx.core.content.ContextCompat.startActivity
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import ani.dantotsu.*
@@ -22,12 +23,14 @@ import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsActivity
import ani.dantotsu.media.SourceSearchDialogFragment
import ani.dantotsu.others.LanguageMapper
+import ani.dantotsu.others.webview.CookieCatcher
import ani.dantotsu.parsers.AnimeSources
import ani.dantotsu.parsers.DynamicAnimeParser
import ani.dantotsu.parsers.WatchSources
import ani.dantotsu.subcriptions.Notifications.Companion.openSettings
import ani.dantotsu.subcriptions.Subscription.Companion.getChannelId
import com.google.android.material.chip.Chip
+import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
@@ -86,8 +89,12 @@ class AnimeWatchAdapter(
null
)
}
- val offline = if (!isOnline(binding.root.context) || currContext()?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
- ?.getBoolean("offlineMode", false) == true) View.GONE else View.VISIBLE
+ val offline = if (!isOnline(binding.root.context) || currContext()?.getSharedPreferences(
+ "Dantotsu",
+ Context.MODE_PRIVATE
+ )
+ ?.getBoolean("offlineMode", false) == true
+ ) View.GONE else View.VISIBLE
binding.animeSourceNameContainer.visibility = offline
binding.animeSourceSettings.visibility = offline
@@ -188,7 +195,7 @@ class AnimeWatchAdapter(
val dialogView =
LayoutInflater.from(fragment.requireContext()).inflate(R.layout.dialog_layout, null)
val dialogBinding = DialogLayoutBinding.bind(dialogView)
-
+ var refresh = false
var run = false
var reversed = media.selected!!.recyclerReversed
var style = media.selected!!.recyclerStyle ?: fragment.uiSettings.animeDefaultView
@@ -237,6 +244,21 @@ class AnimeWatchAdapter(
dialogBinding.layoutText.text = "Compact"
run = true
}
+ dialogBinding.animeWebviewContainer.setOnClickListener {
+ //start CookieCatcher activity
+ if (watchSources.names.isNotEmpty() && source in 0 until watchSources.names.size) {
+ val sourceAHH = watchSources[source] as? DynamicAnimeParser
+ val sourceHttp =
+ sourceAHH?.extension?.sources?.firstOrNull() as? AnimeHttpSource
+ val url = sourceHttp?.baseUrl
+ url?.let {
+ refresh = true
+ val intent = Intent(fragment.requireContext(), CookieCatcher::class.java)
+ .putExtra("url", url)
+ startActivity(fragment.requireContext(), intent, null)
+ }
+ }
+ }
//hidden
dialogBinding.animeScanlatorContainer.visibility = View.GONE
@@ -247,8 +269,13 @@ class AnimeWatchAdapter(
.setView(dialogView)
.setPositiveButton("OK") { _, _ ->
if (run) fragment.onIconPressed(style, reversed)
+ if (refresh) fragment.loadEpisodes(source, true)
}
.setNegativeButton("Cancel") { _, _ ->
+ if (refresh) fragment.loadEpisodes(source, true)
+ }
+ .setOnCancelListener {
+ if (refresh) fragment.loadEpisodes(source, true)
}
.create()
nestedDialog?.show()
@@ -410,7 +437,8 @@ class AnimeWatchAdapter(
)
val items = adapter.count
- binding?.animeSourceLanguageContainer?.visibility = if (items > 1) View.VISIBLE else View.GONE
+ binding?.animeSourceLanguageContainer?.visibility =
+ if (items > 1) View.VISIBLE else View.GONE
binding?.animeSourceLanguage?.setAdapter(adapter)
}
diff --git a/app/src/main/java/ani/dantotsu/media/anime/EpisodeAdapters.kt b/app/src/main/java/ani/dantotsu/media/anime/EpisodeAdapters.kt
index 1cb514ce..686a2c8b 100644
--- a/app/src/main/java/ani/dantotsu/media/anime/EpisodeAdapters.kt
+++ b/app/src/main/java/ani/dantotsu/media/anime/EpisodeAdapters.kt
@@ -11,7 +11,6 @@ import androidx.annotation.OptIn
import androidx.core.content.ContextCompat
import androidx.lifecycle.coroutineScope
import androidx.media3.common.util.UnstableApi
-import androidx.media3.exoplayer.offline.Download
import androidx.media3.exoplayer.offline.DownloadIndex
import androidx.recyclerview.widget.RecyclerView
import ani.dantotsu.*
@@ -63,6 +62,7 @@ class EpisodeAdapter(
index = Helper.downloadManager(fragment.requireContext()).downloadIndex
}
}
+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return (when (viewType) {
0 -> EpisodeListViewHolder(
@@ -248,7 +248,10 @@ class EpisodeAdapter(
// Find the position of the chapter and notify only that item
val position = arr.indexOfFirst { it.number == episodeNumber }
if (position != -1) {
- val taskName = AnimeDownloaderService.AnimeDownloadTask.getTaskName(media.mainName(), episodeNumber)
+ val taskName = AnimeDownloaderService.AnimeDownloadTask.getTaskName(
+ media.mainName(),
+ episodeNumber
+ )
val id = fragment.requireContext().getSharedPreferences(
ContextCompat.getString(fragment.requireContext(), R.string.anime_downloads),
Context.MODE_PRIVATE
@@ -323,6 +326,7 @@ class EpisodeAdapter(
inner class EpisodeListViewHolder(val binding: ItemEpisodeListBinding) :
RecyclerView.ViewHolder(binding.root) {
private val activeCoroutines = mutableSetOf()
+
init {
itemView.setOnClickListener {
if (bindingAdapterPosition < arr.size && bindingAdapterPosition >= 0)
diff --git a/app/src/main/java/ani/dantotsu/media/manga/MangaReadAdapter.kt b/app/src/main/java/ani/dantotsu/media/manga/MangaReadAdapter.kt
index 290491ec..b1e8ee0a 100644
--- a/app/src/main/java/ani/dantotsu/media/manga/MangaReadAdapter.kt
+++ b/app/src/main/java/ani/dantotsu/media/manga/MangaReadAdapter.kt
@@ -3,6 +3,7 @@ package ani.dantotsu.media.manga
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.Context
+import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -23,12 +24,14 @@ import ani.dantotsu.media.MediaDetailsActivity
import ani.dantotsu.media.SourceSearchDialogFragment
import ani.dantotsu.media.anime.handleProgress
import ani.dantotsu.others.LanguageMapper
+import ani.dantotsu.others.webview.CookieCatcher
import ani.dantotsu.parsers.DynamicMangaParser
import ani.dantotsu.parsers.MangaReadSources
import ani.dantotsu.parsers.MangaSources
import ani.dantotsu.subcriptions.Notifications.Companion.openSettings
import ani.dantotsu.subcriptions.Subscription.Companion.getChannelId
import com.google.android.material.chip.Chip
+import eu.kanade.tachiyomi.source.online.HttpSource
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
@@ -65,8 +68,12 @@ class MangaReadAdapter(
null
)
}
- val offline = if (!isOnline(binding.root.context) || currContext()?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
- ?.getBoolean("offlineMode", false) == true) View.GONE else View.VISIBLE
+ val offline = if (!isOnline(binding.root.context) || currContext()?.getSharedPreferences(
+ "Dantotsu",
+ Context.MODE_PRIVATE
+ )
+ ?.getBoolean("offlineMode", false) == true
+ ) View.GONE else View.VISIBLE
binding.animeSourceNameContainer.visibility = offline
binding.animeSourceSettings.visibility = offline
@@ -149,9 +156,10 @@ class MangaReadAdapter(
binding.animeNestedButton.setOnClickListener {
- val dialogView = LayoutInflater.from(fragment.requireContext()).inflate(R.layout.dialog_layout, null)
+ val dialogView =
+ LayoutInflater.from(fragment.requireContext()).inflate(R.layout.dialog_layout, null)
val dialogBinding = DialogLayoutBinding.bind(dialogView)
-
+ var refresh = false
var run = false
var reversed = media.selected!!.recyclerReversed
var style = media.selected!!.recyclerStyle ?: fragment.uiSettings.animeDefaultView
@@ -194,6 +202,20 @@ class MangaReadAdapter(
dialogBinding.layoutText.text = "Compact"
run = true
}
+ dialogBinding.animeWebviewContainer.setOnClickListener {
+ //start CookieCatcher activity
+ if (mangaReadSources.names.isNotEmpty() && source in 0 until mangaReadSources.names.size) {
+ val sourceAHH = mangaReadSources[source] as? DynamicMangaParser
+ val sourceHttp = sourceAHH?.extension?.sources?.firstOrNull() as? HttpSource
+ val url = sourceHttp?.baseUrl
+ url?.let {
+ refresh = true
+ val intent = Intent(fragment.requireContext(), CookieCatcher::class.java)
+ .putExtra("url", url)
+ ContextCompat.startActivity(fragment.requireContext(), intent, null)
+ }
+ }
+ }
//Multi download
dialogBinding.downloadNo.text = "0"
@@ -216,7 +238,8 @@ class MangaReadAdapter(
}
//Scanlator
- dialogBinding.animeScanlatorContainer.visibility = if (options.count() > 1) View.VISIBLE else View.GONE
+ dialogBinding.animeScanlatorContainer.visibility =
+ if (options.count() > 1) View.VISIBLE else View.GONE
dialogBinding.scanlatorNo.text = "${options.count()}"
dialogBinding.animeScanlatorTop.setOnClickListener {
val dialogView2 =
@@ -267,8 +290,13 @@ class MangaReadAdapter(
if (dialogBinding.downloadNo.text != "0") {
fragment.multiDownload(dialogBinding.downloadNo.text.toString().toInt())
}
+ if (refresh) fragment.loadChapters(source, true)
}
.setNegativeButton("Cancel") { _, _ ->
+ if (refresh) fragment.loadChapters(source, true)
+ }
+ .setOnCancelListener {
+ if (refresh) fragment.loadChapters(source, true)
}
.create()
nestedDialog?.show()
@@ -437,7 +465,8 @@ class MangaReadAdapter(
parser.extension.sources.map { LanguageMapper.mapLanguageCodeToName(it.lang) }
)
val items = adapter.count
- binding?.animeSourceLanguageContainer?.visibility = if (items > 1) View.VISIBLE else View.GONE
+ binding?.animeSourceLanguageContainer?.visibility =
+ if (items > 1) View.VISIBLE else View.GONE
binding?.animeSourceLanguage?.setAdapter(adapter)
diff --git a/app/src/main/java/ani/dantotsu/others/webview/CookieCatcher.kt b/app/src/main/java/ani/dantotsu/others/webview/CookieCatcher.kt
new file mode 100644
index 00000000..d1f3635e
--- /dev/null
+++ b/app/src/main/java/ani/dantotsu/others/webview/CookieCatcher.kt
@@ -0,0 +1,60 @@
+package ani.dantotsu.others.webview
+
+import android.annotation.SuppressLint
+import android.app.Application
+import android.os.Build
+import android.os.Bundle
+import android.webkit.CookieManager
+import android.webkit.WebResourceRequest
+import android.webkit.WebView
+import android.webkit.WebViewClient
+import androidx.appcompat.app.AppCompatActivity
+import ani.dantotsu.R
+import ani.dantotsu.themes.ThemeManager
+import eu.kanade.tachiyomi.network.NetworkHelper
+import uy.kohesive.injekt.Injekt
+import uy.kohesive.injekt.api.get
+
+class CookieCatcher : AppCompatActivity() {
+ @SuppressLint("SetJavaScriptEnabled")
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ ThemeManager(this).applyTheme()
+
+ //get url from intent
+ val url = intent.getStringExtra("url") ?: "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+ val process = Application.getProcessName()
+ if (packageName != process) WebView.setDataDirectorySuffix(process)
+ }
+ setContentView(R.layout.activity_discord)
+
+ val webView = findViewById(R.id.discordWebview)
+
+ val cookies: CookieManager = Injekt.get().cookieJar.manager
+ cookies.setAcceptThirdPartyCookies(webView, true)
+
+ webView.apply {
+ settings.javaScriptEnabled = true
+ settings.databaseEnabled = true
+ settings.domStorageEnabled = true
+ }
+ WebView.setWebContentsDebuggingEnabled(true)
+ webView.webViewClient = object : WebViewClient() {
+ override fun shouldOverrideUrlLoading(
+ view: WebView?,
+ request: WebResourceRequest?
+ ): Boolean {
+ return super.shouldOverrideUrlLoading(view, request)
+ }
+
+ override fun onPageFinished(view: WebView?, url: String?) {
+ super.onPageFinished(view, url)
+ }
+ }
+
+ webView.loadUrl(url)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/ani/dantotsu/others/webview/WebViewBottomDialog.kt b/app/src/main/java/ani/dantotsu/others/webview/WebViewBottomDialog.kt
index 257a703c..489c68fc 100644
--- a/app/src/main/java/ani/dantotsu/others/webview/WebViewBottomDialog.kt
+++ b/app/src/main/java/ani/dantotsu/others/webview/WebViewBottomDialog.kt
@@ -11,6 +11,9 @@ import ani.dantotsu.BottomSheetDialogFragment
import ani.dantotsu.FileUrl
import ani.dantotsu.databinding.BottomSheetWebviewBinding
import ani.dantotsu.defaultHeaders
+import eu.kanade.tachiyomi.network.NetworkHelper
+import uy.kohesive.injekt.Injekt
+import uy.kohesive.injekt.api.get
abstract class WebViewBottomDialog : BottomSheetDialogFragment() {
@@ -30,7 +33,8 @@ abstract class WebViewBottomDialog : BottomSheetDialogFragment() {
dismiss()
}
- val cookies: CookieManager = CookieManager.getInstance()
+ val cookies: CookieManager = Injekt.get().cookieJar.manager
+ //CookieManager.getInstance()
override fun onCreateView(
inflater: LayoutInflater,
diff --git a/app/src/main/java/eu/kanade/domain/source/service/SourcePreferences.kt b/app/src/main/java/eu/kanade/domain/source/service/SourcePreferences.kt
index 22a24479..a22ee27b 100644
--- a/app/src/main/java/eu/kanade/domain/source/service/SourcePreferences.kt
+++ b/app/src/main/java/eu/kanade/domain/source/service/SourcePreferences.kt
@@ -11,15 +11,23 @@ class SourcePreferences(
// Common options
- fun sourceDisplayMode() = preferenceStore.getObject("pref_display_mode_catalogue", LibraryDisplayMode.default, LibraryDisplayMode.Serializer::serialize, LibraryDisplayMode.Serializer::deserialize)
+ fun sourceDisplayMode() = preferenceStore.getObject(
+ "pref_display_mode_catalogue",
+ LibraryDisplayMode.default,
+ LibraryDisplayMode.Serializer::serialize,
+ LibraryDisplayMode.Serializer::deserialize
+ )
- fun enabledLanguages() = preferenceStore.getStringSet("source_languages", LocaleHelper.getDefaultEnabledLanguages())
+ fun enabledLanguages() =
+ preferenceStore.getStringSet("source_languages", LocaleHelper.getDefaultEnabledLanguages())
fun showNsfwSource() = preferenceStore.getBoolean("show_nsfw_source", true)
- fun migrationSortingMode() = preferenceStore.getEnum("pref_migration_sorting", SetMigrateSorting.Mode.ALPHABETICAL)
+ fun migrationSortingMode() =
+ preferenceStore.getEnum("pref_migration_sorting", SetMigrateSorting.Mode.ALPHABETICAL)
- fun migrationSortingDirection() = preferenceStore.getEnum("pref_migration_direction", SetMigrateSorting.Direction.ASCENDING)
+ fun migrationSortingDirection() =
+ preferenceStore.getEnum("pref_migration_direction", SetMigrateSorting.Direction.ASCENDING)
fun trustedSignatures() = preferenceStore.getStringSet("trusted_signatures", emptySet())
@@ -37,12 +45,17 @@ class SourcePreferences(
fun animeExtensionUpdatesCount() = preferenceStore.getInt("animeext_updates_count", 0)
fun mangaExtensionUpdatesCount() = preferenceStore.getInt("ext_updates_count", 0)
- fun searchPinnedAnimeSourcesOnly() = preferenceStore.getBoolean("search_pinned_anime_sources_only", false)
- fun searchPinnedMangaSourcesOnly() = preferenceStore.getBoolean("search_pinned_sources_only", false)
+ fun searchPinnedAnimeSourcesOnly() =
+ preferenceStore.getBoolean("search_pinned_anime_sources_only", false)
- fun hideInAnimeLibraryItems() = preferenceStore.getBoolean("browse_hide_in_anime_library_items", false)
+ fun searchPinnedMangaSourcesOnly() =
+ preferenceStore.getBoolean("search_pinned_sources_only", false)
- fun hideInMangaLibraryItems() = preferenceStore.getBoolean("browse_hide_in_library_items", false)
+ fun hideInAnimeLibraryItems() =
+ preferenceStore.getBoolean("browse_hide_in_anime_library_items", false)
+
+ fun hideInMangaLibraryItems() =
+ preferenceStore.getBoolean("browse_hide_in_library_items", false)
// SY -->
@@ -62,7 +75,8 @@ class SourcePreferences(
fun dataSaverImageQuality() = preferenceStore.getInt("data_saver_image_quality", 80)
- fun dataSaverImageFormatJpeg() = preferenceStore.getBoolean("data_saver_image_format_jpeg", false)
+ fun dataSaverImageFormatJpeg() =
+ preferenceStore.getBoolean("data_saver_image_format_jpeg", false)
fun dataSaverServer() = preferenceStore.getString("data_saver_server", "")
diff --git a/app/src/main/java/eu/kanade/tachiyomi/animesource/model/AnimeFilter.kt b/app/src/main/java/eu/kanade/tachiyomi/animesource/model/AnimeFilter.kt
index e19c2b79..b3cf58d5 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/animesource/model/AnimeFilter.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/animesource/model/AnimeFilter.kt
@@ -3,10 +3,15 @@ package eu.kanade.tachiyomi.animesource.model
sealed class AnimeFilter(val name: String, var state: T) {
open class Header(name: String) : AnimeFilter(name, 0)
open class Separator(name: String = "") : AnimeFilter(name, 0)
- abstract class Select(name: String, val values: Array, state: Int = 0) : AnimeFilter(name, state)
+ abstract class Select(name: String, val values: Array, state: Int = 0) :
+ AnimeFilter(name, state)
+
abstract class Text(name: String, state: String = "") : AnimeFilter(name, state)
- abstract class CheckBox(name: String, state: Boolean = false) : AnimeFilter(name, state)
- abstract class TriState(name: String, state: Int = STATE_IGNORE) : AnimeFilter(name, state) {
+ abstract class CheckBox(name: String, state: Boolean = false) :
+ AnimeFilter(name, state)
+
+ abstract class TriState(name: String, state: Int = STATE_IGNORE) :
+ AnimeFilter(name, state) {
fun isIgnored() = state == STATE_IGNORE
fun isIncluded() = state == STATE_INCLUDE
fun isExcluded() = state == STATE_EXCLUDE
diff --git a/app/src/main/java/eu/kanade/tachiyomi/animesource/online/AnimeHttpSource.kt b/app/src/main/java/eu/kanade/tachiyomi/animesource/online/AnimeHttpSource.kt
index f8a38196..197be008 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/animesource/online/AnimeHttpSource.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/animesource/online/AnimeHttpSource.kt
@@ -50,7 +50,8 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
override val id by lazy {
val key = "${name.lowercase()}/$lang/$versionId"
val bytes = MessageDigest.getInstance("MD5").digest(key.toByteArray())
- (0..7).map { bytes[it].toLong() and 0xff shl 8 * (7 - it) }.reduce(Long::or) and Long.MAX_VALUE
+ (0..7).map { bytes[it].toLong() and 0xff shl 8 * (7 - it) }
+ .reduce(Long::or) and Long.MAX_VALUE
}
/**
@@ -112,7 +113,11 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
* @param query the search query.
* @param filters the list of filters to apply.
*/
- override fun fetchSearchAnime(page: Int, query: String, filters: AnimeFilterList): Observable {
+ override fun fetchSearchAnime(
+ page: Int,
+ query: String,
+ filters: AnimeFilterList
+ ): Observable {
return Observable.defer {
try {
client.newCall(searchAnimeRequest(page, query, filters)).asObservableSuccess()
@@ -134,7 +139,11 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
* @param query the search query.
* @param filters the list of filters to apply.
*/
- protected abstract fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request
+ protected abstract fun searchAnimeRequest(
+ page: Int,
+ query: String,
+ filters: AnimeFilterList
+ ): Request
/**
* Parses the response from the site and returns a [AnimesPage] object.
@@ -311,7 +320,12 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
val animeDownloadClient = client.newBuilder()
.callTimeout(30, TimeUnit.MINUTES)
.build()
- return animeDownloadClient.newCachelessCallWithProgress(videoRequest(video, video.totalBytesDownloaded), video)
+ return animeDownloadClient.newCachelessCallWithProgress(
+ videoRequest(
+ video,
+ video.totalBytesDownloaded
+ ), video
+ )
.asObservableSuccess()
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/anime/installer/PackageInstallerInstallerAnime.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/anime/installer/PackageInstallerInstallerAnime.kt
index b1fd050b..ffa12c70 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/extension/anime/installer/PackageInstallerInstallerAnime.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/extension/anime/installer/PackageInstallerInstallerAnime.kt
@@ -23,7 +23,10 @@ class PackageInstallerInstallerAnime(private val service: Service) : InstallerAn
private val packageActionReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
- when (intent.getIntExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE)) {
+ when (intent.getIntExtra(
+ PackageInstaller.EXTRA_STATUS,
+ PackageInstaller.STATUS_FAILURE
+ )) {
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
val userAction = intent.getParcelableExtraCompat(Intent.EXTRA_INTENT)
if (userAction == null) {
@@ -34,9 +37,11 @@ class PackageInstallerInstallerAnime(private val service: Service) : InstallerAn
userAction.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
service.startActivity(userAction)
}
+
PackageInstaller.STATUS_FAILURE_ABORTED -> {
continueQueue(InstallStep.Idle)
}
+
PackageInstaller.STATUS_SUCCESS -> continueQueue(InstallStep.Installed)
else -> continueQueue(InstallStep.Error)
}
@@ -52,7 +57,8 @@ class PackageInstallerInstallerAnime(private val service: Service) : InstallerAn
super.processEntry(entry)
activeSession = null
try {
- val installParams = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)
+ val installParams =
+ PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
installParams.setRequireUserAction(PackageInstaller.SessionParams.USER_ACTION_NOT_REQUIRED)
}
@@ -60,7 +66,8 @@ class PackageInstallerInstallerAnime(private val service: Service) : InstallerAn
val fileSize = service.getUriSize(entry.uri) ?: throw IllegalStateException()
installParams.setSize(fileSize)
- val inputStream = service.contentResolver.openInputStream(entry.uri) ?: throw IllegalStateException()
+ val inputStream =
+ service.contentResolver.openInputStream(entry.uri) ?: throw IllegalStateException()
val session = packageInstaller.openSession(activeSession!!.second)
val outputStream = session.openWrite(entry.downloadId.toString(), 0, fileSize)
session.use {
@@ -82,7 +89,10 @@ class PackageInstallerInstallerAnime(private val service: Service) : InstallerAn
session.commit(intentSender)
}
} catch (e: Exception) {
- logcat(LogPriority.ERROR, e) { "Failed to install extension ${entry.downloadId} ${entry.uri}" }
+ logcat(
+ LogPriority.ERROR,
+ e
+ ) { "Failed to install extension ${entry.downloadId} ${entry.uri}" }
logcat(LogPriority.ERROR) { "Exception: $e" }
snackString("Failed to install extension ${entry.downloadId} ${entry.uri}")
activeSession?.let { (_, sessionId) ->
@@ -108,7 +118,12 @@ class PackageInstallerInstallerAnime(private val service: Service) : InstallerAn
}
init {
- ContextCompat.registerReceiver(service, packageActionReceiver, IntentFilter(INSTALL_ACTION), ContextCompat.RECEIVER_EXPORTED)
+ ContextCompat.registerReceiver(
+ service,
+ packageActionReceiver,
+ IntentFilter(INSTALL_ACTION),
+ ContextCompat.RECEIVER_EXPORTED
+ )
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/anime/util/AnimeExtensionInstallService.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/anime/util/AnimeExtensionInstallService.kt
index fd5353f0..e70cd5e5 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/extension/anime/util/AnimeExtensionInstallService.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/extension/anime/util/AnimeExtensionInstallService.kt
@@ -7,8 +7,8 @@ import android.content.pm.ServiceInfo
import android.net.Uri
import android.os.Build
import android.os.IBinder
-import eu.kanade.domain.base.BasePreferences
import ani.dantotsu.R
+import eu.kanade.domain.base.BasePreferences
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.extension.anime.installer.InstallerAnime
import eu.kanade.tachiyomi.extension.anime.installer.PackageInstallerInstallerAnime
@@ -32,8 +32,12 @@ class AnimeExtensionInstallService : Service() {
setProgress(100, 100, true)
}.build()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- startForeground(Notifications.ID_EXTENSION_INSTALLER, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
- }else{
+ startForeground(
+ Notifications.ID_EXTENSION_INSTALLER,
+ notification,
+ ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
+ )
+ } else {
startForeground(Notifications.ID_EXTENSION_INSTALLER, notification)
}
}
@@ -51,7 +55,10 @@ class AnimeExtensionInstallService : Service() {
if (installer == null) {
installer = when (installerUsed) {
- BasePreferences.ExtensionInstaller.PACKAGEINSTALLER -> PackageInstallerInstallerAnime(this)
+ BasePreferences.ExtensionInstaller.PACKAGEINSTALLER -> PackageInstallerInstallerAnime(
+ this
+ )
+
else -> {
logcat(LogPriority.ERROR) { "Not implemented for installer $installerUsed" }
stopSelf()
diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/anime/util/AnimeExtensionLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/anime/util/AnimeExtensionLoader.kt
index 745366ed..cce7b7e9 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/extension/anime/util/AnimeExtensionLoader.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/extension/anime/util/AnimeExtensionLoader.kt
@@ -41,15 +41,18 @@ internal object AnimeExtensionLoader {
const val LIB_VERSION_MIN = 12
const val LIB_VERSION_MAX = 15
- private const val PACKAGE_FLAGS = PackageManager.GET_CONFIGURATIONS or PackageManager.GET_SIGNATURES
+ private const val PACKAGE_FLAGS =
+ PackageManager.GET_CONFIGURATIONS or PackageManager.GET_SIGNATURES
// jmir1's key
- private const val officialSignature = "50ab1d1e3a20d204d0ad6d334c7691c632e41b98dfa132bf385695fdfa63839c"
+ private const val officialSignature =
+ "50ab1d1e3a20d204d0ad6d334c7691c632e41b98dfa132bf385695fdfa63839c"
/**
* List of the trusted signatures.
*/
- var trustedSignatures = mutableSetOf() + preferences.trustedSignatures().get() + officialSignature
+ var trustedSignatures =
+ mutableSetOf() + preferences.trustedSignatures().get() + officialSignature
/**
* Return a list of all the installed extensions initialized concurrently.
@@ -105,7 +108,11 @@ internal object AnimeExtensionLoader {
* @param pkgName The package name of the extension to load.
* @param pkgInfo The package info of the extension.
*/
- private fun loadExtension(context: Context, pkgName: String, pkgInfo: PackageInfo): AnimeLoadResult {
+ private fun loadExtension(
+ context: Context,
+ pkgName: String,
+ pkgInfo: PackageInfo
+ ): AnimeLoadResult {
val pkgManager = context.packageManager
val appInfo = try {
@@ -141,7 +148,14 @@ internal object AnimeExtensionLoader {
logcat(LogPriority.WARN) { "Package $pkgName isn't signed" }
return AnimeLoadResult.Error
} else if (signatureHash !in trustedSignatures) {
- val extension = AnimeExtension.Untrusted(extName, pkgName, versionName, versionCode, libVersion, signatureHash)
+ val extension = AnimeExtension.Untrusted(
+ extName,
+ pkgName,
+ versionName,
+ versionCode,
+ libVersion,
+ signatureHash
+ )
logcat(LogPriority.WARN, message = { "Extension $pkgName isn't trusted" })
return AnimeLoadResult.Untrusted(extension)
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/manga/MangaExtensionManager.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/manga/MangaExtensionManager.kt
index 260af47c..fe098455 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/extension/manga/MangaExtensionManager.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/extension/manga/MangaExtensionManager.kt
@@ -13,7 +13,6 @@ import eu.kanade.tachiyomi.extension.manga.util.MangaExtensionInstallReceiver
import eu.kanade.tachiyomi.extension.manga.util.MangaExtensionInstaller
import eu.kanade.tachiyomi.extension.manga.util.MangaExtensionLoader
import eu.kanade.tachiyomi.util.preference.plusAssign
-import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -63,9 +62,11 @@ class MangaExtensionManager(
private var subLanguagesEnabledOnFirstRun = preferences.enabledLanguages().isSet()
fun getAppIconForSource(sourceId: Long): Drawable? {
- val pkgName = _installedExtensionsFlow.value.find { ext -> ext.sources.any { it.id == sourceId } }?.pkgName
+ val pkgName =
+ _installedExtensionsFlow.value.find { ext -> ext.sources.any { it.id == sourceId } }?.pkgName
if (pkgName != null) {
- return iconMap[pkgName] ?: iconMap.getOrPut(pkgName) { context.packageManager.getApplicationIcon(pkgName) }
+ return iconMap[pkgName]
+ ?: iconMap.getOrPut(pkgName) { context.packageManager.getApplicationIcon(pkgName) }
}
return null
}
@@ -257,14 +258,20 @@ class MangaExtensionManager(
MangaExtensionLoader.trustedSignatures += signature
preferences.trustedSignatures() += signature
- val nowTrustedExtensions = _untrustedExtensionsFlow.value.filter { it.signatureHash == signature }
+ val nowTrustedExtensions =
+ _untrustedExtensionsFlow.value.filter { it.signatureHash == signature }
_untrustedExtensionsFlow.value -= nowTrustedExtensions
val ctx = context
launchNow {
nowTrustedExtensions
.map { extension ->
- async { MangaExtensionLoader.loadMangaExtensionFromPkgName(ctx, extension.pkgName) }
+ async {
+ MangaExtensionLoader.loadMangaExtensionFromPkgName(
+ ctx,
+ extension.pkgName
+ )
+ }
}
.map { it.await() }
.forEach { result ->
@@ -354,13 +361,15 @@ class MangaExtensionManager(
}
private fun MangaExtension.Installed.updateExists(availableExtension: MangaExtension.Available? = null): Boolean {
- val availableExt = availableExtension ?: _availableExtensionsFlow.value.find { it.pkgName == pkgName }
+ val availableExt =
+ availableExtension ?: _availableExtensionsFlow.value.find { it.pkgName == pkgName }
if (isUnofficial || availableExt == null) return false
return (availableExt.versionCode > versionCode || availableExt.libVersion > libVersion)
}
private fun updatePendingUpdatesCount() {
- preferences.mangaExtensionUpdatesCount().set(_installedExtensionsFlow.value.count { it.hasUpdate })
+ preferences.mangaExtensionUpdatesCount()
+ .set(_installedExtensionsFlow.value.count { it.hasUpdate })
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/manga/util/MangaExtensionInstaller.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/manga/util/MangaExtensionInstaller.kt
index 4109f9f5..f05db16c 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/extension/manga/util/MangaExtensionInstaller.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/extension/manga/util/MangaExtensionInstaller.kt
@@ -77,7 +77,11 @@ internal class MangaExtensionInstaller(private val context: Context) {
val request = DownloadManager.Request(downloadUri)
.setTitle(extension.name)
.setMimeType(APK_MIME)
- .setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, downloadUri.lastPathSegment)
+ .setDestinationInExternalFilesDir(
+ context,
+ Environment.DIRECTORY_DOWNLOADS,
+ downloadUri.lastPathSegment
+ )
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
val id = downloadManager.enqueue(request)
@@ -141,6 +145,7 @@ internal class MangaExtensionInstaller(private val context: Context) {
context.startActivity(intent)
}
+
else -> {
val intent =
MangaExtensionInstallService.getIntent(context, downloadId, uri, installer)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/AndroidCookieJar.kt b/app/src/main/java/eu/kanade/tachiyomi/network/AndroidCookieJar.kt
index f9322e84..82b04be2 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/network/AndroidCookieJar.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/network/AndroidCookieJar.kt
@@ -7,7 +7,7 @@ import okhttp3.HttpUrl
class AndroidCookieJar : CookieJar {
- private val manager = CookieManager.getInstance()
+ val manager = CookieManager.getInstance()
override fun saveFromResponse(url: HttpUrl, cookies: List) {
val urlString = url.toString()
diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/NetworkPreferences.kt b/app/src/main/java/eu/kanade/tachiyomi/network/NetworkPreferences.kt
index fa0eab88..1dce7afd 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/network/NetworkPreferences.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/network/NetworkPreferences.kt
@@ -17,6 +17,9 @@ class NetworkPreferences(
}
fun defaultUserAgent(): Preference {
- return preferenceStore.getString("default_user_agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:110.0) Gecko/20100101 Firefox/110.0")
+ return preferenceStore.getString(
+ "default_user_agent",
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:110.0) Gecko/20100101 Firefox/110.0"
+ )
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt b/app/src/main/java/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt
index 2d8202ea..0beba7cb 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt
@@ -30,7 +30,11 @@ class CloudflareInterceptor(
return response.code in ERROR_CODES && response.header("Server") in SERVER_CHECK
}
- override fun intercept(chain: Interceptor.Chain, request: Request, response: Response): Response {
+ override fun intercept(
+ chain: Interceptor.Chain,
+ request: Request,
+ response: Response
+ ): Response {
try {
response.close()
cookieManager.remove(request.url, COOKIE_NAMES, 0)
@@ -125,7 +129,10 @@ class CloudflareInterceptor(
if (!cloudflareBypassed) {
// Prompt user to update WebView if it seems too outdated
if (isWebViewOutdated) {
- context.toast("Please update the webview app for better compatibility", Toast.LENGTH_LONG)
+ context.toast(
+ "Please update the webview app for better compatibility",
+ Toast.LENGTH_LONG
+ )
}
throw CloudflareBypassException()
diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/HttpSource.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/HttpSource.kt
index d0aa5b2d..16fd9935 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/source/online/HttpSource.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/HttpSource.kt
@@ -50,7 +50,8 @@ abstract class HttpSource : CatalogueSource {
override val id by lazy {
val key = "${name.lowercase()}/$lang/$versionId"
val bytes = MessageDigest.getInstance("MD5").digest(key.toByteArray())
- (0..7).map { bytes[it].toLong() and 0xff shl 8 * (7 - it) }.reduce(Long::or) and Long.MAX_VALUE
+ (0..7).map { bytes[it].toLong() and 0xff shl 8 * (7 - it) }
+ .reduce(Long::or) and Long.MAX_VALUE
}
/**
@@ -112,7 +113,11 @@ abstract class HttpSource : CatalogueSource {
* @param query the search query.
* @param filters the list of filters to apply.
*/
- override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable {
+ override fun fetchSearchManga(
+ page: Int,
+ query: String,
+ filters: FilterList
+ ): Observable {
return Observable.defer {
try {
client.newCall(searchMangaRequest(page, query, filters)).asObservableSuccess()
@@ -134,7 +139,11 @@ abstract class HttpSource : CatalogueSource {
* @param query the search query.
* @param filters the list of filters to apply.
*/
- protected abstract fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request
+ protected abstract fun searchMangaRequest(
+ page: Int,
+ query: String,
+ filters: FilterList
+ ): Request
/**
* Parses the response from the site and returns a [MangasPage] object.
diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/system/NotificationExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/system/NotificationExtensions.kt
index d43d7045..67ce5a03 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/util/system/NotificationExtensions.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/util/system/NotificationExtensions.kt
@@ -16,13 +16,21 @@ import androidx.core.content.getSystemService
val Context.notificationManager: NotificationManager
get() = getSystemService()!!
-fun Context.notify(id: Int, channelId: String, block: (NotificationCompat.Builder.() -> Unit)? = null) {
+fun Context.notify(
+ id: Int,
+ channelId: String,
+ block: (NotificationCompat.Builder.() -> Unit)? = null
+) {
val notification = notificationBuilder(channelId, block).build()
this.notify(id, notification)
}
fun Context.notify(id: Int, notification: Notification) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && PermissionChecker.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PermissionChecker.PERMISSION_GRANTED) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && PermissionChecker.checkSelfPermission(
+ this,
+ Manifest.permission.POST_NOTIFICATIONS
+ ) != PermissionChecker.PERMISSION_GRANTED
+ ) {
return
}
@@ -30,7 +38,11 @@ fun Context.notify(id: Int, notification: Notification) {
}
fun Context.notify(notificationWithIdAndTags: List) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && PermissionChecker.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PermissionChecker.PERMISSION_GRANTED) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && PermissionChecker.checkSelfPermission(
+ this,
+ Manifest.permission.POST_NOTIFICATIONS
+ ) != PermissionChecker.PERMISSION_GRANTED
+ ) {
return
}
@@ -48,7 +60,10 @@ fun Context.cancelNotification(id: Int) {
* @param block the function that will execute inside the builder.
* @return a notification to be displayed or updated.
*/
-fun Context.notificationBuilder(channelId: String, block: (NotificationCompat.Builder.() -> Unit)? = null): NotificationCompat.Builder {
+fun Context.notificationBuilder(
+ channelId: String,
+ block: (NotificationCompat.Builder.() -> Unit)? = null
+): NotificationCompat.Builder {
val builder = NotificationCompat.Builder(this, channelId)
.setColor(getColor(android.R.color.holo_blue_dark))
if (block != null) {
diff --git a/app/src/main/java/tachiyomi/core/preference/Preference.kt b/app/src/main/java/tachiyomi/core/preference/Preference.kt
index c276141e..f7c428ac 100644
--- a/app/src/main/java/tachiyomi/core/preference/Preference.kt
+++ b/app/src/main/java/tachiyomi/core/preference/Preference.kt
@@ -23,4 +23,5 @@ interface Preference {
fun stateIn(scope: CoroutineScope): StateFlow
}
-inline fun Preference.getAndSet(crossinline block: (T) -> R) = set(block(get()))
+inline fun Preference.getAndSet(crossinline block: (T) -> R) =
+ set(block(get()))
diff --git a/app/src/main/java/tachiyomi/core/util/lang/CoroutinesExtensions.kt b/app/src/main/java/tachiyomi/core/util/lang/CoroutinesExtensions.kt
index 4573b2d8..d99b7eb1 100644
--- a/app/src/main/java/tachiyomi/core/util/lang/CoroutinesExtensions.kt
+++ b/app/src/main/java/tachiyomi/core/util/lang/CoroutinesExtensions.kt
@@ -52,9 +52,11 @@ fun CoroutineScope.launchIO(block: suspend CoroutineScope.() -> Unit): Job =
fun CoroutineScope.launchNonCancellable(block: suspend CoroutineScope.() -> Unit): Job =
launchIO { withContext(NonCancellable, block) }
-suspend fun withUIContext(block: suspend CoroutineScope.() -> T) = withContext(Dispatchers.Main, block)
+suspend fun withUIContext(block: suspend CoroutineScope.() -> T) =
+ withContext(Dispatchers.Main, block)
-suspend fun withIOContext(block: suspend CoroutineScope.() -> T) = withContext(Dispatchers.IO, block)
+suspend fun withIOContext(block: suspend CoroutineScope.() -> T) =
+ withContext(Dispatchers.IO, block)
suspend fun withNonCancellableContext(block: suspend CoroutineScope.() -> T) =
withContext(NonCancellable, block)
diff --git a/app/src/main/java/tachiyomi/domain/source/anime/model/StubAnimeSource.kt b/app/src/main/java/tachiyomi/domain/source/anime/model/StubAnimeSource.kt
index 7631c49c..4bc3e65a 100644
--- a/app/src/main/java/tachiyomi/domain/source/anime/model/StubAnimeSource.kt
+++ b/app/src/main/java/tachiyomi/domain/source/anime/model/StubAnimeSource.kt
@@ -30,4 +30,5 @@ class StubAnimeSource(private val sourceData: AnimeSourceData) : AnimeSource {
return if (sourceData.isMissingInfo.not()) "$name (${lang.uppercase()})" else id.toString()
}
}
+
class AnimeSourceNotInstalledException : Exception()
diff --git a/app/src/main/java/tachiyomi/domain/source/anime/repository/AnimeSourceRepository.kt b/app/src/main/java/tachiyomi/domain/source/anime/repository/AnimeSourceRepository.kt
index e8b2d372..c23fac97 100644
--- a/app/src/main/java/tachiyomi/domain/source/anime/repository/AnimeSourceRepository.kt
+++ b/app/src/main/java/tachiyomi/domain/source/anime/repository/AnimeSourceRepository.kt
@@ -19,7 +19,11 @@ interface AnimeSourceRepository {
fun getSourcesWithNonLibraryAnime(): Flow>
- fun searchAnime(sourceId: Long, query: String, filterList: AnimeFilterList): AnimeSourcePagingSourceType
+ fun searchAnime(
+ sourceId: Long,
+ query: String,
+ filterList: AnimeFilterList
+ ): AnimeSourcePagingSourceType
fun getPopularAnime(sourceId: Long): AnimeSourcePagingSourceType
diff --git a/app/src/main/res/drawable/ic_internet.xml b/app/src/main/res/drawable/ic_internet.xml
new file mode 100644
index 00000000..e7b4b2cc
--- /dev/null
+++ b/app/src/main/res/drawable/ic_internet.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/layout/dialog_layout.xml b/app/src/main/res/layout/dialog_layout.xml
index aa1d661f..e90ac449 100644
--- a/app/src/main/res/layout/dialog_layout.xml
+++ b/app/src/main/res/layout/dialog_layout.xml
@@ -6,10 +6,12 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
+
+
+
+ android:layout_weight="1" />
+
+
+
+ android:layout_gravity="center_vertical">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file