clean Sad's shit
This commit is contained in:
parent
84e300482a
commit
cc5b512441
53 changed files with 652 additions and 466 deletions
|
@ -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,12 +79,13 @@ class AnimeDownloaderService : Service() {
|
|||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
notificationManager = NotificationManagerCompat.from(this)
|
||||
builder = NotificationCompat.Builder(this, Notifications.CHANNEL_DOWNLOADER_PROGRESS).apply {
|
||||
setContentTitle("Anime Download Progress")
|
||||
setSmallIcon(R.drawable.ic_round_download_24)
|
||||
priority = NotificationCompat.PRIORITY_DEFAULT
|
||||
setOnlyAlertOnce(true)
|
||||
}
|
||||
builder =
|
||||
NotificationCompat.Builder(this, Notifications.CHANNEL_DOWNLOADER_PROGRESS).apply {
|
||||
setContentTitle("Anime Download Progress")
|
||||
setSmallIcon(R.drawable.ic_round_download_24)
|
||||
priority = NotificationCompat.PRIORITY_DEFAULT
|
||||
setOnlyAlertOnce(true)
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
startForeground(
|
||||
NOTIFICATION_ID,
|
||||
|
@ -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:" +
|
||||
" ${download.failureReason}" +
|
||||
" url: ${task.video.file.url}" +
|
||||
" title: ${task.title}" +
|
||||
" episode: ${task.episode}"))
|
||||
FirebaseCrashlytics.getInstance().recordException(
|
||||
Exception(
|
||||
"Anime Download failed:" +
|
||||
" ${download.failureReason}" +
|
||||
" url: ${task.video.file.url}" +
|
||||
" title: ${task.title}" +
|
||||
" 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 {
|
||||
|
|
|
@ -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
|
||||
|
@ -38,14 +39,14 @@ class OfflineMangaAdapter(
|
|||
@SuppressLint("SetTextI18n")
|
||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
|
||||
|
||||
val view: View = convertView ?: when(style) {
|
||||
val view: View = convertView ?: when (style) {
|
||||
0 -> inflater.inflate(R.layout.item_media_large, parent, false) // large view
|
||||
1 -> inflater.inflate(R.layout.item_media_compact, parent, false) // compact view
|
||||
else -> inflater.inflate(R.layout.item_media_compact, parent, false) // compact view
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -55,22 +56,21 @@ class OfflineMangaAdapter(
|
|||
val type = view.findViewById<TextView>(R.id.itemCompactRelation)
|
||||
val typeView = view.findViewById<LinearLayout>(R.id.itemCompactType)
|
||||
|
||||
if (style == 0){
|
||||
if (style == 0) {
|
||||
val bannerView = view.findViewById<ImageView>(R.id.itemCompactBanner) // for large view
|
||||
val chapters = view.findViewById<TextView>(R.id.itemTotal)
|
||||
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
|
||||
}
|
||||
|
||||
// Bind item data to the views
|
||||
typeimage.setImageResource(if (item.type == "Novel" ) R.drawable.ic_round_book_24 else R.drawable.ic_round_import_contacts_24)
|
||||
typeimage.setImageResource(if (item.type == "Novel") R.drawable.ic_round_book_24 else R.drawable.ic_round_import_contacts_24)
|
||||
type.text = item.type
|
||||
typeView.visibility = View.VISIBLE
|
||||
imageView.setImageURI(item.image)
|
||||
|
@ -103,8 +103,9 @@ class OfflineMangaAdapter(
|
|||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun notifyNewGrid(){
|
||||
style = context.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).getInt("offline_view", 0)
|
||||
fun notifyNewGrid() {
|
||||
style =
|
||||
context.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).getInt("offline_view", 0)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
|
@ -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 }) {
|
||||
DownloadedType.Type.MANGA
|
||||
} else {
|
||||
DownloadedType.Type.NOVEL
|
||||
}
|
||||
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") { _, _ ->
|
||||
|
@ -194,7 +200,7 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
|||
builder.setNegativeButton("No") { _, _ ->
|
||||
// Do nothing
|
||||
}
|
||||
val dialog = builder.show()
|
||||
val dialog = builder.show()
|
||||
dialog.window?.setDimAmount(0.8f)
|
||||
true
|
||||
}
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ data class OfflineMangaModel(
|
|||
val title: String,
|
||||
val score: String,
|
||||
val totalchapter: String,
|
||||
val readchapter : String,
|
||||
val readchapter: String,
|
||||
val type: String,
|
||||
val chapters: String,
|
||||
val isOngoing: Boolean,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -246,7 +244,7 @@ object Helper {
|
|||
.queryDownload(title, episode, DownloadedType.Type.ANIME)
|
||||
|
||||
if (downloadCheck) {
|
||||
AlertDialog.Builder(context , R.style.MyPopup)
|
||||
AlertDialog.Builder(context, R.style.MyPopup)
|
||||
.setTitle("Download Exists")
|
||||
.setMessage("A download for this episode already exists. Do you want to overwrite it?")
|
||||
.setPositiveButton("Yes") { _, _ ->
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue