Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
aayush262 2024-04-21 21:50:41 +05:30
commit c5a03c4455
17 changed files with 55 additions and 31 deletions

View file

@ -636,6 +636,23 @@ fun ImageView.loadImage(file: FileUrl?, size: Int = 0) {
} }
} }
fun ImageView.loadImage(file: FileUrl?, width: Int = 0, height: Int = 0) {
file?.url = PrefManager.getVal<String>(PrefName.ImageUrl).ifEmpty { file?.url ?: "" }
if (file?.url?.isNotEmpty() == true) {
tryWith {
if (file.url.startsWith("content://")) {
Glide.with(this.context).load(Uri.parse(file.url)).transition(withCrossFade())
.override(width, height).into(this)
} else {
val glideUrl = GlideUrl(file.url) { file.headers }
Glide.with(this.context).load(glideUrl).transition(withCrossFade()).override(width, height)
.into(this)
}
}
}
}
fun ImageView.loadLocalImage(file: File?, size: Int = 0) { fun ImageView.loadLocalImage(file: File?, size: Int = 0) {
if (file?.exists() == true) { if (file?.exists() == true) {
tryWith { tryWith {

View file

@ -79,7 +79,6 @@ class AddonDownloader {
activity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager activity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val installerSteps = InstallerSteps(notificationManager, activity) val installerSteps = InstallerSteps(notificationManager, activity)
manager.install(this) manager.install(this)
.observeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe( .subscribe(
{ installStep -> installerSteps.onInstallStep(installStep) {} }, { installStep -> installerSteps.onInstallStep(installStep) {} },

View file

@ -75,7 +75,6 @@ internal class AddonInstallReceiver : BroadcastReceiver() {
} }
Intent.ACTION_PACKAGE_REPLACED -> { Intent.ACTION_PACKAGE_REPLACED -> {
if (ExtensionInstallReceiver.isReplacing(intent)) return
launchNow { launchNow {
when (type) { when (type) {
AddonType.DOWNLOAD -> { AddonType.DOWNLOAD -> {

View file

@ -369,7 +369,7 @@ class DownloadsManager(private val context: Context) {
} }
private const val RESERVED_CHARS = "|\\?*<\":>+[]/'" private const val RESERVED_CHARS = "|\\?*<\":>+[]/'"
private fun String?.findValidName(): String { fun String?.findValidName(): String {
return this?.filterNot { RESERVED_CHARS.contains(it) } ?: "" return this?.filterNot { RESERVED_CHARS.contains(it) } ?: ""
} }

View file

@ -36,6 +36,7 @@ import ani.dantotsu.download.DownloadCompat.Companion.loadOfflineAnimeModelCompa
import ani.dantotsu.download.DownloadedType import ani.dantotsu.download.DownloadedType
import ani.dantotsu.download.DownloadsManager import ani.dantotsu.download.DownloadsManager
import ani.dantotsu.download.DownloadsManager.Companion.compareName import ani.dantotsu.download.DownloadsManager.Companion.compareName
import ani.dantotsu.download.findValidName
import ani.dantotsu.initActivity import ani.dantotsu.initActivity
import ani.dantotsu.media.Media import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsActivity import ani.dantotsu.media.MediaDetailsActivity
@ -289,7 +290,7 @@ class OfflineAnimeFragment : Fragment(), OfflineAnimeSearchListener {
} }
downloadsJob = Job() downloadsJob = Job()
CoroutineScope(Dispatchers.IO + downloadsJob).launch { CoroutineScope(Dispatchers.IO + downloadsJob).launch {
val animeTitles = downloadManager.animeDownloadedTypes.map { it.titleName }.distinct() val animeTitles = downloadManager.animeDownloadedTypes.map { it.titleName.findValidName() }.distinct()
val newAnimeDownloads = mutableListOf<OfflineAnimeModel>() val newAnimeDownloads = mutableListOf<OfflineAnimeModel>()
for (title in animeTitles) { for (title in animeTitles) {
val tDownloads = downloadManager.animeDownloadedTypes.filter { it.titleName == title } val tDownloads = downloadManager.animeDownloadedTypes.filter { it.titleName == title }
@ -365,6 +366,7 @@ class OfflineAnimeFragment : Fragment(), OfflineAnimeSearchListener {
val bannerUri: Uri? = if (banner?.exists() == true) { val bannerUri: Uri? = if (banner?.exists() == true) {
banner.uri banner.uri
} else null } else null
if (coverUri == null && bannerUri == null) throw Exception("No cover or banner found, probably compat")
val title = mediaModel.mainName() val title = mediaModel.mainName()
val score = ((if (mediaModel.userScore == 0) (mediaModel.meanScore val score = ((if (mediaModel.userScore == 0) (mediaModel.meanScore
?: 0) else mediaModel.userScore) / 10.0).toString() ?: 0) else mediaModel.userScore) / 10.0).toString()

View file

@ -34,6 +34,7 @@ import ani.dantotsu.download.DownloadedType
import ani.dantotsu.download.DownloadsManager import ani.dantotsu.download.DownloadsManager
import ani.dantotsu.download.DownloadsManager.Companion.compareName import ani.dantotsu.download.DownloadsManager.Companion.compareName
import ani.dantotsu.download.DownloadsManager.Companion.getSubDirectory import ani.dantotsu.download.DownloadsManager.Companion.getSubDirectory
import ani.dantotsu.download.findValidName
import ani.dantotsu.initActivity import ani.dantotsu.initActivity
import ani.dantotsu.media.Media import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsActivity import ani.dantotsu.media.MediaDetailsActivity
@ -280,7 +281,7 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
downloads = listOf() downloads = listOf()
downloadsJob = Job() downloadsJob = Job()
CoroutineScope(Dispatchers.IO + downloadsJob).launch { CoroutineScope(Dispatchers.IO + downloadsJob).launch {
val mangaTitles = downloadManager.mangaDownloadedTypes.map { it.titleName }.distinct() val mangaTitles = downloadManager.mangaDownloadedTypes.map { it.titleName.findValidName() }.distinct()
val newMangaDownloads = mutableListOf<OfflineMangaModel>() val newMangaDownloads = mutableListOf<OfflineMangaModel>()
for (title in mangaTitles) { for (title in mangaTitles) {
val tDownloads = downloadManager.mangaDownloadedTypes.filter { it.titleName == title } val tDownloads = downloadManager.mangaDownloadedTypes.filter { it.titleName == title }
@ -356,6 +357,7 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
val bannerUri: Uri? = if (banner?.exists() == true) { val bannerUri: Uri? = if (banner?.exists() == true) {
banner.uri banner.uri
} else null } else null
if (coverUri == null && bannerUri == null) throw Exception("No cover or banner found, probably compat")
val title = mediaModel.mainName() val title = mediaModel.mainName()
val score = ((if (mediaModel.userScore == 0) (mediaModel.meanScore val score = ((if (mediaModel.userScore == 0) (mediaModel.meanScore
?: 0) else mediaModel.userScore) / 10.0).toString() ?: 0) else mediaModel.userScore) / 10.0).toString()

View file

@ -70,7 +70,7 @@ object MediaNameAdapter {
return if (seasonMatcher.find()) { return if (seasonMatcher.find()) {
seasonMatcher.group(2)?.toInt() seasonMatcher.group(2)?.toInt()
} else { } else {
null text.toIntOrNull()
} }
} }
@ -93,7 +93,7 @@ object MediaNameAdapter {
} }
} }
} else { } else {
null text.toFloatOrNull()
} }
} }
@ -139,7 +139,7 @@ object MediaNameAdapter {
if (failedChapterNumberMatcher.find()) { if (failedChapterNumberMatcher.find()) {
failedChapterNumberMatcher.group(1)?.toFloat() failedChapterNumberMatcher.group(1)?.toFloat()
} else { } else {
null text.toFloatOrNull()
} }
} }
} }

View file

@ -305,14 +305,12 @@ class SearchAdapter(private val activity: SearchActivity, private val type: Stri
private fun fadeInAnimation(): Animation { private fun fadeInAnimation(): Animation {
return AlphaAnimation(0f, 1f).apply { return AlphaAnimation(0f, 1f).apply {
duration = 150 duration = 150
fillAfter = true
} }
} }
private fun fadeOutAnimation(): Animation { private fun fadeOutAnimation(): Animation {
return AlphaAnimation(1f, 0f).apply { return AlphaAnimation(1f, 0f).apply {
duration = 150 duration = 150
fillAfter = true
} }
} }

View file

@ -121,7 +121,6 @@ class CommentsFragment : Fragment() {
} }
} }
} else { } else {
toast("Not logged in")
activity.binding.commentMessageContainer.visibility = View.GONE activity.binding.commentMessageContainer.visibility = View.GONE
} }

View file

@ -117,9 +117,10 @@ class NovelReadFragment : Fragment(),
context ?: currContext()!!, context ?: currContext()!!,
MediaType.NOVEL, MediaType.NOVEL,
false, false,
media.mainName(),
novel.name novel.name
) )
val file = directory?.findFile(novel.name) val file = directory?.findFile("0.epub")
if (file?.exists() == false) return false if (file?.exists() == false) return false
val fileUri = file?.uri ?: return false val fileUri = file?.uri ?: return false
val intent = Intent(context, NovelReaderActivity::class.java).apply { val intent = Intent(context, NovelReaderActivity::class.java).apply {

View file

@ -8,6 +8,7 @@ import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.databinding.ItemNovelResponseBinding import ani.dantotsu.databinding.ItemNovelResponseBinding
import ani.dantotsu.loadImage
import ani.dantotsu.parsers.ShowResponse import ani.dantotsu.parsers.ShowResponse
import ani.dantotsu.setAnimation import ani.dantotsu.setAnimation
import ani.dantotsu.snackString import ani.dantotsu.snackString
@ -37,10 +38,7 @@ class NovelResponseAdapter(
val binding = holder.binding val binding = holder.binding
val novel = list[position] val novel = list[position]
setAnimation(fragment.requireContext(), holder.binding.root) setAnimation(fragment.requireContext(), holder.binding.root)
binding.itemEpisodeImage.loadImage(novel.coverUrl, 400, 0)
val cover = GlideUrl(novel.coverUrl.url) { novel.coverUrl.headers }
Glide.with(binding.itemEpisodeImage).load(cover).override(400, 0)
.into(binding.itemEpisodeImage)
val typedValue = TypedValue() val typedValue = TypedValue()
fragment.requireContext().theme?.resolveAttribute( fragment.requireContext().theme?.resolveAttribute(

View file

@ -55,12 +55,11 @@ class OfflineAnimeParser : AnimeParser() {
episodes.add(episode) episodes.add(episode)
} }
} }
return if (episodes.isNotEmpty()) { //episodes.sortBy { MediaNameAdapter.findEpisodeNumber(it.number) }
episodes.sortBy { MediaNameAdapter.findEpisodeNumber(it.number) } episodes.addAll(loadEpisodesCompat(animeLink, extra, sAnime))
episodes //filter those with the same name
} else { return episodes.distinctBy { it.number }
loadEpisodesCompat(animeLink, extra, sAnime) .sortedBy { MediaNameAdapter.findEpisodeNumber(it.number) }
}
} }
return emptyList() return emptyList()
} }

View file

@ -43,12 +43,9 @@ class OfflineMangaParser : MangaParser() {
chapters.add(chapter) chapters.add(chapter)
} }
} }
return if (chapters.isNotEmpty()) { chapters.addAll(loadChaptersCompat(mangaLink, extra, sManga))
chapters.sortBy { MediaNameAdapter.findChapterNumber(it.number) } return chapters.distinctBy { it.number }
chapters .sortedBy { MediaNameAdapter.findChapterNumber(it.number) }
} else {
loadChaptersCompat(mangaLink, extra, sManga)
}
} }
return emptyList() return emptyList()
} }

View file

@ -73,7 +73,7 @@ class OfflineNovelParser : NovelParser() {
} }
val cover = directory?.findFile("cover.jpg")?.uri.toString() val cover = directory?.findFile("cover.jpg")?.uri.toString()
names.forEach { names.forEach {
returnList.add(ShowResponse(it, it, cover)) returnList.add(ShowResponse(it, query, cover))
} }
} }
return returnList return returnList

View file

@ -10,7 +10,9 @@ import android.content.pm.PackageInstaller
import android.os.Build import android.os.Build
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.IntentSanitizer import androidx.core.content.IntentSanitizer
import ani.dantotsu.R
import ani.dantotsu.snackString import ani.dantotsu.snackString
import ani.dantotsu.toast
import ani.dantotsu.util.Logger import ani.dantotsu.util.Logger
import eu.kanade.tachiyomi.extension.InstallStep import eu.kanade.tachiyomi.extension.InstallStep
import eu.kanade.tachiyomi.util.lang.use import eu.kanade.tachiyomi.util.lang.use
@ -55,7 +57,16 @@ class PackageInstallerInstaller(private val service: Service) : Installer(servic
} }
PackageInstaller.STATUS_SUCCESS -> continueQueue(InstallStep.Installed) PackageInstaller.STATUS_SUCCESS -> continueQueue(InstallStep.Installed)
else -> continueQueue(InstallStep.Error) PackageInstaller.STATUS_FAILURE_CONFLICT -> {
Logger.log("Failed to install extension due to conflict")
toast(context.getString(R.string.failed_ext_install_conflict))
continueQueue(InstallStep.Error)
}
else -> {
Logger.log("Fatal error for $intent")
Logger.log("Status: ${intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -1)}")
continueQueue(InstallStep.Error)
}
} }
} }
} }

View file

@ -111,7 +111,7 @@
android:layout_gravity="center" android:layout_gravity="center"
android:drawablePadding="4dp" android:drawablePadding="4dp"
android:fontFamily="@font/poppins_bold" android:fontFamily="@font/poppins_bold"
android:text="Image" android:text="@string/image"
android:textColor="?attr/colorPrimary" android:textColor="?attr/colorPrimary"
app:drawableStartCompat="@drawable/ic_round_search_24" app:drawableStartCompat="@drawable/ic_round_search_24"
app:drawableTint="?attr/colorPrimary" /> app:drawableTint="?attr/colorPrimary" />

View file

@ -956,4 +956,6 @@ Non quae tempore quo provident laudantium qui illo dolor vel quia dolor et exerc
<string name="update_addon">Update Addon</string> <string name="update_addon">Update Addon</string>
<string name="install_addon">Install Addon</string> <string name="install_addon">Install Addon</string>
<string name="download_addon_not_found">Download addon not found</string> <string name="download_addon_not_found">Download addon not found</string>
<string name="image">Image</string>
<string name="failed_ext_install_conflict">Failed to install extension due to conflict</string>
</resources> </resources>