Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
c5a03c4455
17 changed files with 55 additions and 31 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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) {} },
|
||||||
|
|
|
@ -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 -> {
|
||||||
|
|
|
@ -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) } ?: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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" />
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue