webview for extensions

This commit is contained in:
rebelonion 2024-01-18 01:09:11 -06:00
parent 26b6564825
commit ff02280239
29 changed files with 447 additions and 100 deletions

View file

@ -945,14 +945,19 @@ fun checkCountry(context: Context): Boolean {
}
const val INCOGNITO_CHANNEL_ID = 26
@SuppressLint("LaunchActivityFromNotification")
fun incognitoNotification(context: Context){
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val incognito = context.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).getBoolean("incognito", false)
fun incognitoNotification(context: Context) {
val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val incognito = context.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
.getBoolean("incognito", false)
if (incognito) {
val intent = Intent(context, NotificationClickReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_IMMUTABLE)
val pendingIntent = PendingIntent.getBroadcast(
context, 0, intent,
PendingIntent.FLAG_IMMUTABLE
)
val builder = NotificationCompat.Builder(context, Notifications.CHANNEL_INCOGNITO_MODE)
.setSmallIcon(R.drawable.ic_incognito_24)
.setContentTitle("Incognito Mode")

View file

@ -198,24 +198,23 @@ class MainActivity : AppCompatActivity() {
else -> 1
}
} else {
uiSettings.defaultStartUpTab
}
uiSettings.defaultStartUpTab
}
binding.includedNavbar.navbarContainer.updateLayoutParams<ViewGroup.MarginLayoutParams> {
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"))
)
}
}

View file

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

View file

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

View file

@ -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)
}

View file

@ -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<String>()
init {
itemView.setOnClickListener {
if (bindingAdapterPosition < arr.size && bindingAdapterPosition >= 0)

View file

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

View file

@ -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<WebView>(R.id.discordWebview)
val cookies: CookieManager = Injekt.get<NetworkHelper>().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)
}
}

View file

@ -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<NetworkHelper>().cookieJar.manager
//CookieManager.getInstance()
override fun onCreateView(
inflater: LayoutInflater,