clean Sad's shit

This commit is contained in:
Finnley Somdahl 2024-01-13 11:20:02 -06:00
parent 84e300482a
commit cc5b512441
53 changed files with 652 additions and 466 deletions

View file

@ -11,12 +11,14 @@ import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.provider.Settings
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.view.animation.AnticipateInterpolator
import android.widget.TextView
import androidx.activity.addCallback
import androidx.activity.viewModels
import androidx.annotation.OptIn
import androidx.appcompat.app.AppCompatActivity
import androidx.core.animation.doOnEnd
import androidx.core.content.ContextCompat
@ -26,12 +28,14 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.offline.Download
import androidx.viewpager2.adapter.FragmentStateAdapter
import ani.dantotsu.App.Companion.context
import ani.dantotsu.connections.anilist.Anilist
import ani.dantotsu.connections.anilist.AnilistHomeViewModel
import ani.dantotsu.databinding.ActivityMainBinding
import ani.dantotsu.databinding.SplashScreenBinding
import ani.dantotsu.download.video.Helper
import ani.dantotsu.home.AnimeFragment
import ani.dantotsu.home.HomeFragment
import ani.dantotsu.home.LoginFragment
@ -46,6 +50,7 @@ import ani.dantotsu.themes.ThemeManager
import io.noties.markwon.Markwon
import io.noties.markwon.SoftBreakAddsNewLinePlugin
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -61,6 +66,7 @@ class MainActivity : AppCompatActivity() {
private var uiSettings = UserInterfaceSettings()
@OptIn(UnstableApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
ThemeManager(this).applyTheme()
LangSet.setLocale(this)
@ -154,7 +160,8 @@ class MainActivity : AppCompatActivity() {
getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
.edit()
.putBoolean("offlineMode", true)
.apply()} else {
.apply()
} else {
getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
.edit()
.putBoolean("offlineMode", false)
@ -267,8 +274,6 @@ class MainActivity : AppCompatActivity() {
}
}
}

View file

@ -7,7 +7,6 @@ import androidx.annotation.OptIn
import androidx.core.content.ContextCompat
import androidx.media3.common.util.UnstableApi
import androidx.media3.database.StandaloneDatabaseProvider
import androidx.media3.datasource.cache.SimpleCache
import ani.dantotsu.download.DownloadsManager
import ani.dantotsu.media.manga.MangaCache
import ani.dantotsu.parsers.novel.NovelExtensionManager
@ -31,7 +30,8 @@ import uy.kohesive.injekt.api.addSingletonFactory
import uy.kohesive.injekt.api.get
class AppModule(val app: Application) : InjektModule {
@OptIn(UnstableApi::class) override fun InjektRegistrar.registerInjectables() {
@OptIn(UnstableApi::class)
override fun InjektRegistrar.registerInjectables() {
addSingleton(app)
addSingletonFactory { DownloadsManager(app) }

View file

@ -10,7 +10,6 @@ import ani.dantotsu.toast
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlin.math.roundToInt
fun updateProgress(media: Media, number: String) {
val incognito = currContext()?.getSharedPreferences("Dantotsu", 0)

View file

@ -17,7 +17,6 @@ import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.offline.Download
import androidx.media3.exoplayer.offline.DownloadManager
import androidx.media3.exoplayer.offline.DownloadService
import ani.dantotsu.FileUrl
@ -25,8 +24,8 @@ import ani.dantotsu.R
import ani.dantotsu.currActivity
import ani.dantotsu.download.DownloadedType
import ani.dantotsu.download.DownloadsManager
import ani.dantotsu.download.video.Helper
import ani.dantotsu.download.video.ExoplayerDownloadService
import ani.dantotsu.download.video.Helper
import ani.dantotsu.logger
import ani.dantotsu.media.Media
import ani.dantotsu.media.anime.AnimeWatchFragment
@ -80,7 +79,8 @@ class AnimeDownloaderService : Service() {
override fun onCreate() {
super.onCreate()
notificationManager = NotificationManagerCompat.from(this)
builder = NotificationCompat.Builder(this, Notifications.CHANNEL_DOWNLOADER_PROGRESS).apply {
builder =
NotificationCompat.Builder(this, Notifications.CHANNEL_DOWNLOADER_PROGRESS).apply {
setContentTitle("Anime Download Progress")
setSmallIcon(R.drawable.ic_round_download_24)
priority = NotificationCompat.PRIORITY_DEFAULT
@ -154,7 +154,9 @@ class AnimeDownloaderService : Service() {
fun cancelDownload(taskName: String) {
CoroutineScope(Dispatchers.Default).launch {
mutex.withLock {
val url = AnimeServiceDataSingleton.downloadQueue.find { it.getTaskName() == taskName }?.video?.file?.url ?: ""
val url =
AnimeServiceDataSingleton.downloadQueue.find { it.getTaskName() == taskName }?.video?.file?.url
?: ""
DownloadService.sendRemoveDownload(
this@AnimeDownloaderService,
ExoplayerDownloadService::class.java,
@ -188,7 +190,8 @@ class AnimeDownloaderService : Service() {
notificationManager.notify(NOTIFICATION_ID, builder.build())
}
@androidx.annotation.OptIn(UnstableApi::class) suspend fun download(task: DownloadTask) {
@androidx.annotation.OptIn(UnstableApi::class)
suspend fun download(task: DownloadTask) {
try {
val downloadManager = Helper.downloadManager(this@AnimeDownloaderService)
withContext(Dispatchers.Main) {
@ -212,11 +215,13 @@ class AnimeDownloaderService : Service() {
Helper.downloadVideo(
it,
task.video,
task.subtitle)
task.subtitle
)
}
saveMediaInfo(task)
val downloadStarted = hasDownloadStarted(downloadManager, task, 30000) // 30 seconds timeout
val downloadStarted =
hasDownloadStarted(downloadManager, task, 30000) // 30 seconds timeout
if (!downloadStarted) {
logger("Download failed to start")
@ -238,11 +243,15 @@ class AnimeDownloaderService : Service() {
notificationManager.notify(NOTIFICATION_ID, builder.build())
snackString("${task.title} - ${task.episode} Download failed")
logger("Download failed: ${download.failureReason}")
FirebaseCrashlytics.getInstance().recordException(Exception("Anime Download failed:" +
FirebaseCrashlytics.getInstance().recordException(
Exception(
"Anime Download failed:" +
" ${download.failureReason}" +
" url: ${task.video.file.url}" +
" title: ${task.title}" +
" episode: ${task.episode}"))
" episode: ${task.episode}"
)
)
broadcastDownloadFailed(task.getTaskName())
break
}
@ -251,7 +260,10 @@ class AnimeDownloaderService : Service() {
builder.setContentText("${task.title} - ${task.episode} Download completed")
notificationManager.notify(NOTIFICATION_ID, builder.build())
snackString("${task.title} - ${task.episode} Download completed")
getSharedPreferences(getString(R.string.anime_downloads), Context.MODE_PRIVATE).edit().putString(
getSharedPreferences(
getString(R.string.anime_downloads),
Context.MODE_PRIVATE
).edit().putString(
task.getTaskName(),
task.video.file.url
).apply()
@ -272,7 +284,10 @@ class AnimeDownloaderService : Service() {
snackString("${task.title} - ${task.episode} Download stopped")
break
}
broadcastDownloadProgress(task.getTaskName(), download.percentDownloaded.toInt())
broadcastDownloadProgress(
task.getTaskName(),
download.percentDownloaded.toInt()
)
if (notifi) {
notificationManager.notify(NOTIFICATION_ID, builder.build())
}
@ -288,7 +303,12 @@ class AnimeDownloaderService : Service() {
}
}
@androidx.annotation.OptIn(UnstableApi::class) suspend fun hasDownloadStarted(downloadManager: DownloadManager, task: DownloadTask, timeout: Long): Boolean {
@androidx.annotation.OptIn(UnstableApi::class)
suspend fun hasDownloadStarted(
downloadManager: DownloadManager,
task: DownloadTask,
timeout: Long
): Boolean {
val startTime = System.currentTimeMillis()
while (System.currentTimeMillis() - startTime < timeout) {
val download = downloadManager.downloadIndex.getDownload(task.video.file.url)
@ -331,7 +351,11 @@ class AnimeDownloaderService : Service() {
media.banner = media.banner?.let { downloadImage(it, directory, "banner.jpg") }
if (task.episodeImage != null) {
media.anime?.episodes?.get(task.episode)?.let { episode ->
episode.thumb = downloadImage(task.episodeImage, episodeDirectory, "episodeImage.jpg")?.let {
episode.thumb = downloadImage(
task.episodeImage,
episodeDirectory,
"episodeImage.jpg"
)?.let {
FileUrl(
it
)
@ -412,7 +436,8 @@ class AnimeDownloaderService : Service() {
}
private val cancelReceiver = object : BroadcastReceiver() {
@androidx.annotation.OptIn(UnstableApi::class) override fun onReceive(context: Context, intent: Intent) {
@androidx.annotation.OptIn(UnstableApi::class)
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == ACTION_CANCEL_DOWNLOAD) {
val taskName = intent.getStringExtra(EXTRA_TASK_NAME)
taskName?.let {

View file

@ -21,7 +21,8 @@ class OfflineMangaAdapter(
private val inflater: LayoutInflater =
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
private var originalItems: List<OfflineMangaModel> = items
private var style = context.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).getInt("offline_view", 0)
private var style =
context.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).getInt("offline_view", 0)
override fun getCount(): Int {
return items.size
@ -45,7 +46,7 @@ class OfflineMangaAdapter(
}
val item = getItem(position) as OfflineMangaModel
val imageView = view!!.findViewById<ImageView>(R.id.itemCompactImage)
val imageView = view.findViewById<ImageView>(R.id.itemCompactImage)
val titleTextView = view.findViewById<TextView>(R.id.itemCompactTitle)
val itemScore = view.findViewById<TextView>(R.id.itemCompactScore)
val itemScoreBG = view.findViewById<View>(R.id.itemCompactScoreBG)
@ -61,10 +62,9 @@ class OfflineMangaAdapter(
chapters.text = " Chapters"
bannerView.setImageURI(item.banner)
totalchapter.text = item.totalchapter
}
else if (style == 1){
val readchapter = view.findViewById<TextView>(R.id.itemCompactUserProgress) // for compact view
} else if (style == 1) {
val readchapter =
view.findViewById<TextView>(R.id.itemCompactUserProgress) // for compact view
readchapter.text = item.readchapter
totalchapter.text = " | " + item.totalchapter
}
@ -104,7 +104,8 @@ class OfflineMangaAdapter(
}
fun notifyNewGrid() {
style = context.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).getInt("offline_view", 0)
style =
context.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).getInt("offline_view", 0)
notifyDataSetChanged()
}
}

View file

@ -20,6 +20,7 @@ import android.widget.AbsListView
import android.widget.AutoCompleteTextView
import android.widget.GridView
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView
import androidx.fragment.app.Fragment
@ -76,7 +77,8 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
val animeUserAvatar = view.findViewById<ShapeableImageView>(R.id.offlineMangaUserAvatar)
animeUserAvatar.setSafeOnClickListener {
val dialogFragment = SettingsDialogFragment.newInstance2(SettingsDialogFragment.Companion.PageType2.OfflineMANGA)
val dialogFragment =
SettingsDialogFragment.newInstance2(SettingsDialogFragment.Companion.PageType2.OfflineMANGA)
dialogFragment.show((it.context as AppCompatActivity).supportFragmentManager, "dialog")
}
@ -92,7 +94,7 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int, ) {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
@ -143,7 +145,8 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
adapter.notifyNewGrid()
}
gridView = if(style == 0) view.findViewById(R.id.gridView) else view.findViewById(R.id.gridView1)
gridView =
if (style == 0) view.findViewById(R.id.gridView) else view.findViewById(R.id.gridView1)
gridView.visibility = View.VISIBLE
getDownloads()
@ -173,17 +176,20 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
}
val total = view.findViewById<TextView>(R.id.total)
total.text = if (gridView.count > 0) "Manga and Novels (${gridView.count})" else "Empty List"
total.text =
if (gridView.count > 0) "Manga and Novels (${gridView.count})" else "Empty List"
gridView.setOnItemLongClickListener { parent, view, position, id ->
// Get the OfflineMangaModel that was clicked
val item = adapter.getItem(position) as OfflineMangaModel
val type: DownloadedType.Type = if (downloadManager.mangaDownloadedTypes.any { it.title == item.title }) {
val type: DownloadedType.Type =
if (downloadManager.mangaDownloadedTypes.any { it.title == item.title }) {
DownloadedType.Type.MANGA
} else {
DownloadedType.Type.NOVEL
}
// Alert dialog to confirm deletion
val builder = androidx.appcompat.app.AlertDialog.Builder(requireContext(), R.style.MyPopup)
val builder =
androidx.appcompat.app.AlertDialog.Builder(requireContext(), R.style.MyPopup)
builder.setTitle("Delete ${item.title}?")
builder.setMessage("Are you sure you want to delete ${item.title}?")
builder.setPositiveButton("Yes") { _, _ ->
@ -253,7 +259,12 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
// Implement behavior for different scroll states if needed
}
override fun onScroll(view: AbsListView, firstVisibleItem: Int, visibleItemCount: Int, totalItemCount: Int) {
override fun onScroll(
view: AbsListView,
firstVisibleItem: Int,
visibleItemCount: Int,
totalItemCount: Int
) {
val first = view.getChildAt(0)
val visibility = first != null && first.top < -height
scrollTop.visibility = if (visibility) View.VISIBLE else View.GONE
@ -365,17 +376,40 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
val title = mediaModel.nameMAL ?: mediaModel.nameRomaji
val score = ((if (mediaModel.userScore == 0) (mediaModel.meanScore
?: 0) else mediaModel.userScore) / 10.0).toString()
val isOngoing = mediaModel.status == currActivity()!!.getString(R.string.status_releasing)
val isOngoing =
mediaModel.status == currActivity()!!.getString(R.string.status_releasing)
val isUserScored = mediaModel.userScore != 0
val readchapter = (mediaModel.userProgress ?: "~").toString()
val totalchapter = "${mediaModel.manga?.totalChapters ?: "??"}"
val chapters = " Chapters"
return OfflineMangaModel(title, score, totalchapter, readchapter, type, chapters, isOngoing, isUserScored, coverUri , bannerUri )
return OfflineMangaModel(
title,
score,
totalchapter,
readchapter,
type,
chapters,
isOngoing,
isUserScored,
coverUri,
bannerUri
)
} catch (e: Exception) {
logger("Error loading media.json: ${e.message}")
logger(e.printStackTrace())
FirebaseCrashlytics.getInstance().recordException(e)
return OfflineMangaModel("unknown", "0", "??", "??","movie" ,"hmm", false, false, null , null)
return OfflineMangaModel(
"unknown",
"0",
"??",
"??",
"movie",
"hmm",
false,
false,
null,
null
)
}
}
}

View file

@ -11,7 +11,8 @@ import androidx.media3.exoplayer.scheduler.Scheduler
import ani.dantotsu.R
@UnstableApi
class ExoplayerDownloadService : DownloadService(1, 2000, "download_service", R.string.downloads, 0) {
class ExoplayerDownloadService :
DownloadService(1, 2000, "download_service", R.string.downloads, 0) {
companion object {
private const val JOB_ID = 1
private const val FOREGROUND_NOTIFICATION_ID = 1

View file

@ -17,7 +17,6 @@ import androidx.core.content.ContextCompat.getString
import androidx.media3.common.C
import androidx.media3.common.MediaItem
import androidx.media3.common.MimeTypes
import androidx.media3.common.TrackSelectionParameters
import androidx.media3.common.util.UnstableApi
import androidx.media3.database.StandaloneDatabaseProvider
import androidx.media3.datasource.DataSource
@ -31,7 +30,6 @@ import androidx.media3.exoplayer.offline.DownloadHelper
import androidx.media3.exoplayer.offline.DownloadManager
import androidx.media3.exoplayer.offline.DownloadService
import androidx.media3.exoplayer.scheduler.Requirements
import androidx.media3.ui.TrackSelectionDialogBuilder
import ani.dantotsu.R
import ani.dantotsu.defaultHeaders
import ani.dantotsu.download.DownloadedType

View file

@ -2,7 +2,6 @@ package ani.dantotsu.home
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
@ -27,7 +26,6 @@ import ani.dantotsu.connections.anilist.Anilist
import ani.dantotsu.connections.anilist.AnilistAnimeViewModel
import ani.dantotsu.connections.anilist.SearchResults
import ani.dantotsu.connections.anilist.getUserId
import ani.dantotsu.currContext
import ani.dantotsu.databinding.FragmentAnimeBinding
import ani.dantotsu.loadData
import ani.dantotsu.media.MediaAdaptor

View file

@ -358,11 +358,13 @@ class HomeFragment : Fragment() {
}
}
}
private fun setIncognito() {
val incognito = currContext()?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
?.getBoolean("incognito", false) ?: false
if (incognito) {
val uiSettings = loadData<UserInterfaceSettings>("ui_settings") ?: UserInterfaceSettings()
val uiSettings =
loadData<UserInterfaceSettings>("ui_settings") ?: UserInterfaceSettings()
binding.incognitoTextView.visibility = View.VISIBLE
if (!uiSettings.immersiveMode) {
binding.root.fitsSystemWindows = true
@ -377,6 +379,7 @@ class HomeFragment : Fragment() {
binding.incognitoTextView.visibility = View.GONE
}
}
override fun onResume() {
if (!model.loaded) Refresh.activity[1]!!.postValue(true)
setIncognito()

View file

@ -2,7 +2,6 @@ package ani.dantotsu.home
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
@ -25,7 +24,6 @@ import ani.dantotsu.connections.anilist.Anilist
import ani.dantotsu.connections.anilist.AnilistMangaViewModel
import ani.dantotsu.connections.anilist.SearchResults
import ani.dantotsu.connections.anilist.getUserId
import ani.dantotsu.currContext
import ani.dantotsu.databinding.FragmentMangaBinding
import ani.dantotsu.loadData
import ani.dantotsu.media.MediaAdaptor

View file

@ -318,8 +318,7 @@ class MediaDetailsActivity : AppCompatActivity(), AppBarLayout.OnOffsetChangedLi
)
if (media.format == "NOVEL") {
tabLayout.inflateMenu(R.menu.novel_menu_detail)
}
else {
} else {
tabLayout.inflateMenu(R.menu.manga_menu_detail)
}
anime = false
@ -365,6 +364,7 @@ class MediaDetailsActivity : AppCompatActivity(), AppBarLayout.OnOffsetChangedLi
R.id.info -> {
selected = 0
}
R.id.watch, R.id.read -> {
selected = 1
}

View file

@ -29,8 +29,8 @@ class SubtitleDownloader {
val subtitleType = when {
responseBody?.contains("[Script Info]") == true -> SubtitleType.ASS
responseBody?.contains("WEBVTT") == true -> SubtitleType.VTT
responseBody.contains("[Script Info]") == true -> SubtitleType.ASS
responseBody.contains("WEBVTT") == true -> SubtitleType.VTT
else -> SubtitleType.SRT
}

View file

@ -5,7 +5,8 @@ import java.util.regex.Pattern
class AnimeNameAdapter {
companion object {
const val episodeRegex = "(episode|ep|e)[\\s:.\\-]*([\\d]+\\.?[\\d]*)[\\s:.\\-]*\\(?\\s*(sub|subbed|dub|dubbed)*\\s*\\)?\\s*"
const val episodeRegex =
"(episode|ep|e)[\\s:.\\-]*([\\d]+\\.?[\\d]*)[\\s:.\\-]*\\(?\\s*(sub|subbed|dub|dubbed)*\\s*\\)?\\s*"
const val seasonRegex = "(season|s)[\\s:.\\-]*(\\d+)[\\s:.\\-]*"
fun findSeasonNumber(text: String): Int? {

View file

@ -14,10 +14,9 @@ import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import ani.dantotsu.*
import ani.dantotsu.databinding.DialogLayoutBinding
import ani.dantotsu.databinding.ItemAnimeWatchBinding
import ani.dantotsu.databinding.ItemChipBinding
import ani.dantotsu.databinding.DialogLayoutBinding
import ani.dantotsu.media.anime.AnimeNameAdapter
import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsActivity
import ani.dantotsu.media.SourceSearchDialogFragment
@ -45,6 +44,7 @@ class AnimeWatchAdapter(
val bind = ItemAnimeWatchBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(bind)
}
private var nestedDialog: AlertDialog? = null
@ -401,7 +401,8 @@ fun handleEpisodes() {
parser.extension.sources.map { LanguageMapper.mapLanguageCodeToName(it.lang) }
)
val items = adapter.count
if (items > 1) binding?.animeSourceLanguageContainer?.visibility = View.VISIBLE else binding?.animeSourceLanguageContainer?.visibility = View.GONE
if (items > 1) binding?.animeSourceLanguageContainer?.visibility =
View.VISIBLE else binding?.animeSourceLanguageContainer?.visibility = View.GONE
binding?.animeSourceLanguage?.setAdapter(adapter)

View file

@ -320,7 +320,8 @@ class AnimeWatchFragment : Fragment() {
if (allSettings.isNotEmpty()) {
var selectedSetting = allSettings[0]
if (allSettings.size > 1) {
val names = allSettings.map { LanguageMapper.mapLanguageCodeToName(it.lang) }.toTypedArray()
val names =
allSettings.map { LanguageMapper.mapLanguageCodeToName(it.lang) }.toTypedArray()
var selectedIndex = 0
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
.setTitle("Select a Source")

View file

@ -11,7 +11,6 @@ import ani.dantotsu.connections.updateProgress
import ani.dantotsu.databinding.ItemEpisodeCompactBinding
import ani.dantotsu.databinding.ItemEpisodeGridBinding
import ani.dantotsu.databinding.ItemEpisodeListBinding
import ani.dantotsu.media.anime.AnimeNameAdapter
import ani.dantotsu.media.Media
import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl

View file

@ -339,7 +339,8 @@ class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityL
setContentView(binding.root)
//Initialize
isCastApiAvailable = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS
isCastApiAvailable = GoogleApiAvailability.getInstance()
.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS
try {
castContext = CastContext.getSharedInstance(this)
castPlayer = CastPlayer(castContext!!)

View file

@ -23,7 +23,6 @@ import ani.dantotsu.databinding.ItemUrlBinding
import ani.dantotsu.download.video.Helper
import ani.dantotsu.media.Media
import ani.dantotsu.media.MediaDetailsViewModel
import ani.dantotsu.others.Download.download
import ani.dantotsu.parsers.VideoExtractor
import ani.dantotsu.parsers.VideoType
import kotlinx.coroutines.CoroutineScope
@ -275,7 +274,8 @@ class SelectorDialogFragment : BottomSheetDialogFragment() {
// media!!.userPreferredName
//)
val episode = media!!.anime!!.episodes!![media!!.anime!!.selectedEpisode!!]!!
val video = if (extractor.videos.size > episode.selectedVideo) extractor.videos[episode.selectedVideo] else null
val video =
if (extractor.videos.size > episode.selectedVideo) extractor.videos[episode.selectedVideo] else null
if (video != null) {
Helper.startAnimeDownloadService(
requireActivity(),

View file

@ -48,7 +48,9 @@ class MangaReadAdapter(
val bind = ItemAnimeWatchBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(bind)
}
private var nestedDialog: AlertDialog? = null
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val binding = holder.binding
@ -211,7 +213,8 @@ class MangaReadAdapter(
dialogBinding.animeScanlatorTop.setOnClickListener {
val dialogView2 =
LayoutInflater.from(currContext()).inflate(R.layout.custom_dialog_layout, null)
val checkboxContainer = dialogView2.findViewById<LinearLayout>(R.id.checkboxContainer)
val checkboxContainer =
dialogView2.findViewById<LinearLayout>(R.id.checkboxContainer)
// Dynamically add checkboxes
options.forEach { option ->
@ -293,6 +296,7 @@ class MangaReadAdapter(
0
)
}
val startChapter = MangaNameAdapter.findChapterNumber(names[limit * (position)])
val endChapter = MangaNameAdapter.findChapterNumber(names[last - 1])
val startChapterString = if (startChapter != null) {
@ -425,7 +429,8 @@ class MangaReadAdapter(
parser.extension.sources.map { LanguageMapper.mapLanguageCodeToName(it.lang) }
)
val items = adapter.count
if (items > 1) binding?.animeSourceLanguageContainer?.visibility = View.VISIBLE else binding?.animeSourceLanguageContainer?.visibility = View.GONE
if (items > 1) binding?.animeSourceLanguageContainer?.visibility =
View.VISIBLE else binding?.animeSourceLanguageContainer?.visibility = View.GONE
binding?.animeSourceLanguage?.setAdapter(adapter)

View file

@ -197,12 +197,15 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
override fun onScanlatorsSelected() {
updateChapters()
}
fun multiDownload(n: Int) {
//get last viewed chapter
val selected = media.userProgress
val chapters = media.manga?.chapters?.values?.toList()
//filter by selected language
val progressChapterIndex = (chapters?.indexOfFirst { MangaNameAdapter.findChapterNumber(it.number)?.toInt() == selected } ?: 0) + 1
val progressChapterIndex = (chapters?.indexOfFirst {
MangaNameAdapter.findChapterNumber(it.number)?.toInt() == selected
} ?: 0) + 1
if (progressChapterIndex < 0 || n < 1 || chapters == null) return
@ -363,7 +366,8 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
if (allSettings.isNotEmpty()) {
var selectedSetting = allSettings[0]
if (allSettings.size > 1) {
val names = allSettings.map { LanguageMapper.mapLanguageCodeToName(it.lang) }.toTypedArray()
val names =
allSettings.map { LanguageMapper.mapLanguageCodeToName(it.lang) }.toTypedArray()
var selectedIndex = 0
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
.setTitle("Select a Source")

View file

@ -89,7 +89,8 @@ abstract class BaseImageAdapter(
}
} else {
val detector = GestureDetectorCompat(view.context, object : GesturesListener() {
override fun onSingleClick(event: MotionEvent) = activity.handleController(event = event)
override fun onSingleClick(event: MotionEvent) =
activity.handleController(event = event)
})
view.findViewById<View>(R.id.imgProgCover).apply {
setOnTouchListener { _, event ->

View file

@ -93,12 +93,14 @@ open class ImageAdapter(
override fun getItemCount(): Int = images.size
override fun isZoomed(): Boolean {
val imageView = activity.findViewById<SubsamplingScaleImageView>(R.id.imgProgImageNoGestures)
val imageView =
activity.findViewById<SubsamplingScaleImageView>(R.id.imgProgImageNoGestures)
return imageView.scale > imageView.minScale
}
override fun setZoom(zoom: Float) {
val imageView = activity.findViewById<SubsamplingScaleImageView>(R.id.imgProgImageNoGestures)
val imageView =
activity.findViewById<SubsamplingScaleImageView>(R.id.imgProgImageNoGestures)
imageView.setScaleAndCenter(zoom, imageView.center)
}
}

View file

@ -255,7 +255,8 @@ class MangaReaderActivity : AppCompatActivity() {
}
showProgressDialog =
if (settings.askIndividual) loadData<Boolean>("${media.id}_progressDialog")?: true else false
if (settings.askIndividual) loadData<Boolean>("${media.id}_progressDialog")
?: true else false
//Chapter Change
fun change(index: Int) {
@ -850,7 +851,8 @@ class MangaReaderActivity : AppCompatActivity() {
private fun progress(runnable: Runnable) {
if (maxChapterPage - currentChapterPage <= 1 && Anilist.userid != null) {
showProgressDialog =
if (settings.askIndividual) loadData<Boolean>("${media.id}_progressDialog")?: true else false
if (settings.askIndividual) loadData<Boolean>("${media.id}_progressDialog")
?: true else false
if (showProgressDialog) {
val dialogView = layoutInflater.inflate(R.layout.item_custom_dialog, null)

View file

@ -42,7 +42,11 @@ class NovelResponseAdapter(
.into(binding.itemEpisodeImage)
val typedValue = TypedValue()
fragment.requireContext().theme?.resolveAttribute(com.google.android.material.R.attr.colorOnBackground, typedValue, true)
fragment.requireContext().theme?.resolveAttribute(
com.google.android.material.R.attr.colorOnBackground,
typedValue,
true
)
val color = typedValue.data
binding.itemEpisodeTitle.text = novel.name
@ -98,14 +102,19 @@ class NovelResponseAdapter(
}
binding.root.setOnLongClickListener {
val builder = androidx.appcompat.app.AlertDialog.Builder(fragment.requireContext(), R.style.DialogTheme)
val builder = androidx.appcompat.app.AlertDialog.Builder(
fragment.requireContext(),
R.style.DialogTheme
)
builder.setTitle("Delete ${novel.name}?")
builder.setMessage("Are you sure you want to delete ${novel.name}?")
builder.setPositiveButton("Yes") { _, _ ->
downloadedCheckCallback.deleteDownload(novel)
deleteDownload(novel.link)
snackString("Deleted ${novel.name}")
if (binding.itemEpisodeFiller.text.toString().contains("Download", ignoreCase = true)) {
if (binding.itemEpisodeFiller.text.toString()
.contains("Download", ignoreCase = true)
) {
binding.itemEpisodeFiller.text = ""
}
}

View file

@ -148,7 +148,8 @@ class NovelReaderActivity : AppCompatActivity(), EbookReaderEventListener {
Toast.makeText(this, "Please update WebView from PlayStore", Toast.LENGTH_LONG).show()
//open playstore
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("https://play.google.com/store/apps/details?id=com.google.android.webview")
intent.data =
Uri.parse("https://play.google.com/store/apps/details?id=com.google.android.webview")
startActivity(intent)
//stop reader
finish()
@ -270,7 +271,8 @@ class NovelReaderActivity : AppCompatActivity(), EbookReaderEventListener {
binding.bookReader.getAppearance {
currentTheme = it
themes.add(0, it)
settings.defaultLN = loadData("${sanitizedBookId}_current_settings") ?: settings.defaultLN
settings.defaultLN =
loadData("${sanitizedBookId}_current_settings") ?: settings.defaultLN
applySettings()
}

View file

@ -22,7 +22,6 @@ import ani.dantotsu.databinding.ActivityListBinding
import ani.dantotsu.loadData
import ani.dantotsu.navBarHeight
import ani.dantotsu.others.LangSet
import ani.dantotsu.saveData
import ani.dantotsu.settings.UserInterfaceSettings
import ani.dantotsu.statusBarHeight
import ani.dantotsu.themes.ThemeManager

View file

@ -7,10 +7,10 @@ import android.view.View
import android.view.ViewGroup
import androidx.core.view.updateLayoutParams
import androidx.fragment.app.Fragment
import ani.dantotsu.databinding.FragmentOfflineBinding
import ani.dantotsu.isOnline
import ani.dantotsu.App
import ani.dantotsu.R
import ani.dantotsu.databinding.FragmentOfflineBinding
import ani.dantotsu.isOnline
import ani.dantotsu.navBarHeight
import ani.dantotsu.startMainActivity
import ani.dantotsu.statusBarHeight
@ -26,8 +26,10 @@ class OfflineFragment : Fragment() {
topMargin = statusBarHeight
bottomMargin = navBarHeight
}
val offline = App.context?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)?.getBoolean("offlineMode", false) ?: false
binding.noInternet.text = if (!isOnline(requireContext())) getString(R.string.no_internet) else "OFFLINE MODE"
val offline = App.context?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
?.getBoolean("offlineMode", false) ?: false
binding.noInternet.text =
if (!isOnline(requireContext())) getString(R.string.no_internet) else "OFFLINE MODE"
binding.refreshButton.setOnClickListener {
if (!isOnline(requireContext()) && offline) {
startMainActivity(requireActivity())

View file

@ -17,7 +17,6 @@ import ani.dantotsu.media.anime.AnimeNameAdapter
import ani.dantotsu.media.manga.ImageData
import ani.dantotsu.media.manga.MangaCache
import ani.dantotsu.snackString
import com.google.firebase.crashlytics.FirebaseCrashlytics
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
import eu.kanade.tachiyomi.animesource.model.AnimesPage
import eu.kanade.tachiyomi.animesource.model.SAnime
@ -317,6 +316,7 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
}
return ret
}
suspend fun imageList(chapterLink: String, sChapter: SChapter): List<ImageData> {
val source = try {
extension.sources[sourceLanguage]
@ -329,7 +329,8 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
try {
println("source.name " + source.name)
val res = source.getPageList(sChapter)
val reIndexedPages = res.mapIndexed { index, page -> Page(index, page.url, page.imageUrl, page.uri) }
val reIndexedPages =
res.mapIndexed { index, page -> Page(index, page.url, page.imageUrl, page.uri) }
val semaphore = Semaphore(5)
val deferreds = reIndexedPages.map { page ->
@ -367,7 +368,7 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
// Convert InputStream to Bitmap
val bitmap = BitmapFactory.decodeStream(inputStream)
inputStream?.close()
inputStream.close()
ani.dantotsu.media.manga.saveImage(
bitmap,
context.contentResolver,
@ -409,7 +410,7 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
)
}
inputStream?.close()
inputStream.close()
} catch (e: Exception) {
// Handle any exceptions
println("An error occurred: ${e.message}")
@ -706,7 +707,7 @@ class VideoServerPassthrough(val videoServer: VideoServer) : VideoExtractor() {
return Subtitle(track.lang, track.url, type ?: SubtitleType.SRT)
}
private fun findSubtitleType(url: String): SubtitleType? {
private fun findSubtitleType(url: String): SubtitleType {
// First, try to determine the type based on the URL file extension
val type: SubtitleType = when {
url.endsWith(".vtt", true) -> SubtitleType.VTT

View file

@ -3,7 +3,6 @@ package ani.dantotsu.parsers
import android.os.Environment
import ani.dantotsu.currContext
import ani.dantotsu.download.DownloadsManager
import ani.dantotsu.logger
import ani.dantotsu.media.anime.AnimeNameAdapter
import eu.kanade.tachiyomi.animesource.model.SAnime
import eu.kanade.tachiyomi.animesource.model.SEpisode

View file

@ -72,7 +72,8 @@ class OfflineNovelParser: NovelParser() {
}
}
}
val cover = currContext()?.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)?.absolutePath + "/Dantotsu/Novel/$title/cover.jpg"
val cover =
currContext()?.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)?.absolutePath + "/Dantotsu/Novel/$title/cover.jpg"
names.forEach {
returnList.add(ShowResponse(it, it, cover))
}

View file

@ -111,7 +111,8 @@ internal object NovelExtensionLoader {
@Suppress("DEPRECATION")
private fun getSignatureHash(pkgInfo: PackageInfo): List<String>? {
val signatures = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && pkgInfo.signingInfo != null) {
val signatures =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && pkgInfo.signingInfo != null) {
pkgInfo.signingInfo.apkContentsSigners
} else {
pkgInfo.signatures

View file

@ -9,9 +9,7 @@ import android.text.TextWatcher
import android.view.View
import android.view.ViewGroup
import android.widget.AutoCompleteTextView
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.PopupMenu
import androidx.core.view.updateLayoutParams
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter

View file

@ -58,7 +58,8 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler {
activity.findViewById<TabLayout>(R.id.tabLayout).visibility = visibility
activity.findViewById<TextInputLayout>(R.id.searchView).visibility = visibility
activity.findViewById<ImageView>(R.id.languageselect).visibility = visibility
activity.findViewById<TextView>(R.id.extensions).text = if (show) getString(R.string.extensions) else name
activity.findViewById<TextView>(R.id.extensions).text =
if (show) getString(R.string.extensions) else name
activity.findViewById<FrameLayout>(R.id.fragmentExtensionsContainer).visibility =
if (show) View.GONE else View.VISIBLE
}
@ -67,7 +68,8 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler {
if (allSettings.isNotEmpty()) {
var selectedSetting = allSettings[0]
if (allSettings.size > 1) {
val names = allSettings.map { LanguageMapper.mapLanguageCodeToName(it.lang) }.toTypedArray()
val names = allSettings.map { LanguageMapper.mapLanguageCodeToName(it.lang) }
.toTypedArray()
var selectedIndex = 0
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
.setTitle("Select a Source")

View file

@ -47,7 +47,8 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler {
private lateinit var extensionsRecyclerView: RecyclerView
private val skipIcons = loadData("skip_extension_icons") ?: false
private val mangaExtensionManager: MangaExtensionManager = Injekt.get()
private val extensionsAdapter = MangaExtensionsAdapter({ pkg ->
private val extensionsAdapter = MangaExtensionsAdapter(
{ pkg ->
val name = pkg.name
val changeUIVisibility: (Boolean) -> Unit = { show ->
val activity = requireActivity() as ExtensionsActivity
@ -56,7 +57,8 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler {
activity.findViewById<TabLayout>(R.id.tabLayout).visibility = visibility
activity.findViewById<TextInputLayout>(R.id.searchView).visibility = visibility
activity.findViewById<ImageView>(R.id.languageselect).visibility = visibility
activity.findViewById<TextView>(R.id.extensions).text = if (show) getString(R.string.extensions) else name
activity.findViewById<TextView>(R.id.extensions).text =
if (show) getString(R.string.extensions) else name
activity.findViewById<FrameLayout>(R.id.fragmentExtensionsContainer).visibility =
if (show) View.GONE else View.VISIBLE
}
@ -65,7 +67,8 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler {
if (allSettings.isNotEmpty()) {
var selectedSetting = allSettings[0]
if (allSettings.size > 1) {
val names = allSettings.map { LanguageMapper.mapLanguageCodeToName(it.lang) }.toTypedArray()
val names = allSettings.map { LanguageMapper.mapLanguageCodeToName(it.lang) }
.toTypedArray()
var selectedIndex = 0
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
.setTitle("Select a Source")
@ -95,7 +98,8 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler {
dialog.window?.setDimAmount(0.8f)
} else {
// If there's only one setting, proceed with the fragment transaction
val fragment = MangaSourcePreferencesFragment().getInstance(selectedSetting.id) {
val fragment =
MangaSourcePreferencesFragment().getInstance(selectedSetting.id) {
changeUIVisibility(true)
}
parentFragmentManager.beginTransaction()

View file

@ -39,7 +39,8 @@ class InstalledNovelExtensionsFragment : Fragment(), SearchQueryHandler {
private lateinit var extensionsRecyclerView: RecyclerView
val skipIcons = loadData("skip_extension_icons") ?: false
private val novelExtensionManager: NovelExtensionManager = Injekt.get()
private val extensionsAdapter = NovelExtensionsAdapter({ pkg ->
private val extensionsAdapter = NovelExtensionsAdapter(
{ pkg ->
Toast.makeText(requireContext(), "Source is not configurable", Toast.LENGTH_SHORT)
.show()
},

View file

@ -97,7 +97,21 @@ class PlayerSettingsActivity : AppCompatActivity() {
val speeds =
arrayOf(0.25f, 0.33f, 0.5f, 0.66f, 0.75f, 1f, 1.15f, 1.25f, 1.33f, 1.5f, 1.66f, 1.75f, 2f)
arrayOf(
0.25f,
0.33f,
0.5f,
0.66f,
0.75f,
1f,
1.15f,
1.25f,
1.33f,
1.5f,
1.66f,
1.75f,
2f
)
val cursedSpeeds = arrayOf(1f, 1.25f, 1.5f, 1.75f, 2f, 2.5f, 3f, 4f, 5f, 10f, 25f, 50f)
var curSpeedArr = if (settings.cursedSpeeds) cursedSpeeds else speeds
var speedsName = curSpeedArr.map { "${it}x" }.toTypedArray()
@ -106,7 +120,8 @@ class PlayerSettingsActivity : AppCompatActivity() {
val speedDialog = AlertDialog.Builder(this, R.style.DialogTheme)
.setTitle(getString(R.string.default_speed))
binding.playerSettingsSpeed.setOnClickListener {
val dialog = speedDialog.setSingleChoiceItems(speedsName, settings.defaultSpeed) { dialog, i ->
val dialog =
speedDialog.setSingleChoiceItems(speedsName, settings.defaultSpeed) { dialog, i ->
settings.defaultSpeed = i
binding.playerSettingsSpeed.text =
getString(R.string.default_playback_speed, speedsName[i])
@ -256,7 +271,8 @@ class PlayerSettingsActivity : AppCompatActivity() {
val resizeDialog = AlertDialog.Builder(this, R.style.DialogTheme)
.setTitle(getString(R.string.default_resize_mode))
binding.playerResizeMode.setOnClickListener {
val dialog = resizeDialog.setSingleChoiceItems(resizeModes, settings.resize) { dialog, count ->
val dialog =
resizeDialog.setSingleChoiceItems(resizeModes, settings.resize) { dialog, count ->
settings.resize = count
saveData(player, settings)
dialog.dismiss()
@ -382,7 +398,10 @@ class PlayerSettingsActivity : AppCompatActivity() {
val outlineDialog = AlertDialog.Builder(this, R.style.DialogTheme)
.setTitle(getString(R.string.outline_type))
binding.videoSubOutline.setOnClickListener {
val dialog = outlineDialog.setSingleChoiceItems(typesOutline, settings.outline) { dialog, count ->
val dialog = outlineDialog.setSingleChoiceItems(
typesOutline,
settings.outline
) { dialog, count ->
settings.outline = count
saveData(player, settings)
dialog.dismiss()

View file

@ -1,17 +1,13 @@
package ani.dantotsu.settings
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.updateLayoutParams
import ani.dantotsu.NoPaddingArrayAdapter
import ani.dantotsu.R
import ani.dantotsu.databinding.ActivityReaderSettingsBinding
import ani.dantotsu.initActivity
import ani.dantotsu.loadData
import ani.dantotsu.media.novel.novelreader.NovelReaderActivity
import ani.dantotsu.navBarHeight
import ani.dantotsu.others.LangSet
import ani.dantotsu.saveData

View file

@ -67,7 +67,8 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListen
private val networkPreferences = Injekt.get<NetworkPreferences>()
private var cursedCounter = 0
@OptIn(UnstableApi::class) @SuppressLint("SetTextI18n")
@OptIn(UnstableApi::class)
@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
LangSet.setLocale(this)
@ -188,12 +189,14 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListen
"custom_theme_int",
Color.parseColor("#6200EE")
)
class CustomColorDialog : SimpleColorDialog() { //idk where to put it
override fun onPositiveButtonClick() {
restartApp()
super.onPositiveButtonClick()
}
}
val tag = "colorPicker"
CustomColorDialog().title("Custom Theme")
.colorPreset(originalColor)
@ -240,7 +243,10 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListen
AlertDialog.Builder(this, R.style.DialogTheme).setTitle("Download Manager")
var downloadManager = loadData<Int>("settings_download_manager") ?: 0
binding.settingsDownloadManager.setOnClickListener {
val dialog = downloadManagerDialog.setSingleChoiceItems(managers, downloadManager) { dialog, count ->
val dialog = downloadManagerDialog.setSingleChoiceItems(
managers,
downloadManager
) { dialog, count ->
downloadManager = count
saveData("settings_download_manager", downloadManager)
dialog.dismiss()
@ -255,7 +261,11 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListen
.setPositiveButton("Yes") { dialog, _ ->
val downloadsManager = Injekt.get<DownloadsManager>()
downloadsManager.purgeDownloads(DownloadedType.Type.ANIME)
DownloadService.sendRemoveAllDownloads(this, ExoplayerDownloadService::class.java, false)
DownloadService.sendRemoveAllDownloads(
this,
ExoplayerDownloadService::class.java,
false
)
dialog.dismiss()
}
.setNegativeButton("No") { dialog, _ ->

View file

@ -1,7 +1,7 @@
package ani.dantotsu.settings
import android.content.Intent
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.util.TypedValue
@ -9,25 +9,24 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import ani.dantotsu.BottomSheetDialogFragment
import ani.dantotsu.R
import ani.dantotsu.MainActivity
import ani.dantotsu.R
import ani.dantotsu.connections.anilist.Anilist
import ani.dantotsu.databinding.BottomSheetSettingsBinding
import ani.dantotsu.download.manga.OfflineMangaFragment
import ani.dantotsu.loadImage
import ani.dantotsu.openLinkInBrowser
import ani.dantotsu.others.imagesearch.ImageSearchActivity
import ani.dantotsu.setSafeOnClickListener
import ani.dantotsu.startMainActivity
import ani.dantotsu.currContext
import ani.dantotsu.home.AnimeFragment
import ani.dantotsu.home.HomeFragment
import ani.dantotsu.home.LoginFragment
import ani.dantotsu.home.MangaFragment
import ani.dantotsu.home.NoInternet
import ani.dantotsu.loadImage
import ani.dantotsu.offline.OfflineFragment
import ani.dantotsu.openLinkInBrowser
import ani.dantotsu.others.imagesearch.ImageSearchActivity
import ani.dantotsu.setSafeOnClickListener
import ani.dantotsu.startMainActivity
class SettingsDialogFragment() : BottomSheetDialogFragment() {
class SettingsDialogFragment : BottomSheetDialogFragment() {
private var _binding: BottomSheetSettingsBinding? = null
private val binding get() = _binding!!
@ -36,8 +35,10 @@ class SettingsDialogFragment() : BottomSheetDialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
pageType = arguments?.getSerializable("pageType") as? PageType ?: PageType.HOME
pageType2 = arguments?.getSerializable("pageType2") as? PageType2 ?: PageType2.OfflineMANGA // changed when offline home page comes
pageType2 = arguments?.getSerializable("pageType2") as? PageType2
?: PageType2.OfflineMANGA // changed when offline home page comes
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -102,7 +103,8 @@ class SettingsDialogFragment() : BottomSheetDialogFragment() {
}
binding.settingsDownloads.isChecked =
context?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)?.getBoolean("offlineMode", false) ?: false
context?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
?.getBoolean("offlineMode", false) ?: false
binding.settingsDownloads.setOnCheckedChangeListener { _, isChecked ->
if (!isChecked) {
@ -112,11 +114,16 @@ class SettingsDialogFragment() : BottomSheetDialogFragment() {
intent.putExtra("FRAGMENT_CLASS_NAME", MangaFragment::class.java.name)
startActivity(intent)
}
PageType2.OfflineHOME -> { //no offline home for now
val intent = Intent(activity, MainActivity::class.java)
intent.putExtra("FRAGMENT_CLASS_NAME", if (Anilist.token != null) HomeFragment::class.java.name else LoginFragment::class.java.name)
intent.putExtra(
"FRAGMENT_CLASS_NAME",
if (Anilist.token != null) HomeFragment::class.java.name else LoginFragment::class.java.name
)
startActivity(intent)
}
PageType2.OfflineANIME -> { //no offline anime for now
val intent = Intent(activity, MainActivity::class.java)
intent.putExtra("FRAGMENT_CLASS_NAME", AnimeFragment::class.java.name)
@ -127,14 +134,19 @@ class SettingsDialogFragment() : BottomSheetDialogFragment() {
when (pageType) {
PageType.MANGA -> {
val intent = Intent(activity, NoInternet::class.java)
intent.putExtra("FRAGMENT_CLASS_NAME", OfflineMangaFragment::class.java.name)
intent.putExtra(
"FRAGMENT_CLASS_NAME",
OfflineMangaFragment::class.java.name
)
startActivity(intent)
}
PageType.ANIME -> {
val intent = Intent(activity, NoInternet::class.java)
intent.putExtra("FRAGMENT_CLASS_NAME", OfflineFragment::class.java.name)
startActivity(intent)
}
PageType.HOME -> {
val intent = Intent(activity, NoInternet::class.java)
intent.putExtra("FRAGMENT_CLASS_NAME", OfflineFragment::class.java.name)
@ -157,9 +169,11 @@ class SettingsDialogFragment() : BottomSheetDialogFragment() {
enum class PageType {
MANGA, ANIME, HOME
}
enum class PageType2 {
OfflineMANGA, OfflineANIME, OfflineHOME
}
fun newInstance(pageType: PageType): SettingsDialogFragment {
val fragment = SettingsDialogFragment()
val args = Bundle()
@ -167,6 +181,7 @@ class SettingsDialogFragment() : BottomSheetDialogFragment() {
fragment.arguments = args
return fragment
}
fun newInstance2(pageType: PageType2): SettingsDialogFragment {
val fragment = SettingsDialogFragment()
val args = Bundle()

View file

@ -99,7 +99,8 @@ class AnimeExtensionPagingSource(
} else {
availableExtensions.filter { it.name.contains(query, ignoreCase = true) }
}
val filternfsw = if (isNsfwEnabled) filteredExtensions else filteredExtensions.filterNot { it.isNsfw }
val filternfsw =
if (isNsfwEnabled) filteredExtensions else filteredExtensions.filterNot { it.isNsfw }
return try {
val sublist = filternfsw.subList(
fromIndex = position,

View file

@ -98,7 +98,8 @@ class MangaExtensionPagingSource(
} else {
availableExtensions.filter { it.name.contains(query, ignoreCase = true) }
}
val filternfsw = if (isNsfwEnabled) filteredExtensions else filteredExtensions.filterNot { it.isNsfw }
val filternfsw =
if (isNsfwEnabled) filteredExtensions else filteredExtensions.filterNot { it.isNsfw }
return try {
val sublist = filternfsw.subList(
fromIndex = position,
@ -192,6 +193,7 @@ class MangaExtensionAdapter(private val clickListener: OnMangaInstallClickListen
}
val extensionIconImageView: ImageView = binding.extensionIconImageView
@SuppressLint("SetTextI18n")
fun bind(extension: MangaExtension.Available) {
val nsfw = if (extension.isNsfw) "(18+)" else ""

View file

@ -4,17 +4,16 @@ import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.widget.RemoteViews
import android.widget.RemoteViewsService
import androidx.core.net.toUri
import ani.dantotsu.R
import ani.dantotsu.logger
import java.io.InputStream
import java.net.HttpURLConnection
import java.net.URL
class CurrentlyAiringRemoteViewsFactory(private val context: Context, intent: Intent) : RemoteViewsService.RemoteViewsFactory {
class CurrentlyAiringRemoteViewsFactory(private val context: Context, intent: Intent) :
RemoteViewsService.RemoteViewsFactory {
private var widgetItems = mutableListOf<WidgetItem>()
override fun onCreate() {
@ -22,7 +21,11 @@ class CurrentlyAiringRemoteViewsFactory(private val context: Context, intent: In
widgetItems.clear()
logger("CurrentlyAiringRemoteViewsFactory onCreate")
widgetItems = List(4) {
WidgetItem("Show $it", "$it days $it hours $it minutes", "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg")
WidgetItem(
"Show $it",
"$it days $it hours $it minutes",
"https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"
)
}.toMutableList()
}
@ -30,11 +33,41 @@ class CurrentlyAiringRemoteViewsFactory(private val context: Context, intent: In
// 4 items for testing
logger("CurrentlyAiringRemoteViewsFactory onDataSetChanged")
widgetItems.clear()
widgetItems.add(WidgetItem("Show 1", "1 day 2 hours 3 minutes", "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"))
widgetItems.add(WidgetItem("Show 2", "2 days 3 hours 4 minutes", "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"))
widgetItems.add(WidgetItem("Show 3", "3 days 4 hours 5 minutes", "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"))
widgetItems.add(WidgetItem("Show 4", "4 days 5 hours 6 minutes", "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"))
widgetItems.add(WidgetItem("Show 5", "5 days 6 hours 7 minutes", "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"))
widgetItems.add(
WidgetItem(
"Show 1",
"1 day 2 hours 3 minutes",
"https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"
)
)
widgetItems.add(
WidgetItem(
"Show 2",
"2 days 3 hours 4 minutes",
"https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"
)
)
widgetItems.add(
WidgetItem(
"Show 3",
"3 days 4 hours 5 minutes",
"https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"
)
)
widgetItems.add(
WidgetItem(
"Show 4",
"4 days 5 hours 6 minutes",
"https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"
)
)
widgetItems.add(
WidgetItem(
"Show 5",
"5 days 6 hours 7 minutes",
"https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"
)
)
}
override fun onDestroy() {

View file

@ -3,6 +3,7 @@ package ani.dantotsu.widgets
import android.content.Intent
import android.widget.RemoteViewsService
import ani.dantotsu.logger
class CurrentlyAiringRemoteViewsService : RemoteViewsService() {
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
logger("CurrentlyAiringRemoteViewsFactory onGetViewFactory")

View file

@ -20,7 +20,11 @@ import ani.dantotsu.R
* App Widget Configuration implemented in [CurrentlyAiringWidgetConfigureActivity]
*/
class CurrentlyAiringWidget : AppWidgetProvider() {
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
appWidgetIds.forEach { appWidgetId ->
val intent = Intent(context, CurrentlyAiringRemoteViewsService::class.java).apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
@ -36,6 +40,7 @@ class CurrentlyAiringWidget : AppWidgetProvider() {
}
super.onUpdate(context, appWidgetManager, appWidgetIds)
}
override fun onDeleted(context: Context, appWidgetIds: IntArray) {
// When the user deletes the widget, delete the preference associated with it.
for (appWidgetId in appWidgetIds) {
@ -51,6 +56,7 @@ class CurrentlyAiringWidget : AppWidgetProvider() {
override fun onDisabled(context: Context) {
super.onDisabled(context)
}
companion object {
fun updateAppWidget(
context: Context,
@ -60,10 +66,15 @@ class CurrentlyAiringWidget : AppWidgetProvider() {
) {
// Create an intent to launch the configuration activity when the widget is clicked
val intent = Intent(context, CurrentlyAiringWidgetConfigureActivity::class.java)
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
val pendingIntent =
PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
// Get the gradient drawable resource and update its start color with the user-selected color
val gradientDrawable = ResourcesCompat.getDrawable(context.resources, R.drawable.gradient_background, null) as GradientDrawable
val gradientDrawable = ResourcesCompat.getDrawable(
context.resources,
R.drawable.gradient_background,
null
) as GradientDrawable
gradientDrawable.colors = intArrayOf(color, Color.GRAY) // End color is gray.
// Create the RemoteViews object and set the background

View file

@ -57,7 +57,7 @@ class CurrentlyAiringWidgetConfigureActivity : Activity() {
binding = CurrentlyAiringWidgetConfigureBinding.inflate(layoutInflater)
setContentView(binding.root)
appWidgetText = binding.appwidgetText as EditText
appWidgetText = binding.appwidgetText
binding.addButton.setOnClickListener(onClickListener)
// Find the widget id from the intent.