clean Sad's shit
This commit is contained in:
parent
84e300482a
commit
cc5b512441
53 changed files with 652 additions and 466 deletions
|
@ -11,12 +11,14 @@ import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.animation.AnticipateInterpolator
|
import android.view.animation.AnticipateInterpolator
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.activity.addCallback
|
import androidx.activity.addCallback
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
|
import androidx.annotation.OptIn
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.animation.doOnEnd
|
import androidx.core.animation.doOnEnd
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
@ -26,12 +28,14 @@ import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.media3.common.util.UnstableApi
|
||||||
|
import androidx.media3.exoplayer.offline.Download
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||||
import ani.dantotsu.App.Companion.context
|
|
||||||
import ani.dantotsu.connections.anilist.Anilist
|
import ani.dantotsu.connections.anilist.Anilist
|
||||||
import ani.dantotsu.connections.anilist.AnilistHomeViewModel
|
import ani.dantotsu.connections.anilist.AnilistHomeViewModel
|
||||||
import ani.dantotsu.databinding.ActivityMainBinding
|
import ani.dantotsu.databinding.ActivityMainBinding
|
||||||
import ani.dantotsu.databinding.SplashScreenBinding
|
import ani.dantotsu.databinding.SplashScreenBinding
|
||||||
|
import ani.dantotsu.download.video.Helper
|
||||||
import ani.dantotsu.home.AnimeFragment
|
import ani.dantotsu.home.AnimeFragment
|
||||||
import ani.dantotsu.home.HomeFragment
|
import ani.dantotsu.home.HomeFragment
|
||||||
import ani.dantotsu.home.LoginFragment
|
import ani.dantotsu.home.LoginFragment
|
||||||
|
@ -46,6 +50,7 @@ import ani.dantotsu.themes.ThemeManager
|
||||||
import io.noties.markwon.Markwon
|
import io.noties.markwon.Markwon
|
||||||
import io.noties.markwon.SoftBreakAddsNewLinePlugin
|
import io.noties.markwon.SoftBreakAddsNewLinePlugin
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
@ -61,6 +66,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
private var uiSettings = UserInterfaceSettings()
|
private var uiSettings = UserInterfaceSettings()
|
||||||
|
|
||||||
|
|
||||||
|
@OptIn(UnstableApi::class)
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
ThemeManager(this).applyTheme()
|
ThemeManager(this).applyTheme()
|
||||||
LangSet.setLocale(this)
|
LangSet.setLocale(this)
|
||||||
|
@ -149,48 +155,49 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isOnline(this)) {
|
if (!isOnline(this)) {
|
||||||
snackString(this@MainActivity.getString(R.string.no_internet_connection))
|
snackString(this@MainActivity.getString(R.string.no_internet_connection))
|
||||||
startActivity(Intent(this, NoInternet::class.java))
|
startActivity(Intent(this, NoInternet::class.java))
|
||||||
getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
|
getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
|
||||||
.edit()
|
.edit()
|
||||||
.putBoolean("offlineMode", true)
|
.putBoolean("offlineMode", true)
|
||||||
.apply()} else {
|
.apply()
|
||||||
getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
|
} else {
|
||||||
.edit()
|
getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
|
||||||
.putBoolean("offlineMode", false)
|
.edit()
|
||||||
.apply()
|
.putBoolean("offlineMode", false)
|
||||||
val model: AnilistHomeViewModel by viewModels()
|
.apply()
|
||||||
model.genres.observe(this) { it ->
|
val model: AnilistHomeViewModel by viewModels()
|
||||||
if (it != null) {
|
model.genres.observe(this) { it ->
|
||||||
if (it) {
|
if (it != null) {
|
||||||
val navbar = binding.includedNavbar.navbar
|
if (it) {
|
||||||
bottomBar = navbar
|
val navbar = binding.includedNavbar.navbar
|
||||||
navbar.visibility = View.VISIBLE
|
bottomBar = navbar
|
||||||
binding.mainProgressBar.visibility = View.GONE
|
navbar.visibility = View.VISIBLE
|
||||||
val mainViewPager = binding.viewpager
|
binding.mainProgressBar.visibility = View.GONE
|
||||||
mainViewPager.isUserInputEnabled = false
|
val mainViewPager = binding.viewpager
|
||||||
mainViewPager.adapter = ViewPagerAdapter(supportFragmentManager, lifecycle)
|
mainViewPager.isUserInputEnabled = false
|
||||||
mainViewPager.setPageTransformer(ZoomOutPageTransformer(uiSettings))
|
mainViewPager.adapter = ViewPagerAdapter(supportFragmentManager, lifecycle)
|
||||||
navbar.setOnTabSelectListener(object :
|
mainViewPager.setPageTransformer(ZoomOutPageTransformer(uiSettings))
|
||||||
AnimatedBottomBar.OnTabSelectListener {
|
navbar.setOnTabSelectListener(object :
|
||||||
override fun onTabSelected(
|
AnimatedBottomBar.OnTabSelectListener {
|
||||||
lastIndex: Int,
|
override fun onTabSelected(
|
||||||
lastTab: AnimatedBottomBar.Tab?,
|
lastIndex: Int,
|
||||||
newIndex: Int,
|
lastTab: AnimatedBottomBar.Tab?,
|
||||||
newTab: AnimatedBottomBar.Tab
|
newIndex: Int,
|
||||||
) {
|
newTab: AnimatedBottomBar.Tab
|
||||||
navbar.animate().translationZ(12f).setDuration(200).start()
|
) {
|
||||||
selectedOption = newIndex
|
navbar.animate().translationZ(12f).setDuration(200).start()
|
||||||
mainViewPager.setCurrentItem(newIndex, false)
|
selectedOption = newIndex
|
||||||
|
mainViewPager.setCurrentItem(newIndex, false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
navbar.selectTabAt(selectedOption)
|
||||||
|
mainViewPager.post { mainViewPager.setCurrentItem(selectedOption, false) }
|
||||||
|
} else {
|
||||||
|
binding.mainProgressBar.visibility = View.GONE
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
navbar.selectTabAt(selectedOption)
|
|
||||||
mainViewPager.post { mainViewPager.setCurrentItem(selectedOption, false) }
|
|
||||||
} else {
|
|
||||||
binding.mainProgressBar.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
//Load Data
|
//Load Data
|
||||||
if (!load) {
|
if (!load) {
|
||||||
scope.launch(Dispatchers.IO) {
|
scope.launch(Dispatchers.IO) {
|
||||||
|
@ -249,7 +256,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
val index = Helper.downloadManager(this@MainActivity).downloadIndex
|
val index = Helper.downloadManager(this@MainActivity).downloadIndex
|
||||||
val downloadCursor = index.getDownloads()
|
val downloadCursor = index.getDownloads()
|
||||||
while (downloadCursor.moveToNext()) {
|
while (downloadCursor.moveToNext()) {
|
||||||
val download = downloadCursor.download
|
val download = downloadCursor.download
|
||||||
|
@ -267,8 +274,6 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ import androidx.annotation.OptIn
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import androidx.media3.database.StandaloneDatabaseProvider
|
import androidx.media3.database.StandaloneDatabaseProvider
|
||||||
import androidx.media3.datasource.cache.SimpleCache
|
|
||||||
import ani.dantotsu.download.DownloadsManager
|
import ani.dantotsu.download.DownloadsManager
|
||||||
import ani.dantotsu.media.manga.MangaCache
|
import ani.dantotsu.media.manga.MangaCache
|
||||||
import ani.dantotsu.parsers.novel.NovelExtensionManager
|
import ani.dantotsu.parsers.novel.NovelExtensionManager
|
||||||
|
@ -31,7 +30,8 @@ import uy.kohesive.injekt.api.addSingletonFactory
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
class AppModule(val app: Application) : InjektModule {
|
class AppModule(val app: Application) : InjektModule {
|
||||||
@OptIn(UnstableApi::class) override fun InjektRegistrar.registerInjectables() {
|
@OptIn(UnstableApi::class)
|
||||||
|
override fun InjektRegistrar.registerInjectables() {
|
||||||
addSingleton(app)
|
addSingleton(app)
|
||||||
|
|
||||||
addSingletonFactory { DownloadsManager(app) }
|
addSingletonFactory { DownloadsManager(app) }
|
||||||
|
|
|
@ -10,7 +10,6 @@ import ani.dantotsu.toast
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlin.math.roundToInt
|
|
||||||
|
|
||||||
fun updateProgress(media: Media, number: String) {
|
fun updateProgress(media: Media, number: String) {
|
||||||
val incognito = currContext()?.getSharedPreferences("Dantotsu", 0)
|
val incognito = currContext()?.getSharedPreferences("Dantotsu", 0)
|
||||||
|
|
|
@ -17,7 +17,6 @@ import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import androidx.media3.exoplayer.offline.Download
|
|
||||||
import androidx.media3.exoplayer.offline.DownloadManager
|
import androidx.media3.exoplayer.offline.DownloadManager
|
||||||
import androidx.media3.exoplayer.offline.DownloadService
|
import androidx.media3.exoplayer.offline.DownloadService
|
||||||
import ani.dantotsu.FileUrl
|
import ani.dantotsu.FileUrl
|
||||||
|
@ -25,8 +24,8 @@ import ani.dantotsu.R
|
||||||
import ani.dantotsu.currActivity
|
import ani.dantotsu.currActivity
|
||||||
import ani.dantotsu.download.DownloadedType
|
import ani.dantotsu.download.DownloadedType
|
||||||
import ani.dantotsu.download.DownloadsManager
|
import ani.dantotsu.download.DownloadsManager
|
||||||
import ani.dantotsu.download.video.Helper
|
|
||||||
import ani.dantotsu.download.video.ExoplayerDownloadService
|
import ani.dantotsu.download.video.ExoplayerDownloadService
|
||||||
|
import ani.dantotsu.download.video.Helper
|
||||||
import ani.dantotsu.logger
|
import ani.dantotsu.logger
|
||||||
import ani.dantotsu.media.Media
|
import ani.dantotsu.media.Media
|
||||||
import ani.dantotsu.media.anime.AnimeWatchFragment
|
import ani.dantotsu.media.anime.AnimeWatchFragment
|
||||||
|
@ -80,12 +79,13 @@ class AnimeDownloaderService : Service() {
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
notificationManager = NotificationManagerCompat.from(this)
|
notificationManager = NotificationManagerCompat.from(this)
|
||||||
builder = NotificationCompat.Builder(this, Notifications.CHANNEL_DOWNLOADER_PROGRESS).apply {
|
builder =
|
||||||
setContentTitle("Anime Download Progress")
|
NotificationCompat.Builder(this, Notifications.CHANNEL_DOWNLOADER_PROGRESS).apply {
|
||||||
setSmallIcon(R.drawable.ic_round_download_24)
|
setContentTitle("Anime Download Progress")
|
||||||
priority = NotificationCompat.PRIORITY_DEFAULT
|
setSmallIcon(R.drawable.ic_round_download_24)
|
||||||
setOnlyAlertOnce(true)
|
priority = NotificationCompat.PRIORITY_DEFAULT
|
||||||
}
|
setOnlyAlertOnce(true)
|
||||||
|
}
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
startForeground(
|
startForeground(
|
||||||
NOTIFICATION_ID,
|
NOTIFICATION_ID,
|
||||||
|
@ -154,7 +154,9 @@ class AnimeDownloaderService : Service() {
|
||||||
fun cancelDownload(taskName: String) {
|
fun cancelDownload(taskName: String) {
|
||||||
CoroutineScope(Dispatchers.Default).launch {
|
CoroutineScope(Dispatchers.Default).launch {
|
||||||
mutex.withLock {
|
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(
|
DownloadService.sendRemoveDownload(
|
||||||
this@AnimeDownloaderService,
|
this@AnimeDownloaderService,
|
||||||
ExoplayerDownloadService::class.java,
|
ExoplayerDownloadService::class.java,
|
||||||
|
@ -188,7 +190,8 @@ class AnimeDownloaderService : Service() {
|
||||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
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 {
|
try {
|
||||||
val downloadManager = Helper.downloadManager(this@AnimeDownloaderService)
|
val downloadManager = Helper.downloadManager(this@AnimeDownloaderService)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
@ -212,11 +215,13 @@ class AnimeDownloaderService : Service() {
|
||||||
Helper.downloadVideo(
|
Helper.downloadVideo(
|
||||||
it,
|
it,
|
||||||
task.video,
|
task.video,
|
||||||
task.subtitle)
|
task.subtitle
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
saveMediaInfo(task)
|
saveMediaInfo(task)
|
||||||
val downloadStarted = hasDownloadStarted(downloadManager, task, 30000) // 30 seconds timeout
|
val downloadStarted =
|
||||||
|
hasDownloadStarted(downloadManager, task, 30000) // 30 seconds timeout
|
||||||
|
|
||||||
if (!downloadStarted) {
|
if (!downloadStarted) {
|
||||||
logger("Download failed to start")
|
logger("Download failed to start")
|
||||||
|
@ -238,11 +243,15 @@ class AnimeDownloaderService : Service() {
|
||||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
||||||
snackString("${task.title} - ${task.episode} Download failed")
|
snackString("${task.title} - ${task.episode} Download failed")
|
||||||
logger("Download failed: ${download.failureReason}")
|
logger("Download failed: ${download.failureReason}")
|
||||||
FirebaseCrashlytics.getInstance().recordException(Exception("Anime Download failed:" +
|
FirebaseCrashlytics.getInstance().recordException(
|
||||||
" ${download.failureReason}" +
|
Exception(
|
||||||
" url: ${task.video.file.url}" +
|
"Anime Download failed:" +
|
||||||
" title: ${task.title}" +
|
" ${download.failureReason}" +
|
||||||
" episode: ${task.episode}"))
|
" url: ${task.video.file.url}" +
|
||||||
|
" title: ${task.title}" +
|
||||||
|
" episode: ${task.episode}"
|
||||||
|
)
|
||||||
|
)
|
||||||
broadcastDownloadFailed(task.getTaskName())
|
broadcastDownloadFailed(task.getTaskName())
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -251,7 +260,10 @@ class AnimeDownloaderService : Service() {
|
||||||
builder.setContentText("${task.title} - ${task.episode} Download completed")
|
builder.setContentText("${task.title} - ${task.episode} Download completed")
|
||||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
||||||
snackString("${task.title} - ${task.episode} Download completed")
|
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.getTaskName(),
|
||||||
task.video.file.url
|
task.video.file.url
|
||||||
).apply()
|
).apply()
|
||||||
|
@ -272,7 +284,10 @@ class AnimeDownloaderService : Service() {
|
||||||
snackString("${task.title} - ${task.episode} Download stopped")
|
snackString("${task.title} - ${task.episode} Download stopped")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
broadcastDownloadProgress(task.getTaskName(), download.percentDownloaded.toInt())
|
broadcastDownloadProgress(
|
||||||
|
task.getTaskName(),
|
||||||
|
download.percentDownloaded.toInt()
|
||||||
|
)
|
||||||
if (notifi) {
|
if (notifi) {
|
||||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
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()
|
val startTime = System.currentTimeMillis()
|
||||||
while (System.currentTimeMillis() - startTime < timeout) {
|
while (System.currentTimeMillis() - startTime < timeout) {
|
||||||
val download = downloadManager.downloadIndex.getDownload(task.video.file.url)
|
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") }
|
media.banner = media.banner?.let { downloadImage(it, directory, "banner.jpg") }
|
||||||
if (task.episodeImage != null) {
|
if (task.episodeImage != null) {
|
||||||
media.anime?.episodes?.get(task.episode)?.let { episode ->
|
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(
|
FileUrl(
|
||||||
it
|
it
|
||||||
)
|
)
|
||||||
|
@ -412,7 +436,8 @@ class AnimeDownloaderService : Service() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private val cancelReceiver = object : BroadcastReceiver() {
|
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) {
|
if (intent.action == ACTION_CANCEL_DOWNLOAD) {
|
||||||
val taskName = intent.getStringExtra(EXTRA_TASK_NAME)
|
val taskName = intent.getStringExtra(EXTRA_TASK_NAME)
|
||||||
taskName?.let {
|
taskName?.let {
|
||||||
|
|
|
@ -21,7 +21,8 @@ class OfflineMangaAdapter(
|
||||||
private val inflater: LayoutInflater =
|
private val inflater: LayoutInflater =
|
||||||
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||||
private var originalItems: List<OfflineMangaModel> = items
|
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 {
|
override fun getCount(): Int {
|
||||||
return items.size
|
return items.size
|
||||||
|
@ -38,14 +39,14 @@ class OfflineMangaAdapter(
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
|
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
|
0 -> inflater.inflate(R.layout.item_media_large, parent, false) // large view
|
||||||
1 -> inflater.inflate(R.layout.item_media_compact, parent, false) // compact 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
|
else -> inflater.inflate(R.layout.item_media_compact, parent, false) // compact view
|
||||||
}
|
}
|
||||||
|
|
||||||
val item = getItem(position) as OfflineMangaModel
|
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 titleTextView = view.findViewById<TextView>(R.id.itemCompactTitle)
|
||||||
val itemScore = view.findViewById<TextView>(R.id.itemCompactScore)
|
val itemScore = view.findViewById<TextView>(R.id.itemCompactScore)
|
||||||
val itemScoreBG = view.findViewById<View>(R.id.itemCompactScoreBG)
|
val itemScoreBG = view.findViewById<View>(R.id.itemCompactScoreBG)
|
||||||
|
@ -55,22 +56,21 @@ class OfflineMangaAdapter(
|
||||||
val type = view.findViewById<TextView>(R.id.itemCompactRelation)
|
val type = view.findViewById<TextView>(R.id.itemCompactRelation)
|
||||||
val typeView = view.findViewById<LinearLayout>(R.id.itemCompactType)
|
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 bannerView = view.findViewById<ImageView>(R.id.itemCompactBanner) // for large view
|
||||||
val chapters = view.findViewById<TextView>(R.id.itemTotal)
|
val chapters = view.findViewById<TextView>(R.id.itemTotal)
|
||||||
chapters.text = " Chapters"
|
chapters.text = " Chapters"
|
||||||
bannerView.setImageURI(item.banner)
|
bannerView.setImageURI(item.banner)
|
||||||
totalchapter.text = item.totalchapter
|
totalchapter.text = item.totalchapter
|
||||||
}
|
} else if (style == 1) {
|
||||||
|
val readchapter =
|
||||||
else if (style == 1){
|
view.findViewById<TextView>(R.id.itemCompactUserProgress) // for compact view
|
||||||
val readchapter = view.findViewById<TextView>(R.id.itemCompactUserProgress) // for compact view
|
|
||||||
readchapter.text = item.readchapter
|
readchapter.text = item.readchapter
|
||||||
totalchapter.text = " | " + item.totalchapter
|
totalchapter.text = " | " + item.totalchapter
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind item data to the views
|
// 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
|
type.text = item.type
|
||||||
typeView.visibility = View.VISIBLE
|
typeView.visibility = View.VISIBLE
|
||||||
imageView.setImageURI(item.image)
|
imageView.setImageURI(item.image)
|
||||||
|
@ -103,8 +103,9 @@ class OfflineMangaAdapter(
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun notifyNewGrid(){
|
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()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -20,6 +20,7 @@ import android.widget.AbsListView
|
||||||
import android.widget.AutoCompleteTextView
|
import android.widget.AutoCompleteTextView
|
||||||
import android.widget.GridView
|
import android.widget.GridView
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.cardview.widget.CardView
|
import androidx.cardview.widget.CardView
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
@ -76,7 +77,8 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
||||||
|
|
||||||
val animeUserAvatar = view.findViewById<ShapeableImageView>(R.id.offlineMangaUserAvatar)
|
val animeUserAvatar = view.findViewById<ShapeableImageView>(R.id.offlineMangaUserAvatar)
|
||||||
animeUserAvatar.setSafeOnClickListener {
|
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")
|
dialogFragment.show((it.context as AppCompatActivity).supportFragmentManager, "dialog")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +94,7 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
||||||
override fun afterTextChanged(s: Editable?) {
|
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) {
|
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||||
|
@ -143,7 +145,8 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
||||||
adapter.notifyNewGrid()
|
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
|
gridView.visibility = View.VISIBLE
|
||||||
getDownloads()
|
getDownloads()
|
||||||
|
|
||||||
|
@ -173,17 +176,20 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
val total = view.findViewById<TextView>(R.id.total)
|
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 ->
|
gridView.setOnItemLongClickListener { parent, view, position, id ->
|
||||||
// Get the OfflineMangaModel that was clicked
|
// Get the OfflineMangaModel that was clicked
|
||||||
val item = adapter.getItem(position) as OfflineMangaModel
|
val item = adapter.getItem(position) as OfflineMangaModel
|
||||||
val type: DownloadedType.Type = if (downloadManager.mangaDownloadedTypes.any { it.title == item.title }) {
|
val type: DownloadedType.Type =
|
||||||
DownloadedType.Type.MANGA
|
if (downloadManager.mangaDownloadedTypes.any { it.title == item.title }) {
|
||||||
} else {
|
DownloadedType.Type.MANGA
|
||||||
DownloadedType.Type.NOVEL
|
} else {
|
||||||
}
|
DownloadedType.Type.NOVEL
|
||||||
|
}
|
||||||
// Alert dialog to confirm deletion
|
// 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.setTitle("Delete ${item.title}?")
|
||||||
builder.setMessage("Are you sure you want to delete ${item.title}?")
|
builder.setMessage("Are you sure you want to delete ${item.title}?")
|
||||||
builder.setPositiveButton("Yes") { _, _ ->
|
builder.setPositiveButton("Yes") { _, _ ->
|
||||||
|
@ -194,7 +200,7 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
||||||
builder.setNegativeButton("No") { _, _ ->
|
builder.setNegativeButton("No") { _, _ ->
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
val dialog = builder.show()
|
val dialog = builder.show()
|
||||||
dialog.window?.setDimAmount(0.8f)
|
dialog.window?.setDimAmount(0.8f)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -253,7 +259,12 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
||||||
// Implement behavior for different scroll states if needed
|
// 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 first = view.getChildAt(0)
|
||||||
val visibility = first != null && first.top < -height
|
val visibility = first != null && first.top < -height
|
||||||
scrollTop.visibility = if (visibility) View.VISIBLE else View.GONE
|
scrollTop.visibility = if (visibility) View.VISIBLE else View.GONE
|
||||||
|
@ -365,17 +376,40 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
||||||
val title = mediaModel.nameMAL ?: mediaModel.nameRomaji
|
val title = mediaModel.nameMAL ?: mediaModel.nameRomaji
|
||||||
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()
|
||||||
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 isUserScored = mediaModel.userScore != 0
|
||||||
val readchapter = (mediaModel.userProgress ?: "~").toString()
|
val readchapter = (mediaModel.userProgress ?: "~").toString()
|
||||||
val totalchapter = "${mediaModel.manga?.totalChapters ?: "??"}"
|
val totalchapter = "${mediaModel.manga?.totalChapters ?: "??"}"
|
||||||
val chapters = " Chapters"
|
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) {
|
} catch (e: Exception) {
|
||||||
logger("Error loading media.json: ${e.message}")
|
logger("Error loading media.json: ${e.message}")
|
||||||
logger(e.printStackTrace())
|
logger(e.printStackTrace())
|
||||||
FirebaseCrashlytics.getInstance().recordException(e)
|
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 title: String,
|
||||||
val score: String,
|
val score: String,
|
||||||
val totalchapter: String,
|
val totalchapter: String,
|
||||||
val readchapter : String,
|
val readchapter: String,
|
||||||
val type: String,
|
val type: String,
|
||||||
val chapters: String,
|
val chapters: String,
|
||||||
val isOngoing: Boolean,
|
val isOngoing: Boolean,
|
||||||
|
|
|
@ -11,7 +11,8 @@ import androidx.media3.exoplayer.scheduler.Scheduler
|
||||||
import ani.dantotsu.R
|
import ani.dantotsu.R
|
||||||
|
|
||||||
@UnstableApi
|
@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 {
|
companion object {
|
||||||
private const val JOB_ID = 1
|
private const val JOB_ID = 1
|
||||||
private const val FOREGROUND_NOTIFICATION_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.C
|
||||||
import androidx.media3.common.MediaItem
|
import androidx.media3.common.MediaItem
|
||||||
import androidx.media3.common.MimeTypes
|
import androidx.media3.common.MimeTypes
|
||||||
import androidx.media3.common.TrackSelectionParameters
|
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import androidx.media3.database.StandaloneDatabaseProvider
|
import androidx.media3.database.StandaloneDatabaseProvider
|
||||||
import androidx.media3.datasource.DataSource
|
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.DownloadManager
|
||||||
import androidx.media3.exoplayer.offline.DownloadService
|
import androidx.media3.exoplayer.offline.DownloadService
|
||||||
import androidx.media3.exoplayer.scheduler.Requirements
|
import androidx.media3.exoplayer.scheduler.Requirements
|
||||||
import androidx.media3.ui.TrackSelectionDialogBuilder
|
|
||||||
import ani.dantotsu.R
|
import ani.dantotsu.R
|
||||||
import ani.dantotsu.defaultHeaders
|
import ani.dantotsu.defaultHeaders
|
||||||
import ani.dantotsu.download.DownloadedType
|
import ani.dantotsu.download.DownloadedType
|
||||||
|
@ -246,7 +244,7 @@ object Helper {
|
||||||
.queryDownload(title, episode, DownloadedType.Type.ANIME)
|
.queryDownload(title, episode, DownloadedType.Type.ANIME)
|
||||||
|
|
||||||
if (downloadCheck) {
|
if (downloadCheck) {
|
||||||
AlertDialog.Builder(context , R.style.MyPopup)
|
AlertDialog.Builder(context, R.style.MyPopup)
|
||||||
.setTitle("Download Exists")
|
.setTitle("Download Exists")
|
||||||
.setMessage("A download for this episode already exists. Do you want to overwrite it?")
|
.setMessage("A download for this episode already exists. Do you want to overwrite it?")
|
||||||
.setPositiveButton("Yes") { _, _ ->
|
.setPositiveButton("Yes") { _, _ ->
|
||||||
|
|
|
@ -2,7 +2,6 @@ package ani.dantotsu.home
|
||||||
|
|
||||||
import android.animation.ObjectAnimator
|
import android.animation.ObjectAnimator
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
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.AnilistAnimeViewModel
|
||||||
import ani.dantotsu.connections.anilist.SearchResults
|
import ani.dantotsu.connections.anilist.SearchResults
|
||||||
import ani.dantotsu.connections.anilist.getUserId
|
import ani.dantotsu.connections.anilist.getUserId
|
||||||
import ani.dantotsu.currContext
|
|
||||||
import ani.dantotsu.databinding.FragmentAnimeBinding
|
import ani.dantotsu.databinding.FragmentAnimeBinding
|
||||||
import ani.dantotsu.loadData
|
import ani.dantotsu.loadData
|
||||||
import ani.dantotsu.media.MediaAdaptor
|
import ani.dantotsu.media.MediaAdaptor
|
||||||
|
@ -52,14 +50,14 @@ class AnimeFragment : Fragment() {
|
||||||
private lateinit var animePageAdapter: AnimePageAdapter
|
private lateinit var animePageAdapter: AnimePageAdapter
|
||||||
|
|
||||||
private var uiSettings: UserInterfaceSettings =
|
private var uiSettings: UserInterfaceSettings =
|
||||||
loadData("ui_settings") ?: UserInterfaceSettings()
|
loadData("ui_settings") ?: UserInterfaceSettings()
|
||||||
|
|
||||||
val model: AnilistAnimeViewModel by activityViewModels()
|
val model: AnilistAnimeViewModel by activityViewModels()
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View {
|
): View {
|
||||||
_binding = FragmentAnimeBinding.inflate(inflater, container, false)
|
_binding = FragmentAnimeBinding.inflate(inflater, container, false)
|
||||||
return binding.root
|
return binding.root
|
||||||
|
@ -81,11 +79,11 @@ class AnimeFragment : Fragment() {
|
||||||
if (displayCutout != null) {
|
if (displayCutout != null) {
|
||||||
if (displayCutout.boundingRects.size > 0) {
|
if (displayCutout.boundingRects.size > 0) {
|
||||||
height = max(
|
height = max(
|
||||||
statusBarHeight,
|
statusBarHeight,
|
||||||
min(
|
min(
|
||||||
displayCutout.boundingRects[0].width(),
|
displayCutout.boundingRects[0].width(),
|
||||||
displayCutout.boundingRects[0].height()
|
displayCutout.boundingRects[0].height()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,12 +102,12 @@ class AnimeFragment : Fragment() {
|
||||||
if (model.notSet) {
|
if (model.notSet) {
|
||||||
model.notSet = false
|
model.notSet = false
|
||||||
model.searchResults = SearchResults(
|
model.searchResults = SearchResults(
|
||||||
"ANIME",
|
"ANIME",
|
||||||
isAdult = false,
|
isAdult = false,
|
||||||
onList = false,
|
onList = false,
|
||||||
results = mutableListOf(),
|
results = mutableListOf(),
|
||||||
hasNextPage = true,
|
hasNextPage = true,
|
||||||
sort = Anilist.sortBy[1]
|
sort = Anilist.sortBy[1]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val popularAdaptor = MediaAdaptor(1, model.searchResults.results, requireActivity())
|
val popularAdaptor = MediaAdaptor(1, model.searchResults.results, requireActivity())
|
||||||
|
@ -177,7 +175,7 @@ class AnimeFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.animePageRecyclerView.addOnScrollListener(object :
|
binding.animePageRecyclerView.addOnScrollListener(object :
|
||||||
RecyclerView.OnScrollListener() {
|
RecyclerView.OnScrollListener() {
|
||||||
override fun onScrolled(v: RecyclerView, dx: Int, dy: Int) {
|
override fun onScrolled(v: RecyclerView, dx: Int, dy: Int) {
|
||||||
if (!v.canScrollVertically(1)) {
|
if (!v.canScrollVertically(1)) {
|
||||||
if (model.searchResults.hasNextPage && model.searchResults.results.isNotEmpty() && !loading) {
|
if (model.searchResults.hasNextPage && model.searchResults.results.isNotEmpty() && !loading) {
|
||||||
|
@ -217,19 +215,19 @@ class AnimeFragment : Fragment() {
|
||||||
model.getTrending().observe(viewLifecycleOwner) {
|
model.getTrending().observe(viewLifecycleOwner) {
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
animePageAdapter.updateTrending(
|
animePageAdapter.updateTrending(
|
||||||
MediaAdaptor(
|
MediaAdaptor(
|
||||||
if (uiSettings.smallView) 3 else 2,
|
if (uiSettings.smallView) 3 else 2,
|
||||||
it,
|
it,
|
||||||
requireActivity(),
|
requireActivity(),
|
||||||
viewPager = animePageAdapter.trendingViewPager
|
viewPager = animePageAdapter.trendingViewPager
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
animePageAdapter.updateAvatar()
|
animePageAdapter.updateAvatar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binding.animePageScrollTop.translationY =
|
binding.animePageScrollTop.translationY =
|
||||||
-(navBarHeight + bottomBar.height + bottomBar.marginBottom).toFloat()
|
-(navBarHeight + bottomBar.height + bottomBar.marginBottom).toFloat()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,13 +245,13 @@ class AnimeFragment : Fragment() {
|
||||||
animePageAdapter.onSeasonLongClick = { i ->
|
animePageAdapter.onSeasonLongClick = { i ->
|
||||||
val (season, year) = Anilist.currentSeasons[i]
|
val (season, year) = Anilist.currentSeasons[i]
|
||||||
ContextCompat.startActivity(
|
ContextCompat.startActivity(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
Intent(requireContext(), SearchActivity::class.java)
|
Intent(requireContext(), SearchActivity::class.java)
|
||||||
.putExtra("type", "ANIME")
|
.putExtra("type", "ANIME")
|
||||||
.putExtra("season", season)
|
.putExtra("season", season)
|
||||||
.putExtra("seasonYear", year.toString())
|
.putExtra("seasonYear", year.toString())
|
||||||
.putExtra("search", true),
|
.putExtra("search", true),
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,8 +152,8 @@ class AnimePageAdapter : RecyclerView.Adapter<AnimePageAdapter.AnimePageViewHold
|
||||||
|
|
||||||
fun setIncognito() {
|
fun setIncognito() {
|
||||||
val incognito = currContext()?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
|
val incognito = currContext()?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
|
||||||
?.getBoolean("incognito", false) ?: false
|
?.getBoolean("incognito", false) ?: false
|
||||||
if(incognito) {
|
if (incognito) {
|
||||||
binding.incognitoTextView.visibility = View.VISIBLE
|
binding.incognitoTextView.visibility = View.VISIBLE
|
||||||
if (!uiSettings.immersiveMode) {
|
if (!uiSettings.immersiveMode) {
|
||||||
binding.root.fitsSystemWindows = true
|
binding.root.fitsSystemWindows = true
|
||||||
|
|
|
@ -358,11 +358,13 @@ class HomeFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setIncognito() {
|
private fun setIncognito() {
|
||||||
val incognito = currContext()?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
|
val incognito = currContext()?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
|
||||||
?.getBoolean("incognito", false) ?: false
|
?.getBoolean("incognito", false) ?: false
|
||||||
if(incognito) {
|
if (incognito) {
|
||||||
val uiSettings = loadData<UserInterfaceSettings>("ui_settings") ?: UserInterfaceSettings()
|
val uiSettings =
|
||||||
|
loadData<UserInterfaceSettings>("ui_settings") ?: UserInterfaceSettings()
|
||||||
binding.incognitoTextView.visibility = View.VISIBLE
|
binding.incognitoTextView.visibility = View.VISIBLE
|
||||||
if (!uiSettings.immersiveMode) {
|
if (!uiSettings.immersiveMode) {
|
||||||
binding.root.fitsSystemWindows = true
|
binding.root.fitsSystemWindows = true
|
||||||
|
@ -377,6 +379,7 @@ class HomeFragment : Fragment() {
|
||||||
binding.incognitoTextView.visibility = View.GONE
|
binding.incognitoTextView.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
if (!model.loaded) Refresh.activity[1]!!.postValue(true)
|
if (!model.loaded) Refresh.activity[1]!!.postValue(true)
|
||||||
setIncognito()
|
setIncognito()
|
||||||
|
|
|
@ -2,7 +2,6 @@ package ani.dantotsu.home
|
||||||
|
|
||||||
import android.animation.ObjectAnimator
|
import android.animation.ObjectAnimator
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
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.AnilistMangaViewModel
|
||||||
import ani.dantotsu.connections.anilist.SearchResults
|
import ani.dantotsu.connections.anilist.SearchResults
|
||||||
import ani.dantotsu.connections.anilist.getUserId
|
import ani.dantotsu.connections.anilist.getUserId
|
||||||
import ani.dantotsu.currContext
|
|
||||||
import ani.dantotsu.databinding.FragmentMangaBinding
|
import ani.dantotsu.databinding.FragmentMangaBinding
|
||||||
import ani.dantotsu.loadData
|
import ani.dantotsu.loadData
|
||||||
import ani.dantotsu.media.MediaAdaptor
|
import ani.dantotsu.media.MediaAdaptor
|
||||||
|
@ -48,14 +46,14 @@ class MangaFragment : Fragment() {
|
||||||
private lateinit var mangaPageAdapter: MangaPageAdapter
|
private lateinit var mangaPageAdapter: MangaPageAdapter
|
||||||
|
|
||||||
private var uiSettings: UserInterfaceSettings =
|
private var uiSettings: UserInterfaceSettings =
|
||||||
loadData("ui_settings") ?: UserInterfaceSettings()
|
loadData("ui_settings") ?: UserInterfaceSettings()
|
||||||
|
|
||||||
val model: AnilistMangaViewModel by activityViewModels()
|
val model: AnilistMangaViewModel by activityViewModels()
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View {
|
): View {
|
||||||
_binding = FragmentMangaBinding.inflate(inflater, container, false)
|
_binding = FragmentMangaBinding.inflate(inflater, container, false)
|
||||||
return binding.root
|
return binding.root
|
||||||
|
@ -76,11 +74,11 @@ class MangaFragment : Fragment() {
|
||||||
if (displayCutout != null) {
|
if (displayCutout != null) {
|
||||||
if (displayCutout.boundingRects.size > 0) {
|
if (displayCutout.boundingRects.size > 0) {
|
||||||
height = max(
|
height = max(
|
||||||
statusBarHeight,
|
statusBarHeight,
|
||||||
min(
|
min(
|
||||||
displayCutout.boundingRects[0].width(),
|
displayCutout.boundingRects[0].width(),
|
||||||
displayCutout.boundingRects[0].height()
|
displayCutout.boundingRects[0].height()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,18 +96,18 @@ class MangaFragment : Fragment() {
|
||||||
if (model.notSet) {
|
if (model.notSet) {
|
||||||
model.notSet = false
|
model.notSet = false
|
||||||
model.searchResults = SearchResults(
|
model.searchResults = SearchResults(
|
||||||
"MANGA",
|
"MANGA",
|
||||||
isAdult = false,
|
isAdult = false,
|
||||||
onList = false,
|
onList = false,
|
||||||
results = arrayListOf(),
|
results = arrayListOf(),
|
||||||
hasNextPage = true,
|
hasNextPage = true,
|
||||||
sort = Anilist.sortBy[1]
|
sort = Anilist.sortBy[1]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val popularAdaptor = MediaAdaptor(1, model.searchResults.results, requireActivity())
|
val popularAdaptor = MediaAdaptor(1, model.searchResults.results, requireActivity())
|
||||||
val progressAdaptor = ProgressAdapter(searched = model.searched)
|
val progressAdaptor = ProgressAdapter(searched = model.searched)
|
||||||
binding.mangaPageRecyclerView.adapter =
|
binding.mangaPageRecyclerView.adapter =
|
||||||
ConcatAdapter(mangaPageAdapter, popularAdaptor, progressAdaptor)
|
ConcatAdapter(mangaPageAdapter, popularAdaptor, progressAdaptor)
|
||||||
val layout = LinearLayoutManager(requireContext())
|
val layout = LinearLayoutManager(requireContext())
|
||||||
binding.mangaPageRecyclerView.layoutManager = layout
|
binding.mangaPageRecyclerView.layoutManager = layout
|
||||||
|
|
||||||
|
@ -135,7 +133,7 @@ class MangaFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.mangaPageRecyclerView.addOnScrollListener(object :
|
binding.mangaPageRecyclerView.addOnScrollListener(object :
|
||||||
RecyclerView.OnScrollListener() {
|
RecyclerView.OnScrollListener() {
|
||||||
override fun onScrolled(v: RecyclerView, dx: Int, dy: Int) {
|
override fun onScrolled(v: RecyclerView, dx: Int, dy: Int) {
|
||||||
if (!v.canScrollVertically(1)) {
|
if (!v.canScrollVertically(1)) {
|
||||||
if (model.searchResults.hasNextPage && model.searchResults.results.isNotEmpty() && !loading) {
|
if (model.searchResults.hasNextPage && model.searchResults.results.isNotEmpty() && !loading) {
|
||||||
|
@ -175,19 +173,19 @@ class MangaFragment : Fragment() {
|
||||||
model.getTrending().observe(viewLifecycleOwner) {
|
model.getTrending().observe(viewLifecycleOwner) {
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
mangaPageAdapter.updateTrending(
|
mangaPageAdapter.updateTrending(
|
||||||
MediaAdaptor(
|
MediaAdaptor(
|
||||||
if (uiSettings.smallView) 3 else 2,
|
if (uiSettings.smallView) 3 else 2,
|
||||||
it,
|
it,
|
||||||
requireActivity(),
|
requireActivity(),
|
||||||
viewPager = mangaPageAdapter.trendingViewPager
|
viewPager = mangaPageAdapter.trendingViewPager
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
mangaPageAdapter.updateAvatar()
|
mangaPageAdapter.updateAvatar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binding.mangaPageScrollTop.translationY =
|
binding.mangaPageScrollTop.translationY =
|
||||||
-(navBarHeight + bottomBar.height + bottomBar.marginBottom).toFloat()
|
-(navBarHeight + bottomBar.height + bottomBar.marginBottom).toFloat()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,8 +144,8 @@ class MangaPageAdapter : RecyclerView.Adapter<MangaPageAdapter.MangaPageViewHold
|
||||||
|
|
||||||
fun setIncognito() {
|
fun setIncognito() {
|
||||||
val incognito = currContext()?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
|
val incognito = currContext()?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
|
||||||
?.getBoolean("incognito", false) ?: false
|
?.getBoolean("incognito", false) ?: false
|
||||||
if(incognito) {
|
if (incognito) {
|
||||||
binding.incognitoTextView.visibility = View.VISIBLE
|
binding.incognitoTextView.visibility = View.VISIBLE
|
||||||
if (!uiSettings.immersiveMode) {
|
if (!uiSettings.immersiveMode) {
|
||||||
binding.root.fitsSystemWindows = true
|
binding.root.fitsSystemWindows = true
|
||||||
|
|
|
@ -318,8 +318,7 @@ class MediaDetailsActivity : AppCompatActivity(), AppBarLayout.OnOffsetChangedLi
|
||||||
)
|
)
|
||||||
if (media.format == "NOVEL") {
|
if (media.format == "NOVEL") {
|
||||||
tabLayout.inflateMenu(R.menu.novel_menu_detail)
|
tabLayout.inflateMenu(R.menu.novel_menu_detail)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
tabLayout.inflateMenu(R.menu.manga_menu_detail)
|
tabLayout.inflateMenu(R.menu.manga_menu_detail)
|
||||||
}
|
}
|
||||||
anime = false
|
anime = false
|
||||||
|
@ -365,6 +364,7 @@ class MediaDetailsActivity : AppCompatActivity(), AppBarLayout.OnOffsetChangedLi
|
||||||
R.id.info -> {
|
R.id.info -> {
|
||||||
selected = 0
|
selected = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.watch, R.id.read -> {
|
R.id.watch, R.id.read -> {
|
||||||
selected = 1
|
selected = 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,8 @@ class SubtitleDownloader {
|
||||||
|
|
||||||
|
|
||||||
val subtitleType = when {
|
val subtitleType = when {
|
||||||
responseBody?.contains("[Script Info]") == true -> SubtitleType.ASS
|
responseBody.contains("[Script Info]") == true -> SubtitleType.ASS
|
||||||
responseBody?.contains("WEBVTT") == true -> SubtitleType.VTT
|
responseBody.contains("WEBVTT") == true -> SubtitleType.VTT
|
||||||
else -> SubtitleType.SRT
|
else -> SubtitleType.SRT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@ import java.util.regex.Pattern
|
||||||
|
|
||||||
class AnimeNameAdapter {
|
class AnimeNameAdapter {
|
||||||
companion object {
|
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:.\\-]*"
|
const val seasonRegex = "(season|s)[\\s:.\\-]*(\\d+)[\\s:.\\-]*"
|
||||||
|
|
||||||
fun findSeasonNumber(text: String): Int? {
|
fun findSeasonNumber(text: String): Int? {
|
||||||
|
|
|
@ -14,10 +14,9 @@ import androidx.core.content.ContextCompat
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import ani.dantotsu.*
|
import ani.dantotsu.*
|
||||||
|
import ani.dantotsu.databinding.DialogLayoutBinding
|
||||||
import ani.dantotsu.databinding.ItemAnimeWatchBinding
|
import ani.dantotsu.databinding.ItemAnimeWatchBinding
|
||||||
import ani.dantotsu.databinding.ItemChipBinding
|
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.Media
|
||||||
import ani.dantotsu.media.MediaDetailsActivity
|
import ani.dantotsu.media.MediaDetailsActivity
|
||||||
import ani.dantotsu.media.SourceSearchDialogFragment
|
import ani.dantotsu.media.SourceSearchDialogFragment
|
||||||
|
@ -45,6 +44,7 @@ class AnimeWatchAdapter(
|
||||||
val bind = ItemAnimeWatchBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
val bind = ItemAnimeWatchBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
return ViewHolder(bind)
|
return ViewHolder(bind)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var nestedDialog: AlertDialog? = null
|
private var nestedDialog: AlertDialog? = null
|
||||||
|
|
||||||
|
|
||||||
|
@ -234,11 +234,11 @@ class AnimeWatchAdapter(
|
||||||
dialogBinding.animeScanlatorContainer.visibility = View.GONE
|
dialogBinding.animeScanlatorContainer.visibility = View.GONE
|
||||||
dialogBinding.animeDownloadContainer.visibility = View.GONE
|
dialogBinding.animeDownloadContainer.visibility = View.GONE
|
||||||
|
|
||||||
nestedDialog = AlertDialog.Builder(fragment.requireContext() , R.style.MyPopup)
|
nestedDialog = AlertDialog.Builder(fragment.requireContext(), R.style.MyPopup)
|
||||||
.setTitle("Options")
|
.setTitle("Options")
|
||||||
.setView(dialogView)
|
.setView(dialogView)
|
||||||
.setPositiveButton("OK") { _, _ ->
|
.setPositiveButton("OK") { _, _ ->
|
||||||
if (run) fragment.onIconPressed(style, reversed)
|
if (run) fragment.onIconPressed(style, reversed)
|
||||||
}
|
}
|
||||||
.setNegativeButton("Cancel") { _, _ ->
|
.setNegativeButton("Cancel") { _, _ ->
|
||||||
}
|
}
|
||||||
|
@ -311,74 +311,74 @@ class AnimeWatchAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
fun handleEpisodes() {
|
fun handleEpisodes() {
|
||||||
val binding = _binding
|
val binding = _binding
|
||||||
if (binding != null) {
|
if (binding != null) {
|
||||||
if (media.anime?.episodes != null) {
|
if (media.anime?.episodes != null) {
|
||||||
val episodes = media.anime.episodes!!.keys.toTypedArray()
|
val episodes = media.anime.episodes!!.keys.toTypedArray()
|
||||||
|
|
||||||
val anilistEp = (media.userProgress ?: 0).plus(1)
|
val anilistEp = (media.userProgress ?: 0).plus(1)
|
||||||
val appEp = loadData<String>("${media.id}_current_ep")?.toIntOrNull() ?: 1
|
val appEp = loadData<String>("${media.id}_current_ep")?.toIntOrNull() ?: 1
|
||||||
|
|
||||||
var continueEp = (if (anilistEp > appEp) anilistEp else appEp).toString()
|
var continueEp = (if (anilistEp > appEp) anilistEp else appEp).toString()
|
||||||
if (episodes.contains(continueEp)) {
|
if (episodes.contains(continueEp)) {
|
||||||
binding.animeSourceContinue.visibility = View.VISIBLE
|
binding.animeSourceContinue.visibility = View.VISIBLE
|
||||||
handleProgress(
|
handleProgress(
|
||||||
binding.itemEpisodeProgressCont,
|
binding.itemEpisodeProgressCont,
|
||||||
binding.itemEpisodeProgress,
|
binding.itemEpisodeProgress,
|
||||||
binding.itemEpisodeProgressEmpty,
|
binding.itemEpisodeProgressEmpty,
|
||||||
media.id,
|
media.id,
|
||||||
continueEp
|
continueEp
|
||||||
)
|
)
|
||||||
if ((binding.itemEpisodeProgress.layoutParams as LinearLayout.LayoutParams).weight > fragment.playerSettings.watchPercentage) {
|
if ((binding.itemEpisodeProgress.layoutParams as LinearLayout.LayoutParams).weight > fragment.playerSettings.watchPercentage) {
|
||||||
val e = episodes.indexOf(continueEp)
|
val e = episodes.indexOf(continueEp)
|
||||||
if (e != -1 && e + 1 < episodes.size) {
|
if (e != -1 && e + 1 < episodes.size) {
|
||||||
continueEp = episodes[e + 1]
|
continueEp = episodes[e + 1]
|
||||||
handleProgress(
|
handleProgress(
|
||||||
binding.itemEpisodeProgressCont,
|
binding.itemEpisodeProgressCont,
|
||||||
binding.itemEpisodeProgress,
|
binding.itemEpisodeProgress,
|
||||||
binding.itemEpisodeProgressEmpty,
|
binding.itemEpisodeProgressEmpty,
|
||||||
media.id,
|
media.id,
|
||||||
continueEp
|
continueEp
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
val ep = media.anime.episodes!![continueEp]!!
|
||||||
val ep = media.anime.episodes!![continueEp]!!
|
|
||||||
|
|
||||||
val cleanedTitle = ep.title?.let { AnimeNameAdapter.removeEpisodeNumber(it) }
|
val cleanedTitle = ep.title?.let { AnimeNameAdapter.removeEpisodeNumber(it) }
|
||||||
|
|
||||||
binding.itemEpisodeImage.loadImage(
|
binding.itemEpisodeImage.loadImage(
|
||||||
ep.thumb ?: FileUrl[media.banner ?: media.cover], 0
|
ep.thumb ?: FileUrl[media.banner ?: media.cover], 0
|
||||||
)
|
)
|
||||||
if (ep.filler) binding.itemEpisodeFillerView.visibility = View.VISIBLE
|
if (ep.filler) binding.itemEpisodeFillerView.visibility = View.VISIBLE
|
||||||
binding.animeSourceContinueText.text =
|
binding.animeSourceContinueText.text =
|
||||||
currActivity()!!.getString(R.string.continue_episode) + "${ep.number}${if (ep.filler) " - Filler" else ""}${"\n$cleanedTitle"}"
|
currActivity()!!.getString(R.string.continue_episode) + "${ep.number}${if (ep.filler) " - Filler" else ""}${"\n$cleanedTitle"}"
|
||||||
binding.animeSourceContinue.setOnClickListener {
|
binding.animeSourceContinue.setOnClickListener {
|
||||||
fragment.onEpisodeClick(continueEp)
|
fragment.onEpisodeClick(continueEp)
|
||||||
}
|
|
||||||
if (fragment.continueEp) {
|
|
||||||
if ((binding.itemEpisodeProgress.layoutParams as LinearLayout.LayoutParams).weight < fragment.playerSettings.watchPercentage) {
|
|
||||||
binding.animeSourceContinue.performClick()
|
|
||||||
fragment.continueEp = false
|
|
||||||
}
|
}
|
||||||
|
if (fragment.continueEp) {
|
||||||
|
if ((binding.itemEpisodeProgress.layoutParams as LinearLayout.LayoutParams).weight < fragment.playerSettings.watchPercentage) {
|
||||||
|
binding.animeSourceContinue.performClick()
|
||||||
|
fragment.continueEp = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
binding.animeSourceContinue.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.animeSourceProgressBar.visibility = View.GONE
|
||||||
|
if (media.anime.episodes!!.isNotEmpty())
|
||||||
|
binding.animeSourceNotFound.visibility = View.GONE
|
||||||
|
else
|
||||||
|
binding.animeSourceNotFound.visibility = View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
binding.animeSourceContinue.visibility = View.GONE
|
binding.animeSourceContinue.visibility = View.GONE
|
||||||
}
|
|
||||||
|
|
||||||
binding.animeSourceProgressBar.visibility = View.GONE
|
|
||||||
if (media.anime.episodes!!.isNotEmpty())
|
|
||||||
binding.animeSourceNotFound.visibility = View.GONE
|
binding.animeSourceNotFound.visibility = View.GONE
|
||||||
else
|
clearChips()
|
||||||
binding.animeSourceNotFound.visibility = View.VISIBLE
|
binding.animeSourceProgressBar.visibility = View.VISIBLE
|
||||||
} else {
|
}
|
||||||
binding.animeSourceContinue.visibility = View.GONE
|
|
||||||
binding.animeSourceNotFound.visibility = View.GONE
|
|
||||||
clearChips()
|
|
||||||
binding.animeSourceProgressBar.visibility = View.VISIBLE
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun setLanguageList(lang: Int, source: Int) {
|
private fun setLanguageList(lang: Int, source: Int) {
|
||||||
val binding = _binding
|
val binding = _binding
|
||||||
|
@ -401,7 +401,8 @@ fun handleEpisodes() {
|
||||||
parser.extension.sources.map { LanguageMapper.mapLanguageCodeToName(it.lang) }
|
parser.extension.sources.map { LanguageMapper.mapLanguageCodeToName(it.lang) }
|
||||||
)
|
)
|
||||||
val items = adapter.count
|
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)
|
binding?.animeSourceLanguage?.setAdapter(adapter)
|
||||||
|
|
||||||
|
|
|
@ -320,9 +320,10 @@ class AnimeWatchFragment : Fragment() {
|
||||||
if (allSettings.isNotEmpty()) {
|
if (allSettings.isNotEmpty()) {
|
||||||
var selectedSetting = allSettings[0]
|
var selectedSetting = allSettings[0]
|
||||||
if (allSettings.size > 1) {
|
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
|
var selectedIndex = 0
|
||||||
val dialog = AlertDialog.Builder(requireContext() , R.style.MyPopup)
|
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
|
||||||
.setTitle("Select a Source")
|
.setTitle("Select a Source")
|
||||||
.setSingleChoiceItems(names, selectedIndex) { dialog, which ->
|
.setSingleChoiceItems(names, selectedIndex) { dialog, which ->
|
||||||
selectedIndex = which
|
selectedIndex = which
|
||||||
|
|
|
@ -26,18 +26,18 @@ class CustomCastThemeFactory : MediaRouteDialogFactory() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CustomMediaRouterChooserDialogFragment: MediaRouteChooserDialogFragment() {
|
class CustomMediaRouterChooserDialogFragment : MediaRouteChooserDialogFragment() {
|
||||||
override fun onCreateChooserDialog(
|
override fun onCreateChooserDialog(
|
||||||
context: Context,
|
context: Context,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): MediaRouteChooserDialog =
|
): MediaRouteChooserDialog =
|
||||||
MediaRouteChooserDialog(context, R.style.MyPopup)
|
MediaRouteChooserDialog(context, R.style.MyPopup)
|
||||||
}
|
}
|
||||||
|
|
||||||
class CustomMediaRouteControllerDialogFragment: MediaRouteControllerDialogFragment() {
|
class CustomMediaRouteControllerDialogFragment : MediaRouteControllerDialogFragment() {
|
||||||
override fun onCreateControllerDialog(
|
override fun onCreateControllerDialog(
|
||||||
context: Context,
|
context: Context,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): MediaRouteControllerDialog =
|
): MediaRouteControllerDialog =
|
||||||
MediaRouteControllerDialog(context, R.style.MyPopup)
|
MediaRouteControllerDialog(context, R.style.MyPopup)
|
||||||
}
|
}
|
|
@ -11,7 +11,6 @@ import ani.dantotsu.connections.updateProgress
|
||||||
import ani.dantotsu.databinding.ItemEpisodeCompactBinding
|
import ani.dantotsu.databinding.ItemEpisodeCompactBinding
|
||||||
import ani.dantotsu.databinding.ItemEpisodeGridBinding
|
import ani.dantotsu.databinding.ItemEpisodeGridBinding
|
||||||
import ani.dantotsu.databinding.ItemEpisodeListBinding
|
import ani.dantotsu.databinding.ItemEpisodeListBinding
|
||||||
import ani.dantotsu.media.anime.AnimeNameAdapter
|
|
||||||
import ani.dantotsu.media.Media
|
import ani.dantotsu.media.Media
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.load.model.GlideUrl
|
import com.bumptech.glide.load.model.GlideUrl
|
||||||
|
@ -77,11 +76,11 @@ class EpisodeAdapter(
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
val ep = arr[position]
|
val ep = arr[position]
|
||||||
val title = if (!ep.title.isNullOrEmpty() && ep.title != "null") {
|
val title = if (!ep.title.isNullOrEmpty() && ep.title != "null") {
|
||||||
ep.title?.let { AnimeNameAdapter.removeEpisodeNumber(it) }
|
ep.title?.let { AnimeNameAdapter.removeEpisodeNumber(it) }
|
||||||
} else {
|
} else {
|
||||||
ep.number
|
ep.number
|
||||||
} ?: ""
|
} ?: ""
|
||||||
|
|
||||||
when (holder) {
|
when (holder) {
|
||||||
is EpisodeListViewHolder -> {
|
is EpisodeListViewHolder -> {
|
||||||
|
|
|
@ -339,7 +339,8 @@ class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityL
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
//Initialize
|
//Initialize
|
||||||
isCastApiAvailable = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS
|
isCastApiAvailable = GoogleApiAvailability.getInstance()
|
||||||
|
.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS
|
||||||
try {
|
try {
|
||||||
castContext = CastContext.getSharedInstance(this)
|
castContext = CastContext.getSharedInstance(this)
|
||||||
castPlayer = CastPlayer(castContext!!)
|
castPlayer = CastPlayer(castContext!!)
|
||||||
|
|
|
@ -23,7 +23,6 @@ import ani.dantotsu.databinding.ItemUrlBinding
|
||||||
import ani.dantotsu.download.video.Helper
|
import ani.dantotsu.download.video.Helper
|
||||||
import ani.dantotsu.media.Media
|
import ani.dantotsu.media.Media
|
||||||
import ani.dantotsu.media.MediaDetailsViewModel
|
import ani.dantotsu.media.MediaDetailsViewModel
|
||||||
import ani.dantotsu.others.Download.download
|
|
||||||
import ani.dantotsu.parsers.VideoExtractor
|
import ani.dantotsu.parsers.VideoExtractor
|
||||||
import ani.dantotsu.parsers.VideoType
|
import ani.dantotsu.parsers.VideoType
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
@ -275,7 +274,8 @@ class SelectorDialogFragment : BottomSheetDialogFragment() {
|
||||||
// media!!.userPreferredName
|
// media!!.userPreferredName
|
||||||
//)
|
//)
|
||||||
val episode = media!!.anime!!.episodes!![media!!.anime!!.selectedEpisode!!]!!
|
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) {
|
if (video != null) {
|
||||||
Helper.startAnimeDownloadService(
|
Helper.startAnimeDownloadService(
|
||||||
requireActivity(),
|
requireActivity(),
|
||||||
|
@ -284,7 +284,7 @@ class SelectorDialogFragment : BottomSheetDialogFragment() {
|
||||||
video,
|
video,
|
||||||
null,
|
null,
|
||||||
media,
|
media,
|
||||||
episode.thumb?.url?: media!!.banner?: media!!.cover
|
episode.thumb?.url ?: media!!.banner ?: media!!.cover
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
dismiss()
|
dismiss()
|
||||||
|
|
|
@ -48,7 +48,9 @@ class MangaReadAdapter(
|
||||||
val bind = ItemAnimeWatchBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
val bind = ItemAnimeWatchBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
return ViewHolder(bind)
|
return ViewHolder(bind)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var nestedDialog: AlertDialog? = null
|
private var nestedDialog: AlertDialog? = null
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val binding = holder.binding
|
val binding = holder.binding
|
||||||
|
@ -211,7 +213,8 @@ class MangaReadAdapter(
|
||||||
dialogBinding.animeScanlatorTop.setOnClickListener {
|
dialogBinding.animeScanlatorTop.setOnClickListener {
|
||||||
val dialogView2 =
|
val dialogView2 =
|
||||||
LayoutInflater.from(currContext()).inflate(R.layout.custom_dialog_layout, null)
|
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
|
// Dynamically add checkboxes
|
||||||
options.forEach { option ->
|
options.forEach { option ->
|
||||||
|
@ -248,12 +251,12 @@ class MangaReadAdapter(
|
||||||
dialog.window?.setDimAmount(0.8f)
|
dialog.window?.setDimAmount(0.8f)
|
||||||
}
|
}
|
||||||
|
|
||||||
nestedDialog = AlertDialog.Builder(fragment.requireContext() , R.style.MyPopup)
|
nestedDialog = AlertDialog.Builder(fragment.requireContext(), R.style.MyPopup)
|
||||||
.setTitle("Options")
|
.setTitle("Options")
|
||||||
.setView(dialogView)
|
.setView(dialogView)
|
||||||
.setPositiveButton("OK") { _, _ ->
|
.setPositiveButton("OK") { _, _ ->
|
||||||
if(run) fragment.onIconPressed(style, reversed)
|
if (run) fragment.onIconPressed(style, reversed)
|
||||||
if (dialogBinding.downloadNo.text != "0"){
|
if (dialogBinding.downloadNo.text != "0") {
|
||||||
fragment.multiDownload(dialogBinding.downloadNo.text.toString().toInt())
|
fragment.multiDownload(dialogBinding.downloadNo.text.toString().toInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,6 +296,7 @@ class MangaReadAdapter(
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val startChapter = MangaNameAdapter.findChapterNumber(names[limit * (position)])
|
val startChapter = MangaNameAdapter.findChapterNumber(names[limit * (position)])
|
||||||
val endChapter = MangaNameAdapter.findChapterNumber(names[last - 1])
|
val endChapter = MangaNameAdapter.findChapterNumber(names[last - 1])
|
||||||
val startChapterString = if (startChapter != null) {
|
val startChapterString = if (startChapter != null) {
|
||||||
|
@ -425,7 +429,8 @@ class MangaReadAdapter(
|
||||||
parser.extension.sources.map { LanguageMapper.mapLanguageCodeToName(it.lang) }
|
parser.extension.sources.map { LanguageMapper.mapLanguageCodeToName(it.lang) }
|
||||||
)
|
)
|
||||||
val items = adapter.count
|
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)
|
binding?.animeSourceLanguage?.setAdapter(adapter)
|
||||||
|
|
||||||
|
|
|
@ -197,12 +197,15 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
||||||
override fun onScanlatorsSelected() {
|
override fun onScanlatorsSelected() {
|
||||||
updateChapters()
|
updateChapters()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun multiDownload(n: Int) {
|
fun multiDownload(n: Int) {
|
||||||
//get last viewed chapter
|
//get last viewed chapter
|
||||||
val selected = media.userProgress
|
val selected = media.userProgress
|
||||||
val chapters = media.manga?.chapters?.values?.toList()
|
val chapters = media.manga?.chapters?.values?.toList()
|
||||||
//filter by selected language
|
//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
|
if (progressChapterIndex < 0 || n < 1 || chapters == null) return
|
||||||
|
|
||||||
|
@ -363,7 +366,8 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
||||||
if (allSettings.isNotEmpty()) {
|
if (allSettings.isNotEmpty()) {
|
||||||
var selectedSetting = allSettings[0]
|
var selectedSetting = allSettings[0]
|
||||||
if (allSettings.size > 1) {
|
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
|
var selectedIndex = 0
|
||||||
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
|
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
|
||||||
.setTitle("Select a Source")
|
.setTitle("Select a Source")
|
||||||
|
|
|
@ -89,7 +89,8 @@ abstract class BaseImageAdapter(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val detector = GestureDetectorCompat(view.context, object : GesturesListener() {
|
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 {
|
view.findViewById<View>(R.id.imgProgCover).apply {
|
||||||
setOnTouchListener { _, event ->
|
setOnTouchListener { _, event ->
|
||||||
|
|
|
@ -93,12 +93,14 @@ open class ImageAdapter(
|
||||||
override fun getItemCount(): Int = images.size
|
override fun getItemCount(): Int = images.size
|
||||||
|
|
||||||
override fun isZoomed(): Boolean {
|
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
|
return imageView.scale > imageView.minScale
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setZoom(zoom: Float) {
|
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)
|
imageView.setScaleAndCenter(zoom, imageView.center)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,7 +255,8 @@ class MangaReaderActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
showProgressDialog =
|
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
|
//Chapter Change
|
||||||
fun change(index: Int) {
|
fun change(index: Int) {
|
||||||
|
@ -850,7 +851,8 @@ class MangaReaderActivity : AppCompatActivity() {
|
||||||
private fun progress(runnable: Runnable) {
|
private fun progress(runnable: Runnable) {
|
||||||
if (maxChapterPage - currentChapterPage <= 1 && Anilist.userid != null) {
|
if (maxChapterPage - currentChapterPage <= 1 && Anilist.userid != null) {
|
||||||
showProgressDialog =
|
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) {
|
if (showProgressDialog) {
|
||||||
|
|
||||||
val dialogView = layoutInflater.inflate(R.layout.item_custom_dialog, null)
|
val dialogView = layoutInflater.inflate(R.layout.item_custom_dialog, null)
|
||||||
|
|
|
@ -42,7 +42,11 @@ class NovelResponseAdapter(
|
||||||
.into(binding.itemEpisodeImage)
|
.into(binding.itemEpisodeImage)
|
||||||
|
|
||||||
val typedValue = TypedValue()
|
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
|
val color = typedValue.data
|
||||||
|
|
||||||
binding.itemEpisodeTitle.text = novel.name
|
binding.itemEpisodeTitle.text = novel.name
|
||||||
|
@ -98,14 +102,19 @@ class NovelResponseAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.root.setOnLongClickListener {
|
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.setTitle("Delete ${novel.name}?")
|
||||||
builder.setMessage("Are you sure you want to delete ${novel.name}?")
|
builder.setMessage("Are you sure you want to delete ${novel.name}?")
|
||||||
builder.setPositiveButton("Yes") { _, _ ->
|
builder.setPositiveButton("Yes") { _, _ ->
|
||||||
downloadedCheckCallback.deleteDownload(novel)
|
downloadedCheckCallback.deleteDownload(novel)
|
||||||
deleteDownload(novel.link)
|
deleteDownload(novel.link)
|
||||||
snackString("Deleted ${novel.name}")
|
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 = ""
|
binding.itemEpisodeFiller.text = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,7 +148,8 @@ class NovelReaderActivity : AppCompatActivity(), EbookReaderEventListener {
|
||||||
Toast.makeText(this, "Please update WebView from PlayStore", Toast.LENGTH_LONG).show()
|
Toast.makeText(this, "Please update WebView from PlayStore", Toast.LENGTH_LONG).show()
|
||||||
//open playstore
|
//open playstore
|
||||||
val intent = Intent(Intent.ACTION_VIEW)
|
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)
|
startActivity(intent)
|
||||||
//stop reader
|
//stop reader
|
||||||
finish()
|
finish()
|
||||||
|
@ -270,7 +271,8 @@ class NovelReaderActivity : AppCompatActivity(), EbookReaderEventListener {
|
||||||
binding.bookReader.getAppearance {
|
binding.bookReader.getAppearance {
|
||||||
currentTheme = it
|
currentTheme = it
|
||||||
themes.add(0, it)
|
themes.add(0, it)
|
||||||
settings.defaultLN = loadData("${sanitizedBookId}_current_settings") ?: settings.defaultLN
|
settings.defaultLN =
|
||||||
|
loadData("${sanitizedBookId}_current_settings") ?: settings.defaultLN
|
||||||
applySettings()
|
applySettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +353,7 @@ class NovelReaderActivity : AppCompatActivity(), EbookReaderEventListener {
|
||||||
saveData("${sanitizedBookId}_current_settings", settings.defaultLN)
|
saveData("${sanitizedBookId}_current_settings", settings.defaultLN)
|
||||||
hideBars()
|
hideBars()
|
||||||
|
|
||||||
if(settings.defaultLN.useOledTheme) {
|
if (settings.defaultLN.useOledTheme) {
|
||||||
themes.forEach { theme ->
|
themes.forEach { theme ->
|
||||||
theme.darkBg = Color.parseColor("#000000")
|
theme.darkBg = Color.parseColor("#000000")
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import ani.dantotsu.databinding.ActivityListBinding
|
||||||
import ani.dantotsu.loadData
|
import ani.dantotsu.loadData
|
||||||
import ani.dantotsu.navBarHeight
|
import ani.dantotsu.navBarHeight
|
||||||
import ani.dantotsu.others.LangSet
|
import ani.dantotsu.others.LangSet
|
||||||
import ani.dantotsu.saveData
|
|
||||||
import ani.dantotsu.settings.UserInterfaceSettings
|
import ani.dantotsu.settings.UserInterfaceSettings
|
||||||
import ani.dantotsu.statusBarHeight
|
import ani.dantotsu.statusBarHeight
|
||||||
import ani.dantotsu.themes.ThemeManager
|
import ani.dantotsu.themes.ThemeManager
|
||||||
|
|
|
@ -7,10 +7,10 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.view.updateLayoutParams
|
import androidx.core.view.updateLayoutParams
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import ani.dantotsu.databinding.FragmentOfflineBinding
|
|
||||||
import ani.dantotsu.isOnline
|
|
||||||
import ani.dantotsu.App
|
import ani.dantotsu.App
|
||||||
import ani.dantotsu.R
|
import ani.dantotsu.R
|
||||||
|
import ani.dantotsu.databinding.FragmentOfflineBinding
|
||||||
|
import ani.dantotsu.isOnline
|
||||||
import ani.dantotsu.navBarHeight
|
import ani.dantotsu.navBarHeight
|
||||||
import ani.dantotsu.startMainActivity
|
import ani.dantotsu.startMainActivity
|
||||||
import ani.dantotsu.statusBarHeight
|
import ani.dantotsu.statusBarHeight
|
||||||
|
@ -26,8 +26,10 @@ class OfflineFragment : Fragment() {
|
||||||
topMargin = statusBarHeight
|
topMargin = statusBarHeight
|
||||||
bottomMargin = navBarHeight
|
bottomMargin = navBarHeight
|
||||||
}
|
}
|
||||||
val offline = App.context?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)?.getBoolean("offlineMode", false) ?: false
|
val offline = App.context?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)
|
||||||
binding.noInternet.text = if (!isOnline(requireContext())) getString(R.string.no_internet) else "OFFLINE MODE"
|
?.getBoolean("offlineMode", false) ?: false
|
||||||
|
binding.noInternet.text =
|
||||||
|
if (!isOnline(requireContext())) getString(R.string.no_internet) else "OFFLINE MODE"
|
||||||
binding.refreshButton.setOnClickListener {
|
binding.refreshButton.setOnClickListener {
|
||||||
if (!isOnline(requireContext()) && offline) {
|
if (!isOnline(requireContext()) && offline) {
|
||||||
startMainActivity(requireActivity())
|
startMainActivity(requireActivity())
|
||||||
|
|
|
@ -17,7 +17,6 @@ import ani.dantotsu.media.anime.AnimeNameAdapter
|
||||||
import ani.dantotsu.media.manga.ImageData
|
import ani.dantotsu.media.manga.ImageData
|
||||||
import ani.dantotsu.media.manga.MangaCache
|
import ani.dantotsu.media.manga.MangaCache
|
||||||
import ani.dantotsu.snackString
|
import ani.dantotsu.snackString
|
||||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
|
||||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||||
|
@ -317,6 +316,7 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun imageList(chapterLink: String, sChapter: SChapter): List<ImageData> {
|
suspend fun imageList(chapterLink: String, sChapter: SChapter): List<ImageData> {
|
||||||
val source = try {
|
val source = try {
|
||||||
extension.sources[sourceLanguage]
|
extension.sources[sourceLanguage]
|
||||||
|
@ -329,7 +329,8 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
|
||||||
try {
|
try {
|
||||||
println("source.name " + source.name)
|
println("source.name " + source.name)
|
||||||
val res = source.getPageList(sChapter)
|
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 semaphore = Semaphore(5)
|
||||||
val deferreds = reIndexedPages.map { page ->
|
val deferreds = reIndexedPages.map { page ->
|
||||||
|
@ -367,7 +368,7 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
|
||||||
// Convert InputStream to Bitmap
|
// Convert InputStream to Bitmap
|
||||||
val bitmap = BitmapFactory.decodeStream(inputStream)
|
val bitmap = BitmapFactory.decodeStream(inputStream)
|
||||||
|
|
||||||
inputStream?.close()
|
inputStream.close()
|
||||||
ani.dantotsu.media.manga.saveImage(
|
ani.dantotsu.media.manga.saveImage(
|
||||||
bitmap,
|
bitmap,
|
||||||
context.contentResolver,
|
context.contentResolver,
|
||||||
|
@ -409,7 +410,7 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
inputStream?.close()
|
inputStream.close()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// Handle any exceptions
|
// Handle any exceptions
|
||||||
println("An error occurred: ${e.message}")
|
println("An error occurred: ${e.message}")
|
||||||
|
@ -628,7 +629,7 @@ class VideoServerPassthrough(val videoServer: VideoServer) : VideoExtractor() {
|
||||||
if (format == null) {
|
if (format == null) {
|
||||||
logger("Unknown video format: $videoUrl")
|
logger("Unknown video format: $videoUrl")
|
||||||
//FirebaseCrashlytics.getInstance()
|
//FirebaseCrashlytics.getInstance()
|
||||||
// .recordException(Exception("Unknown video format: $videoUrl"))
|
// .recordException(Exception("Unknown video format: $videoUrl"))
|
||||||
format = VideoType.CONTAINER
|
format = VideoType.CONTAINER
|
||||||
}
|
}
|
||||||
val headersMap: Map<String, String> =
|
val headersMap: Map<String, String> =
|
||||||
|
@ -706,7 +707,7 @@ class VideoServerPassthrough(val videoServer: VideoServer) : VideoExtractor() {
|
||||||
return Subtitle(track.lang, track.url, type ?: SubtitleType.SRT)
|
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
|
// First, try to determine the type based on the URL file extension
|
||||||
val type: SubtitleType = when {
|
val type: SubtitleType = when {
|
||||||
url.endsWith(".vtt", true) -> SubtitleType.VTT
|
url.endsWith(".vtt", true) -> SubtitleType.VTT
|
||||||
|
|
|
@ -34,7 +34,7 @@ abstract class NovelParser : BaseParser() {
|
||||||
//val query = mediaObj.name ?: mediaObj.nameRomaji
|
//val query = mediaObj.name ?: mediaObj.nameRomaji
|
||||||
//return search(query).sortByVolume(query)
|
//return search(query).sortByVolume(query)
|
||||||
val results: List<ShowResponse>
|
val results: List<ShowResponse>
|
||||||
return if(mediaObj.name != null) {
|
return if (mediaObj.name != null) {
|
||||||
val query = mediaObj.name
|
val query = mediaObj.name
|
||||||
results = search(query).sortByVolume(query)
|
results = search(query).sortByVolume(query)
|
||||||
results.ifEmpty {
|
results.ifEmpty {
|
||||||
|
|
|
@ -3,7 +3,6 @@ package ani.dantotsu.parsers
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import ani.dantotsu.currContext
|
import ani.dantotsu.currContext
|
||||||
import ani.dantotsu.download.DownloadsManager
|
import ani.dantotsu.download.DownloadsManager
|
||||||
import ani.dantotsu.logger
|
|
||||||
import ani.dantotsu.media.anime.AnimeNameAdapter
|
import ani.dantotsu.media.anime.AnimeNameAdapter
|
||||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||||
|
|
|
@ -9,7 +9,7 @@ import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class OfflineNovelParser: NovelParser() {
|
class OfflineNovelParser : NovelParser() {
|
||||||
private val downloadManager = Injekt.get<DownloadsManager>()
|
private val downloadManager = Injekt.get<DownloadsManager>()
|
||||||
|
|
||||||
override val hostUrl: String = "Offline"
|
override val hostUrl: String = "Offline"
|
||||||
|
@ -31,7 +31,7 @@ class OfflineNovelParser: NovelParser() {
|
||||||
if (it.isDirectory) {
|
if (it.isDirectory) {
|
||||||
val chapter = Book(
|
val chapter = Book(
|
||||||
it.name,
|
it.name,
|
||||||
it.absolutePath + "/cover.jpg",
|
it.absolutePath + "/cover.jpg",
|
||||||
null,
|
null,
|
||||||
listOf(it.absolutePath + "/0.epub")
|
listOf(it.absolutePath + "/0.epub")
|
||||||
)
|
)
|
||||||
|
@ -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 {
|
names.forEach {
|
||||||
returnList.add(ShowResponse(it, it, cover))
|
returnList.add(ShowResponse(it, it, cover))
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,11 +111,12 @@ internal object NovelExtensionLoader {
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
private fun getSignatureHash(pkgInfo: PackageInfo): List<String>? {
|
private fun getSignatureHash(pkgInfo: PackageInfo): List<String>? {
|
||||||
val signatures = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && pkgInfo.signingInfo != null) {
|
val signatures =
|
||||||
pkgInfo.signingInfo.apkContentsSigners
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && pkgInfo.signingInfo != null) {
|
||||||
} else {
|
pkgInfo.signingInfo.apkContentsSigners
|
||||||
pkgInfo.signatures
|
} else {
|
||||||
}
|
pkgInfo.signatures
|
||||||
|
}
|
||||||
return if (!signatures.isNullOrEmpty()) {
|
return if (!signatures.isNullOrEmpty()) {
|
||||||
signatures.map { Hash.sha256(it.toByteArray()) }
|
signatures.map { Hash.sha256(it.toByteArray()) }
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -9,9 +9,7 @@ import android.text.TextWatcher
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.AutoCompleteTextView
|
import android.widget.AutoCompleteTextView
|
||||||
import androidx.activity.OnBackPressedCallback
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.widget.PopupMenu
|
|
||||||
import androidx.core.view.updateLayoutParams
|
import androidx.core.view.updateLayoutParams
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||||
|
@ -117,17 +115,17 @@ class ExtensionsActivity : AppCompatActivity() {
|
||||||
|
|
||||||
initActivity(this)
|
initActivity(this)
|
||||||
binding.languageselect.visibility = View.GONE
|
binding.languageselect.visibility = View.GONE
|
||||||
/* TODO
|
/* TODO
|
||||||
binding.languageselect.setOnClickListener {
|
binding.languageselect.setOnClickListener {
|
||||||
val popup = PopupMenu(this, it)
|
val popup = PopupMenu(this, it)
|
||||||
popup.inflate(R.menu.launguage_selector_menu)
|
popup.inflate(R.menu.launguage_selector_menu)
|
||||||
popup.setOnMenuItemClickListener { menuItem ->
|
popup.setOnMenuItemClickListener { menuItem ->
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
popup.setOnDismissListener {
|
popup.setOnDismissListener {
|
||||||
}
|
}
|
||||||
popup.show()
|
popup.show()
|
||||||
}*/
|
}*/
|
||||||
binding.settingsContainer.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
binding.settingsContainer.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
topMargin = statusBarHeight
|
topMargin = statusBarHeight
|
||||||
bottomMargin = navBarHeight
|
bottomMargin = navBarHeight
|
||||||
|
|
|
@ -18,83 +18,83 @@ class FAQActivity : AppCompatActivity() {
|
||||||
|
|
||||||
Triple(
|
Triple(
|
||||||
R.drawable.ic_round_help_24,
|
R.drawable.ic_round_help_24,
|
||||||
currContext()?.getString(R.string.question_1)?:"",
|
currContext()?.getString(R.string.question_1) ?: "",
|
||||||
currContext()?.getString(R.string.answer_1)?:""
|
currContext()?.getString(R.string.answer_1) ?: ""
|
||||||
),
|
),
|
||||||
Triple(
|
Triple(
|
||||||
R.drawable.ic_round_auto_awesome_24,
|
R.drawable.ic_round_auto_awesome_24,
|
||||||
currContext()?.getString(R.string.question_2)?:"",
|
currContext()?.getString(R.string.question_2) ?: "",
|
||||||
currContext()?.getString(R.string.answer_2)?:""
|
currContext()?.getString(R.string.answer_2) ?: ""
|
||||||
),
|
),
|
||||||
Triple(
|
Triple(
|
||||||
R.drawable.ic_round_auto_awesome_24,
|
R.drawable.ic_round_auto_awesome_24,
|
||||||
currContext()?.getString(R.string.question_17)?:"",
|
currContext()?.getString(R.string.question_17) ?: "",
|
||||||
currContext()?.getString(R.string.answer_17)?:""
|
currContext()?.getString(R.string.answer_17) ?: ""
|
||||||
),
|
),
|
||||||
Triple(
|
Triple(
|
||||||
R.drawable.ic_round_download_24,
|
R.drawable.ic_round_download_24,
|
||||||
currContext()?.getString(R.string.question_3)?:"",
|
currContext()?.getString(R.string.question_3) ?: "",
|
||||||
currContext()?.getString(R.string.answer_3)?:""
|
currContext()?.getString(R.string.answer_3) ?: ""
|
||||||
),
|
),
|
||||||
Triple(
|
Triple(
|
||||||
R.drawable.ic_round_help_24,
|
R.drawable.ic_round_help_24,
|
||||||
currContext()?.getString(R.string.question_16)?:"",
|
currContext()?.getString(R.string.question_16) ?: "",
|
||||||
currContext()?.getString(R.string.answer_16)?:""
|
currContext()?.getString(R.string.answer_16) ?: ""
|
||||||
),
|
),
|
||||||
Triple(
|
Triple(
|
||||||
R.drawable.ic_round_dns_24,
|
R.drawable.ic_round_dns_24,
|
||||||
currContext()?.getString(R.string.question_4)?:"",
|
currContext()?.getString(R.string.question_4) ?: "",
|
||||||
currContext()?.getString(R.string.answer_4)?:""
|
currContext()?.getString(R.string.answer_4) ?: ""
|
||||||
),
|
),
|
||||||
Triple(
|
Triple(
|
||||||
R.drawable.ic_baseline_screen_lock_portrait_24,
|
R.drawable.ic_baseline_screen_lock_portrait_24,
|
||||||
currContext()?.getString(R.string.question_5)?:"",
|
currContext()?.getString(R.string.question_5) ?: "",
|
||||||
currContext()?.getString(R.string.answer_5)?:""
|
currContext()?.getString(R.string.answer_5) ?: ""
|
||||||
),
|
),
|
||||||
Triple(
|
Triple(
|
||||||
R.drawable.ic_anilist,
|
R.drawable.ic_anilist,
|
||||||
currContext()?.getString(R.string.question_6)?:"",
|
currContext()?.getString(R.string.question_6) ?: "",
|
||||||
currContext()?.getString(R.string.answer_6)?:""
|
currContext()?.getString(R.string.answer_6) ?: ""
|
||||||
),
|
),
|
||||||
Triple(
|
Triple(
|
||||||
R.drawable.ic_round_movie_filter_24,
|
R.drawable.ic_round_movie_filter_24,
|
||||||
currContext()?.getString(R.string.question_7)?:"",
|
currContext()?.getString(R.string.question_7) ?: "",
|
||||||
currContext()?.getString(R.string.answer_7)?:""
|
currContext()?.getString(R.string.answer_7) ?: ""
|
||||||
),
|
),
|
||||||
Triple(
|
Triple(
|
||||||
R.drawable.ic_round_lock_open_24,
|
R.drawable.ic_round_lock_open_24,
|
||||||
currContext()?.getString(R.string.question_9)?:"",
|
currContext()?.getString(R.string.question_9) ?: "",
|
||||||
currContext()?.getString(R.string.answer_9)?:""
|
currContext()?.getString(R.string.answer_9) ?: ""
|
||||||
),
|
),
|
||||||
Triple(
|
Triple(
|
||||||
R.drawable.ic_round_smart_button_24,
|
R.drawable.ic_round_smart_button_24,
|
||||||
currContext()?.getString(R.string.question_10)?:"",
|
currContext()?.getString(R.string.question_10) ?: "",
|
||||||
currContext()?.getString(R.string.answer_10)?:""
|
currContext()?.getString(R.string.answer_10) ?: ""
|
||||||
),
|
),
|
||||||
Triple(
|
Triple(
|
||||||
R.drawable.ic_round_smart_button_24,
|
R.drawable.ic_round_smart_button_24,
|
||||||
currContext()?.getString(R.string.question_11)?:"",
|
currContext()?.getString(R.string.question_11) ?: "",
|
||||||
currContext()?.getString(R.string.answer_11)?:""
|
currContext()?.getString(R.string.answer_11) ?: ""
|
||||||
),
|
),
|
||||||
Triple(
|
Triple(
|
||||||
R.drawable.ic_round_info_24,
|
R.drawable.ic_round_info_24,
|
||||||
currContext()?.getString(R.string.question_12)?:"",
|
currContext()?.getString(R.string.question_12) ?: "",
|
||||||
currContext()?.getString(R.string.answer_12)?:""
|
currContext()?.getString(R.string.answer_12) ?: ""
|
||||||
),
|
),
|
||||||
Triple(
|
Triple(
|
||||||
R.drawable.ic_round_help_24,
|
R.drawable.ic_round_help_24,
|
||||||
currContext()?.getString(R.string.question_13)?:"",
|
currContext()?.getString(R.string.question_13) ?: "",
|
||||||
currContext()?.getString(R.string.answer_13)?:""
|
currContext()?.getString(R.string.answer_13) ?: ""
|
||||||
),
|
),
|
||||||
Triple(
|
Triple(
|
||||||
R.drawable.ic_round_art_track_24,
|
R.drawable.ic_round_art_track_24,
|
||||||
currContext()?.getString(R.string.question_14)?:"",
|
currContext()?.getString(R.string.question_14) ?: "",
|
||||||
currContext()?.getString(R.string.answer_14)?:""
|
currContext()?.getString(R.string.answer_14) ?: ""
|
||||||
),
|
),
|
||||||
Triple(
|
Triple(
|
||||||
R.drawable.ic_round_video_settings_24,
|
R.drawable.ic_round_video_settings_24,
|
||||||
currContext()?.getString(R.string.question_15)?:"",
|
currContext()?.getString(R.string.question_15) ?: "",
|
||||||
currContext()?.getString(R.string.answer_15)?:""
|
currContext()?.getString(R.string.answer_15) ?: ""
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler {
|
||||||
private val animeExtensionManager: AnimeExtensionManager = Injekt.get()
|
private val animeExtensionManager: AnimeExtensionManager = Injekt.get()
|
||||||
private val extensionsAdapter = AnimeExtensionsAdapter(
|
private val extensionsAdapter = AnimeExtensionsAdapter(
|
||||||
{ pkg ->
|
{ pkg ->
|
||||||
val name= pkg.name
|
val name = pkg.name
|
||||||
val changeUIVisibility: (Boolean) -> Unit = { show ->
|
val changeUIVisibility: (Boolean) -> Unit = { show ->
|
||||||
val activity = requireActivity() as ExtensionsActivity
|
val activity = requireActivity() as ExtensionsActivity
|
||||||
val visibility = if (show) View.VISIBLE else View.GONE
|
val visibility = if (show) View.VISIBLE else View.GONE
|
||||||
|
@ -58,7 +58,8 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler {
|
||||||
activity.findViewById<TabLayout>(R.id.tabLayout).visibility = visibility
|
activity.findViewById<TabLayout>(R.id.tabLayout).visibility = visibility
|
||||||
activity.findViewById<TextInputLayout>(R.id.searchView).visibility = visibility
|
activity.findViewById<TextInputLayout>(R.id.searchView).visibility = visibility
|
||||||
activity.findViewById<ImageView>(R.id.languageselect).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 =
|
activity.findViewById<FrameLayout>(R.id.fragmentExtensionsContainer).visibility =
|
||||||
if (show) View.GONE else View.VISIBLE
|
if (show) View.GONE else View.VISIBLE
|
||||||
}
|
}
|
||||||
|
@ -67,7 +68,8 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler {
|
||||||
if (allSettings.isNotEmpty()) {
|
if (allSettings.isNotEmpty()) {
|
||||||
var selectedSetting = allSettings[0]
|
var selectedSetting = allSettings[0]
|
||||||
if (allSettings.size > 1) {
|
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
|
var selectedIndex = 0
|
||||||
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
|
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
|
||||||
.setTitle("Select a Source")
|
.setTitle("Select a Source")
|
||||||
|
|
|
@ -47,72 +47,76 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler {
|
||||||
private lateinit var extensionsRecyclerView: RecyclerView
|
private lateinit var extensionsRecyclerView: RecyclerView
|
||||||
private val skipIcons = loadData("skip_extension_icons") ?: false
|
private val skipIcons = loadData("skip_extension_icons") ?: false
|
||||||
private val mangaExtensionManager: MangaExtensionManager = Injekt.get()
|
private val mangaExtensionManager: MangaExtensionManager = Injekt.get()
|
||||||
private val extensionsAdapter = MangaExtensionsAdapter({ pkg ->
|
private val extensionsAdapter = MangaExtensionsAdapter(
|
||||||
val name= pkg.name
|
{ pkg ->
|
||||||
val changeUIVisibility: (Boolean) -> Unit = { show ->
|
val name = pkg.name
|
||||||
val activity = requireActivity() as ExtensionsActivity
|
val changeUIVisibility: (Boolean) -> Unit = { show ->
|
||||||
val visibility = if (show) View.VISIBLE else View.GONE
|
val activity = requireActivity() as ExtensionsActivity
|
||||||
activity.findViewById<ViewPager2>(R.id.viewPager).visibility = visibility
|
val visibility = if (show) View.VISIBLE else View.GONE
|
||||||
activity.findViewById<TabLayout>(R.id.tabLayout).visibility = visibility
|
activity.findViewById<ViewPager2>(R.id.viewPager).visibility = visibility
|
||||||
activity.findViewById<TextInputLayout>(R.id.searchView).visibility = visibility
|
activity.findViewById<TabLayout>(R.id.tabLayout).visibility = visibility
|
||||||
activity.findViewById<ImageView>(R.id.languageselect).visibility = visibility
|
activity.findViewById<TextInputLayout>(R.id.searchView).visibility = visibility
|
||||||
activity.findViewById<TextView>(R.id.extensions).text = if (show) getString(R.string.extensions) else name
|
activity.findViewById<ImageView>(R.id.languageselect).visibility = visibility
|
||||||
activity.findViewById<FrameLayout>(R.id.fragmentExtensionsContainer).visibility =
|
activity.findViewById<TextView>(R.id.extensions).text =
|
||||||
if (show) View.GONE else View.VISIBLE
|
if (show) getString(R.string.extensions) else name
|
||||||
}
|
activity.findViewById<FrameLayout>(R.id.fragmentExtensionsContainer).visibility =
|
||||||
var itemSelected = false
|
if (show) View.GONE else View.VISIBLE
|
||||||
val allSettings = pkg.sources.filterIsInstance<ConfigurableSource>()
|
}
|
||||||
if (allSettings.isNotEmpty()) {
|
var itemSelected = false
|
||||||
var selectedSetting = allSettings[0]
|
val allSettings = pkg.sources.filterIsInstance<ConfigurableSource>()
|
||||||
if (allSettings.size > 1) {
|
if (allSettings.isNotEmpty()) {
|
||||||
val names = allSettings.map { LanguageMapper.mapLanguageCodeToName(it.lang) }.toTypedArray()
|
var selectedSetting = allSettings[0]
|
||||||
var selectedIndex = 0
|
if (allSettings.size > 1) {
|
||||||
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
|
val names = allSettings.map { LanguageMapper.mapLanguageCodeToName(it.lang) }
|
||||||
.setTitle("Select a Source")
|
.toTypedArray()
|
||||||
.setSingleChoiceItems(names, selectedIndex) { dialog, which ->
|
var selectedIndex = 0
|
||||||
itemSelected = true
|
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
|
||||||
selectedIndex = which
|
.setTitle("Select a Source")
|
||||||
selectedSetting = allSettings[selectedIndex]
|
.setSingleChoiceItems(names, selectedIndex) { dialog, which ->
|
||||||
dialog.dismiss()
|
itemSelected = true
|
||||||
|
selectedIndex = which
|
||||||
|
selectedSetting = allSettings[selectedIndex]
|
||||||
|
dialog.dismiss()
|
||||||
|
|
||||||
// Move the fragment transaction here
|
// Move the fragment transaction here
|
||||||
val fragment =
|
val fragment =
|
||||||
MangaSourcePreferencesFragment().getInstance(selectedSetting.id) {
|
MangaSourcePreferencesFragment().getInstance(selectedSetting.id) {
|
||||||
|
changeUIVisibility(true)
|
||||||
|
}
|
||||||
|
parentFragmentManager.beginTransaction()
|
||||||
|
.setCustomAnimations(R.anim.slide_up, R.anim.slide_down)
|
||||||
|
.replace(R.id.fragmentExtensionsContainer, fragment)
|
||||||
|
.addToBackStack(null)
|
||||||
|
.commit()
|
||||||
|
}
|
||||||
|
.setOnDismissListener {
|
||||||
|
if (!itemSelected) {
|
||||||
changeUIVisibility(true)
|
changeUIVisibility(true)
|
||||||
}
|
}
|
||||||
parentFragmentManager.beginTransaction()
|
}
|
||||||
.setCustomAnimations(R.anim.slide_up, R.anim.slide_down)
|
.show()
|
||||||
.replace(R.id.fragmentExtensionsContainer, fragment)
|
dialog.window?.setDimAmount(0.8f)
|
||||||
.addToBackStack(null)
|
} else {
|
||||||
.commit()
|
// If there's only one setting, proceed with the fragment transaction
|
||||||
}
|
val fragment =
|
||||||
.setOnDismissListener {
|
MangaSourcePreferencesFragment().getInstance(selectedSetting.id) {
|
||||||
if (!itemSelected) {
|
|
||||||
changeUIVisibility(true)
|
changeUIVisibility(true)
|
||||||
}
|
}
|
||||||
}
|
parentFragmentManager.beginTransaction()
|
||||||
.show()
|
.setCustomAnimations(R.anim.slide_up, R.anim.slide_down)
|
||||||
dialog.window?.setDimAmount(0.8f)
|
.replace(R.id.fragmentExtensionsContainer, fragment)
|
||||||
} else {
|
.addToBackStack(null)
|
||||||
// If there's only one setting, proceed with the fragment transaction
|
.commit()
|
||||||
val fragment = MangaSourcePreferencesFragment().getInstance(selectedSetting.id) {
|
|
||||||
changeUIVisibility(true)
|
|
||||||
}
|
}
|
||||||
parentFragmentManager.beginTransaction()
|
|
||||||
.setCustomAnimations(R.anim.slide_up, R.anim.slide_down)
|
|
||||||
.replace(R.id.fragmentExtensionsContainer, fragment)
|
|
||||||
.addToBackStack(null)
|
|
||||||
.commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide ViewPager2 and TabLayout
|
// Hide ViewPager2 and TabLayout
|
||||||
changeUIVisibility(false)
|
changeUIVisibility(false)
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(requireContext(), "Source is not configurable", Toast.LENGTH_SHORT)
|
Toast.makeText(requireContext(), "Source is not configurable", Toast.LENGTH_SHORT)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ pkg: MangaExtension.Installed , forceDelete: Boolean ->
|
{ pkg: MangaExtension.Installed, forceDelete: Boolean ->
|
||||||
if (isAdded) { // Check if the fragment is currently added to its activity
|
if (isAdded) { // Check if the fragment is currently added to its activity
|
||||||
val context = requireContext() // Store context in a variable
|
val context = requireContext() // Store context in a variable
|
||||||
val notificationManager =
|
val notificationManager =
|
||||||
|
|
|
@ -39,10 +39,11 @@ class InstalledNovelExtensionsFragment : Fragment(), SearchQueryHandler {
|
||||||
private lateinit var extensionsRecyclerView: RecyclerView
|
private lateinit var extensionsRecyclerView: RecyclerView
|
||||||
val skipIcons = loadData("skip_extension_icons") ?: false
|
val skipIcons = loadData("skip_extension_icons") ?: false
|
||||||
private val novelExtensionManager: NovelExtensionManager = Injekt.get()
|
private val novelExtensionManager: NovelExtensionManager = Injekt.get()
|
||||||
private val extensionsAdapter = NovelExtensionsAdapter({ pkg ->
|
private val extensionsAdapter = NovelExtensionsAdapter(
|
||||||
Toast.makeText(requireContext(), "Source is not configurable", Toast.LENGTH_SHORT)
|
{ pkg ->
|
||||||
.show()
|
Toast.makeText(requireContext(), "Source is not configurable", Toast.LENGTH_SHORT)
|
||||||
},
|
.show()
|
||||||
|
},
|
||||||
{ pkg, forceDelete ->
|
{ pkg, forceDelete ->
|
||||||
if (isAdded) { // Check if the fragment is currently added to its activity
|
if (isAdded) { // Check if the fragment is currently added to its activity
|
||||||
val context = requireContext() // Store context in a variable
|
val context = requireContext() // Store context in a variable
|
||||||
|
|
|
@ -97,7 +97,21 @@ class PlayerSettingsActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
|
||||||
val speeds =
|
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)
|
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 curSpeedArr = if (settings.cursedSpeeds) cursedSpeeds else speeds
|
||||||
var speedsName = curSpeedArr.map { "${it}x" }.toTypedArray()
|
var speedsName = curSpeedArr.map { "${it}x" }.toTypedArray()
|
||||||
|
@ -106,13 +120,14 @@ class PlayerSettingsActivity : AppCompatActivity() {
|
||||||
val speedDialog = AlertDialog.Builder(this, R.style.DialogTheme)
|
val speedDialog = AlertDialog.Builder(this, R.style.DialogTheme)
|
||||||
.setTitle(getString(R.string.default_speed))
|
.setTitle(getString(R.string.default_speed))
|
||||||
binding.playerSettingsSpeed.setOnClickListener {
|
binding.playerSettingsSpeed.setOnClickListener {
|
||||||
val dialog = speedDialog.setSingleChoiceItems(speedsName, settings.defaultSpeed) { dialog, i ->
|
val dialog =
|
||||||
settings.defaultSpeed = i
|
speedDialog.setSingleChoiceItems(speedsName, settings.defaultSpeed) { dialog, i ->
|
||||||
binding.playerSettingsSpeed.text =
|
settings.defaultSpeed = i
|
||||||
getString(R.string.default_playback_speed, speedsName[i])
|
binding.playerSettingsSpeed.text =
|
||||||
saveData(player, settings)
|
getString(R.string.default_playback_speed, speedsName[i])
|
||||||
dialog.dismiss()
|
saveData(player, settings)
|
||||||
}.show()
|
dialog.dismiss()
|
||||||
|
}.show()
|
||||||
dialog.window?.setDimAmount(0.8f)
|
dialog.window?.setDimAmount(0.8f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,11 +271,12 @@ class PlayerSettingsActivity : AppCompatActivity() {
|
||||||
val resizeDialog = AlertDialog.Builder(this, R.style.DialogTheme)
|
val resizeDialog = AlertDialog.Builder(this, R.style.DialogTheme)
|
||||||
.setTitle(getString(R.string.default_resize_mode))
|
.setTitle(getString(R.string.default_resize_mode))
|
||||||
binding.playerResizeMode.setOnClickListener {
|
binding.playerResizeMode.setOnClickListener {
|
||||||
val dialog = resizeDialog.setSingleChoiceItems(resizeModes, settings.resize) { dialog, count ->
|
val dialog =
|
||||||
settings.resize = count
|
resizeDialog.setSingleChoiceItems(resizeModes, settings.resize) { dialog, count ->
|
||||||
saveData(player, settings)
|
settings.resize = count
|
||||||
dialog.dismiss()
|
saveData(player, settings)
|
||||||
}.show()
|
dialog.dismiss()
|
||||||
|
}.show()
|
||||||
dialog.window?.setDimAmount(0.8f)
|
dialog.window?.setDimAmount(0.8f)
|
||||||
}
|
}
|
||||||
fun restartApp() {
|
fun restartApp() {
|
||||||
|
@ -382,7 +398,10 @@ class PlayerSettingsActivity : AppCompatActivity() {
|
||||||
val outlineDialog = AlertDialog.Builder(this, R.style.DialogTheme)
|
val outlineDialog = AlertDialog.Builder(this, R.style.DialogTheme)
|
||||||
.setTitle(getString(R.string.outline_type))
|
.setTitle(getString(R.string.outline_type))
|
||||||
binding.videoSubOutline.setOnClickListener {
|
binding.videoSubOutline.setOnClickListener {
|
||||||
val dialog = outlineDialog.setSingleChoiceItems(typesOutline, settings.outline) { dialog, count ->
|
val dialog = outlineDialog.setSingleChoiceItems(
|
||||||
|
typesOutline,
|
||||||
|
settings.outline
|
||||||
|
) { dialog, count ->
|
||||||
settings.outline = count
|
settings.outline = count
|
||||||
saveData(player, settings)
|
saveData(player, settings)
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
package ani.dantotsu.settings
|
package ani.dantotsu.settings
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.AdapterView
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.updateLayoutParams
|
import androidx.core.view.updateLayoutParams
|
||||||
import ani.dantotsu.NoPaddingArrayAdapter
|
|
||||||
import ani.dantotsu.R
|
import ani.dantotsu.R
|
||||||
import ani.dantotsu.databinding.ActivityReaderSettingsBinding
|
import ani.dantotsu.databinding.ActivityReaderSettingsBinding
|
||||||
import ani.dantotsu.initActivity
|
import ani.dantotsu.initActivity
|
||||||
import ani.dantotsu.loadData
|
import ani.dantotsu.loadData
|
||||||
import ani.dantotsu.media.novel.novelreader.NovelReaderActivity
|
|
||||||
import ani.dantotsu.navBarHeight
|
import ani.dantotsu.navBarHeight
|
||||||
import ani.dantotsu.others.LangSet
|
import ani.dantotsu.others.LangSet
|
||||||
import ani.dantotsu.saveData
|
import ani.dantotsu.saveData
|
||||||
|
|
|
@ -58,7 +58,7 @@ import uy.kohesive.injekt.api.get
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
|
||||||
class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListener {
|
class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListener {
|
||||||
private val restartMainActivity = object : OnBackPressedCallback(false) {
|
private val restartMainActivity = object : OnBackPressedCallback(false) {
|
||||||
override fun handleOnBackPressed() = startMainActivity(this@SettingsActivity)
|
override fun handleOnBackPressed() = startMainActivity(this@SettingsActivity)
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,8 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListen
|
||||||
private val networkPreferences = Injekt.get<NetworkPreferences>()
|
private val networkPreferences = Injekt.get<NetworkPreferences>()
|
||||||
private var cursedCounter = 0
|
private var cursedCounter = 0
|
||||||
|
|
||||||
@OptIn(UnstableApi::class) @SuppressLint("SetTextI18n")
|
@OptIn(UnstableApi::class)
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
LangSet.setLocale(this)
|
LangSet.setLocale(this)
|
||||||
|
@ -188,12 +189,14 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListen
|
||||||
"custom_theme_int",
|
"custom_theme_int",
|
||||||
Color.parseColor("#6200EE")
|
Color.parseColor("#6200EE")
|
||||||
)
|
)
|
||||||
|
|
||||||
class CustomColorDialog : SimpleColorDialog() { //idk where to put it
|
class CustomColorDialog : SimpleColorDialog() { //idk where to put it
|
||||||
override fun onPositiveButtonClick() {
|
override fun onPositiveButtonClick() {
|
||||||
restartApp()
|
restartApp()
|
||||||
super.onPositiveButtonClick()
|
super.onPositiveButtonClick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val tag = "colorPicker"
|
val tag = "colorPicker"
|
||||||
CustomColorDialog().title("Custom Theme")
|
CustomColorDialog().title("Custom Theme")
|
||||||
.colorPreset(originalColor)
|
.colorPreset(originalColor)
|
||||||
|
@ -240,7 +243,10 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListen
|
||||||
AlertDialog.Builder(this, R.style.DialogTheme).setTitle("Download Manager")
|
AlertDialog.Builder(this, R.style.DialogTheme).setTitle("Download Manager")
|
||||||
var downloadManager = loadData<Int>("settings_download_manager") ?: 0
|
var downloadManager = loadData<Int>("settings_download_manager") ?: 0
|
||||||
binding.settingsDownloadManager.setOnClickListener {
|
binding.settingsDownloadManager.setOnClickListener {
|
||||||
val dialog = downloadManagerDialog.setSingleChoiceItems(managers, downloadManager) { dialog, count ->
|
val dialog = downloadManagerDialog.setSingleChoiceItems(
|
||||||
|
managers,
|
||||||
|
downloadManager
|
||||||
|
) { dialog, count ->
|
||||||
downloadManager = count
|
downloadManager = count
|
||||||
saveData("settings_download_manager", downloadManager)
|
saveData("settings_download_manager", downloadManager)
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
|
@ -255,7 +261,11 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListen
|
||||||
.setPositiveButton("Yes") { dialog, _ ->
|
.setPositiveButton("Yes") { dialog, _ ->
|
||||||
val downloadsManager = Injekt.get<DownloadsManager>()
|
val downloadsManager = Injekt.get<DownloadsManager>()
|
||||||
downloadsManager.purgeDownloads(DownloadedType.Type.ANIME)
|
downloadsManager.purgeDownloads(DownloadedType.Type.ANIME)
|
||||||
DownloadService.sendRemoveAllDownloads(this, ExoplayerDownloadService::class.java, false)
|
DownloadService.sendRemoveAllDownloads(
|
||||||
|
this,
|
||||||
|
ExoplayerDownloadService::class.java,
|
||||||
|
false
|
||||||
|
)
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
.setNegativeButton("No") { dialog, _ ->
|
.setNegativeButton("No") { dialog, _ ->
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package ani.dantotsu.settings
|
package ani.dantotsu.settings
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
|
@ -9,25 +9,24 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import ani.dantotsu.BottomSheetDialogFragment
|
import ani.dantotsu.BottomSheetDialogFragment
|
||||||
import ani.dantotsu.R
|
|
||||||
import ani.dantotsu.MainActivity
|
import ani.dantotsu.MainActivity
|
||||||
|
import ani.dantotsu.R
|
||||||
import ani.dantotsu.connections.anilist.Anilist
|
import ani.dantotsu.connections.anilist.Anilist
|
||||||
import ani.dantotsu.databinding.BottomSheetSettingsBinding
|
import ani.dantotsu.databinding.BottomSheetSettingsBinding
|
||||||
import ani.dantotsu.download.manga.OfflineMangaFragment
|
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.AnimeFragment
|
||||||
import ani.dantotsu.home.HomeFragment
|
import ani.dantotsu.home.HomeFragment
|
||||||
import ani.dantotsu.home.LoginFragment
|
import ani.dantotsu.home.LoginFragment
|
||||||
import ani.dantotsu.home.MangaFragment
|
import ani.dantotsu.home.MangaFragment
|
||||||
import ani.dantotsu.home.NoInternet
|
import ani.dantotsu.home.NoInternet
|
||||||
|
import ani.dantotsu.loadImage
|
||||||
import ani.dantotsu.offline.OfflineFragment
|
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 var _binding: BottomSheetSettingsBinding? = null
|
||||||
private val binding get() = _binding!!
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
@ -36,8 +35,10 @@ class SettingsDialogFragment() : BottomSheetDialogFragment() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
pageType = arguments?.getSerializable("pageType") as? PageType ?: PageType.HOME
|
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(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
|
@ -81,8 +82,8 @@ class SettingsDialogFragment() : BottomSheetDialogFragment() {
|
||||||
) ?: false
|
) ?: false
|
||||||
|
|
||||||
binding.settingsIncognito.setOnCheckedChangeListener { _, isChecked ->
|
binding.settingsIncognito.setOnCheckedChangeListener { _, isChecked ->
|
||||||
context?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)?.edit()
|
context?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)?.edit()
|
||||||
?.putBoolean("incognito", isChecked)?.apply()
|
?.putBoolean("incognito", isChecked)?.apply()
|
||||||
}
|
}
|
||||||
binding.settingsExtensionSettings.setSafeOnClickListener {
|
binding.settingsExtensionSettings.setSafeOnClickListener {
|
||||||
startActivity(Intent(activity, ExtensionsActivity::class.java))
|
startActivity(Intent(activity, ExtensionsActivity::class.java))
|
||||||
|
@ -102,7 +103,8 @@ class SettingsDialogFragment() : BottomSheetDialogFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.settingsDownloads.isChecked =
|
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 ->
|
binding.settingsDownloads.setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
|
||||||
if (!isChecked) {
|
if (!isChecked) {
|
||||||
|
@ -112,11 +114,16 @@ class SettingsDialogFragment() : BottomSheetDialogFragment() {
|
||||||
intent.putExtra("FRAGMENT_CLASS_NAME", MangaFragment::class.java.name)
|
intent.putExtra("FRAGMENT_CLASS_NAME", MangaFragment::class.java.name)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
PageType2.OfflineHOME -> { //no offline home for now
|
PageType2.OfflineHOME -> { //no offline home for now
|
||||||
val intent = Intent(activity, MainActivity::class.java)
|
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)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
PageType2.OfflineANIME -> { //no offline anime for now
|
PageType2.OfflineANIME -> { //no offline anime for now
|
||||||
val intent = Intent(activity, MainActivity::class.java)
|
val intent = Intent(activity, MainActivity::class.java)
|
||||||
intent.putExtra("FRAGMENT_CLASS_NAME", AnimeFragment::class.java.name)
|
intent.putExtra("FRAGMENT_CLASS_NAME", AnimeFragment::class.java.name)
|
||||||
|
@ -127,14 +134,19 @@ class SettingsDialogFragment() : BottomSheetDialogFragment() {
|
||||||
when (pageType) {
|
when (pageType) {
|
||||||
PageType.MANGA -> {
|
PageType.MANGA -> {
|
||||||
val intent = Intent(activity, NoInternet::class.java)
|
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)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
PageType.ANIME -> {
|
|
||||||
val intent = Intent(activity, NoInternet::class.java)
|
PageType.ANIME -> {
|
||||||
intent.putExtra("FRAGMENT_CLASS_NAME", OfflineFragment::class.java.name)
|
val intent = Intent(activity, NoInternet::class.java)
|
||||||
startActivity(intent)
|
intent.putExtra("FRAGMENT_CLASS_NAME", OfflineFragment::class.java.name)
|
||||||
}
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
PageType.HOME -> {
|
PageType.HOME -> {
|
||||||
val intent = Intent(activity, NoInternet::class.java)
|
val intent = Intent(activity, NoInternet::class.java)
|
||||||
intent.putExtra("FRAGMENT_CLASS_NAME", OfflineFragment::class.java.name)
|
intent.putExtra("FRAGMENT_CLASS_NAME", OfflineFragment::class.java.name)
|
||||||
|
@ -145,8 +157,8 @@ class SettingsDialogFragment() : BottomSheetDialogFragment() {
|
||||||
dismiss()
|
dismiss()
|
||||||
context?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)?.edit()
|
context?.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE)?.edit()
|
||||||
?.putBoolean("offlineMode", isChecked)?.apply()
|
?.putBoolean("offlineMode", isChecked)?.apply()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
|
@ -157,9 +169,11 @@ class SettingsDialogFragment() : BottomSheetDialogFragment() {
|
||||||
enum class PageType {
|
enum class PageType {
|
||||||
MANGA, ANIME, HOME
|
MANGA, ANIME, HOME
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class PageType2 {
|
enum class PageType2 {
|
||||||
OfflineMANGA, OfflineANIME, OfflineHOME
|
OfflineMANGA, OfflineANIME, OfflineHOME
|
||||||
}
|
}
|
||||||
|
|
||||||
fun newInstance(pageType: PageType): SettingsDialogFragment {
|
fun newInstance(pageType: PageType): SettingsDialogFragment {
|
||||||
val fragment = SettingsDialogFragment()
|
val fragment = SettingsDialogFragment()
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
|
@ -167,6 +181,7 @@ class SettingsDialogFragment() : BottomSheetDialogFragment() {
|
||||||
fragment.arguments = args
|
fragment.arguments = args
|
||||||
return fragment
|
return fragment
|
||||||
}
|
}
|
||||||
|
|
||||||
fun newInstance2(pageType: PageType2): SettingsDialogFragment {
|
fun newInstance2(pageType: PageType2): SettingsDialogFragment {
|
||||||
val fragment = SettingsDialogFragment()
|
val fragment = SettingsDialogFragment()
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
|
|
|
@ -44,14 +44,14 @@ class UserInterfaceSettingsActivity : AppCompatActivity() {
|
||||||
binding.uiSettingsHomeLayout.setOnClickListener {
|
binding.uiSettingsHomeLayout.setOnClickListener {
|
||||||
val dialog = AlertDialog.Builder(this, R.style.DialogTheme)
|
val dialog = AlertDialog.Builder(this, R.style.DialogTheme)
|
||||||
.setTitle(getString(R.string.home_layout_show)).apply {
|
.setTitle(getString(R.string.home_layout_show)).apply {
|
||||||
setMultiChoiceItems(
|
setMultiChoiceItems(
|
||||||
views,
|
views,
|
||||||
settings.homeLayoutShow.toBooleanArray()
|
settings.homeLayoutShow.toBooleanArray()
|
||||||
) { _, i, value ->
|
) { _, i, value ->
|
||||||
settings.homeLayoutShow[i] = value
|
settings.homeLayoutShow[i] = value
|
||||||
saveData(ui, settings)
|
saveData(ui, settings)
|
||||||
}
|
}
|
||||||
}.show()
|
}.show()
|
||||||
dialog.window?.setDimAmount(0.8f)
|
dialog.window?.setDimAmount(0.8f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,8 @@ class AnimeExtensionPagingSource(
|
||||||
} else {
|
} else {
|
||||||
availableExtensions.filter { it.name.contains(query, ignoreCase = true) }
|
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 {
|
return try {
|
||||||
val sublist = filternfsw.subList(
|
val sublist = filternfsw.subList(
|
||||||
fromIndex = position,
|
fromIndex = position,
|
||||||
|
|
|
@ -98,7 +98,8 @@ class MangaExtensionPagingSource(
|
||||||
} else {
|
} else {
|
||||||
availableExtensions.filter { it.name.contains(query, ignoreCase = true) }
|
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 {
|
return try {
|
||||||
val sublist = filternfsw.subList(
|
val sublist = filternfsw.subList(
|
||||||
fromIndex = position,
|
fromIndex = position,
|
||||||
|
@ -192,6 +193,7 @@ class MangaExtensionAdapter(private val clickListener: OnMangaInstallClickListen
|
||||||
}
|
}
|
||||||
|
|
||||||
val extensionIconImageView: ImageView = binding.extensionIconImageView
|
val extensionIconImageView: ImageView = binding.extensionIconImageView
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
fun bind(extension: MangaExtension.Available) {
|
fun bind(extension: MangaExtension.Available) {
|
||||||
val nsfw = if (extension.isNsfw) "(18+)" else ""
|
val nsfw = if (extension.isNsfw) "(18+)" else ""
|
||||||
|
|
|
@ -4,17 +4,16 @@ import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.net.Uri
|
|
||||||
import android.widget.RemoteViews
|
import android.widget.RemoteViews
|
||||||
import android.widget.RemoteViewsService
|
import android.widget.RemoteViewsService
|
||||||
import androidx.core.net.toUri
|
|
||||||
import ani.dantotsu.R
|
import ani.dantotsu.R
|
||||||
import ani.dantotsu.logger
|
import ani.dantotsu.logger
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
import java.net.URL
|
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>()
|
private var widgetItems = mutableListOf<WidgetItem>()
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
|
@ -22,7 +21,11 @@ class CurrentlyAiringRemoteViewsFactory(private val context: Context, intent: In
|
||||||
widgetItems.clear()
|
widgetItems.clear()
|
||||||
logger("CurrentlyAiringRemoteViewsFactory onCreate")
|
logger("CurrentlyAiringRemoteViewsFactory onCreate")
|
||||||
widgetItems = List(4) {
|
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()
|
}.toMutableList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,11 +33,41 @@ class CurrentlyAiringRemoteViewsFactory(private val context: Context, intent: In
|
||||||
// 4 items for testing
|
// 4 items for testing
|
||||||
logger("CurrentlyAiringRemoteViewsFactory onDataSetChanged")
|
logger("CurrentlyAiringRemoteViewsFactory onDataSetChanged")
|
||||||
widgetItems.clear()
|
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(
|
||||||
widgetItems.add(WidgetItem("Show 2", "2 days 3 hours 4 minutes", "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"))
|
WidgetItem(
|
||||||
widgetItems.add(WidgetItem("Show 3", "3 days 4 hours 5 minutes", "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"))
|
"Show 1",
|
||||||
widgetItems.add(WidgetItem("Show 4", "4 days 5 hours 6 minutes", "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"))
|
"1 day 2 hours 3 minutes",
|
||||||
widgetItems.add(WidgetItem("Show 5", "5 days 6 hours 7 minutes", "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"))
|
"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() {
|
override fun onDestroy() {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package ani.dantotsu.widgets
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.widget.RemoteViewsService
|
import android.widget.RemoteViewsService
|
||||||
import ani.dantotsu.logger
|
import ani.dantotsu.logger
|
||||||
|
|
||||||
class CurrentlyAiringRemoteViewsService : RemoteViewsService() {
|
class CurrentlyAiringRemoteViewsService : RemoteViewsService() {
|
||||||
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
|
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
|
||||||
logger("CurrentlyAiringRemoteViewsFactory onGetViewFactory")
|
logger("CurrentlyAiringRemoteViewsFactory onGetViewFactory")
|
||||||
|
|
|
@ -20,7 +20,11 @@ import ani.dantotsu.R
|
||||||
* App Widget Configuration implemented in [CurrentlyAiringWidgetConfigureActivity]
|
* App Widget Configuration implemented in [CurrentlyAiringWidgetConfigureActivity]
|
||||||
*/
|
*/
|
||||||
class CurrentlyAiringWidget : AppWidgetProvider() {
|
class CurrentlyAiringWidget : AppWidgetProvider() {
|
||||||
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
|
override fun onUpdate(
|
||||||
|
context: Context,
|
||||||
|
appWidgetManager: AppWidgetManager,
|
||||||
|
appWidgetIds: IntArray
|
||||||
|
) {
|
||||||
appWidgetIds.forEach { appWidgetId ->
|
appWidgetIds.forEach { appWidgetId ->
|
||||||
val intent = Intent(context, CurrentlyAiringRemoteViewsService::class.java).apply {
|
val intent = Intent(context, CurrentlyAiringRemoteViewsService::class.java).apply {
|
||||||
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
|
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
|
||||||
|
@ -36,6 +40,7 @@ class CurrentlyAiringWidget : AppWidgetProvider() {
|
||||||
}
|
}
|
||||||
super.onUpdate(context, appWidgetManager, appWidgetIds)
|
super.onUpdate(context, appWidgetManager, appWidgetIds)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDeleted(context: Context, appWidgetIds: IntArray) {
|
override fun onDeleted(context: Context, appWidgetIds: IntArray) {
|
||||||
// When the user deletes the widget, delete the preference associated with it.
|
// When the user deletes the widget, delete the preference associated with it.
|
||||||
for (appWidgetId in appWidgetIds) {
|
for (appWidgetId in appWidgetIds) {
|
||||||
|
@ -51,6 +56,7 @@ class CurrentlyAiringWidget : AppWidgetProvider() {
|
||||||
override fun onDisabled(context: Context) {
|
override fun onDisabled(context: Context) {
|
||||||
super.onDisabled(context)
|
super.onDisabled(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun updateAppWidget(
|
fun updateAppWidget(
|
||||||
context: Context,
|
context: Context,
|
||||||
|
@ -60,10 +66,15 @@ class CurrentlyAiringWidget : AppWidgetProvider() {
|
||||||
) {
|
) {
|
||||||
// Create an intent to launch the configuration activity when the widget is clicked
|
// Create an intent to launch the configuration activity when the widget is clicked
|
||||||
val intent = Intent(context, CurrentlyAiringWidgetConfigureActivity::class.java)
|
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
|
// 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.
|
gradientDrawable.colors = intArrayOf(color, Color.GRAY) // End color is gray.
|
||||||
|
|
||||||
// Create the RemoteViews object and set the background
|
// Create the RemoteViews object and set the background
|
||||||
|
|
|
@ -57,7 +57,7 @@ class CurrentlyAiringWidgetConfigureActivity : Activity() {
|
||||||
binding = CurrentlyAiringWidgetConfigureBinding.inflate(layoutInflater)
|
binding = CurrentlyAiringWidgetConfigureBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
appWidgetText = binding.appwidgetText as EditText
|
appWidgetText = binding.appwidgetText
|
||||||
binding.addButton.setOnClickListener(onClickListener)
|
binding.addButton.setOnClickListener(onClickListener)
|
||||||
|
|
||||||
// Find the widget id from the intent.
|
// Find the widget id from the intent.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue