diff --git a/README.md b/README.md
index 6b713a2a..76bece4b 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ Dantotsu is an [Anilist](https://anilist.co/) only client.
> **Dantotsu (断トツ; Dan-totsu)** literally means "the best of the best" in Japanese. Try it out for yourself and be the judge!
-
+
## Terms of Use
By downloading, installing, or using this application, you agree to:
diff --git a/app/build.gradle b/app/build.gradle
index 0604d87e..915b3ba8 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -17,8 +17,9 @@ android {
applicationId "ani.dantotsu"
minSdk 21
targetSdk 35
- versionName "3.2.2"
- versionCode 300200200
+ versionCode((System.currentTimeMillis() / 60000).toInteger())
+ versionName "3.2.0"
+ versionCode 300200000
signingConfig signingConfigs.debug
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a0e43c2e..7459e050 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,4 +1,4 @@
-
+`
diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/api/Media.kt b/app/src/main/java/ani/dantotsu/connections/anilist/api/Media.kt
index c833f913..4f3509f6 100644
--- a/app/src/main/java/ani/dantotsu/connections/anilist/api/Media.kt
+++ b/app/src/main/java/ani/dantotsu/connections/anilist/api/Media.kt
@@ -253,7 +253,7 @@ data class MediaStreamingEpisode(
// The site location of the streaming episode
@SerialName("site") var site: String?,
-) : java.io.Serializable
+)
@Serializable
data class MediaCoverImage(
diff --git a/app/src/main/java/ani/dantotsu/connections/discord/RPC.kt b/app/src/main/java/ani/dantotsu/connections/discord/RPC.kt
index eec99b96..20bafb39 100644
--- a/app/src/main/java/ani/dantotsu/connections/discord/RPC.kt
+++ b/app/src/main/java/ani/dantotsu/connections/discord/RPC.kt
@@ -50,9 +50,8 @@ open class RPC(val token: String, val coroutineContext: CoroutineContext) {
val assetApi = RPCExternalAsset(data.applicationId, token!!, client, json)
suspend fun String.discordUrl() = assetApi.getDiscordUri(this)
- return json.encodeToString(
- Presence.Response(
- 3,
+ return json.encodeToString(Presence.Response(
+ 3,
Presence(
activities = listOf(
Activity(
diff --git a/app/src/main/java/ani/dantotsu/download/manga/MangaDownloaderService.kt b/app/src/main/java/ani/dantotsu/download/manga/MangaDownloaderService.kt
index 2ea82108..58e7de38 100644
--- a/app/src/main/java/ani/dantotsu/download/manga/MangaDownloaderService.kt
+++ b/app/src/main/java/ani/dantotsu/download/manga/MangaDownloaderService.kt
@@ -232,18 +232,12 @@ class MangaDownloaderService : Service() {
image.page,
image.source
)
- if (bitmap == null) {
- snackString("${task.chapter} - Retrying to download page ${index.ofLength(3)}, attempt ${retryCount + 1}.")
- }
retryCount++
}
- if (bitmap == null) {
- outputDir.deleteRecursively(this@MangaDownloaderService, false)
- throw Exception("${task.chapter} - Unable to download all pages after $retryCount attempts. Try again.")
+ if (bitmap != null) {
+ saveToDisk("${index.ofLength(3)}.jpg", outputDir, bitmap)
}
-
- saveToDisk("${index.ofLength(3)}.jpg", outputDir, bitmap)
farthest++
builder.setProgress(task.imageData.size, farthest, false)
diff --git a/app/src/main/java/ani/dantotsu/media/anime/ExoplayerView.kt b/app/src/main/java/ani/dantotsu/media/anime/ExoplayerView.kt
index 4de053dd..f8a3f725 100644
--- a/app/src/main/java/ani/dantotsu/media/anime/ExoplayerView.kt
+++ b/app/src/main/java/ani/dantotsu/media/anime/ExoplayerView.kt
@@ -152,7 +152,6 @@ import ani.dantotsu.toPx
import ani.dantotsu.toast
import ani.dantotsu.tryWithSuspend
import ani.dantotsu.util.Logger
-import ani.dantotsu.util.customAlertDialog
import com.anggrayudi.storage.file.extension
import com.bumptech.glide.Glide
import com.google.android.gms.cast.framework.CastButtonFactory
@@ -182,10 +181,8 @@ import kotlin.math.roundToInt
@UnstableApi
@SuppressLint("ClickableViewAccessibility")
-class ExoplayerView :
- AppCompatActivity(),
- Player.Listener,
- SessionAvailabilityListener {
+class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityListener {
+
private val resumeWindow = "resumeWindow"
private val resumePosition = "resumePosition"
private val playerFullscreen = "playerFullscreen"
@@ -286,11 +283,10 @@ class ExoplayerView :
val displayCutout = window.decorView.rootWindowInsets.displayCutout
if (displayCutout != null) {
if (displayCutout.boundingRects.size > 0) {
- notchHeight =
- min(
- displayCutout.boundingRects[0].width(),
- displayCutout.boundingRects[0].height(),
- )
+ notchHeight = min(
+ displayCutout.boundingRects[0].width(),
+ displayCutout.boundingRects[0].height()
+ )
checkNotch()
}
}
@@ -301,8 +297,7 @@ class ExoplayerView :
private fun checkNotch() {
if (notchHeight != 0) {
val orientation = resources.configuration.orientation
- playerView
- .findViewById(R.id.exo_controller_margin)
+ playerView.findViewById(R.id.exo_controller_margin)
.updateLayoutParams {
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
marginStart = notchHeight
@@ -332,30 +327,28 @@ class ExoplayerView :
val secondaryColor = PrefManager.getVal(PrefName.SecondaryColor)
- val outline =
- when (PrefManager.getVal(PrefName.Outline)) {
- 0 -> EDGE_TYPE_OUTLINE // Normal
- 1 -> EDGE_TYPE_DEPRESSED // Shine
- 2 -> EDGE_TYPE_DROP_SHADOW // Drop shadow
- 3 -> EDGE_TYPE_NONE // No outline
- else -> EDGE_TYPE_OUTLINE // Normal
- }
+ val outline = when (PrefManager.getVal(PrefName.Outline)) {
+ 0 -> EDGE_TYPE_OUTLINE // Normal
+ 1 -> EDGE_TYPE_DEPRESSED // Shine
+ 2 -> EDGE_TYPE_DROP_SHADOW // Drop shadow
+ 3 -> EDGE_TYPE_NONE // No outline
+ else -> EDGE_TYPE_OUTLINE // Normal
+ }
val subBackground = PrefManager.getVal(PrefName.SubBackground)
val subWindow = PrefManager.getVal(PrefName.SubWindow)
- val font =
- when (PrefManager.getVal(PrefName.Font)) {
- 0 -> ResourcesCompat.getFont(this, R.font.poppins_semi_bold)
- 1 -> ResourcesCompat.getFont(this, R.font.poppins_bold)
- 2 -> ResourcesCompat.getFont(this, R.font.poppins)
- 3 -> ResourcesCompat.getFont(this, R.font.poppins_thin)
- 4 -> ResourcesCompat.getFont(this, R.font.century_gothic_regular)
- 5 -> ResourcesCompat.getFont(this, R.font.levenim_mt_bold)
- 6 -> ResourcesCompat.getFont(this, R.font.blocky)
- else -> ResourcesCompat.getFont(this, R.font.poppins_semi_bold)
- }
+ val font = when (PrefManager.getVal(PrefName.Font)) {
+ 0 -> ResourcesCompat.getFont(this, R.font.poppins_semi_bold)
+ 1 -> ResourcesCompat.getFont(this, R.font.poppins_bold)
+ 2 -> ResourcesCompat.getFont(this, R.font.poppins)
+ 3 -> ResourcesCompat.getFont(this, R.font.poppins_thin)
+ 4 -> ResourcesCompat.getFont(this, R.font.century_gothic_regular)
+ 5 -> ResourcesCompat.getFont(this, R.font.levenim_mt_bold)
+ 6 -> ResourcesCompat.getFont(this, R.font.blocky)
+ else -> ResourcesCompat.getFont(this, R.font.poppins_semi_bold)
+ }
val fontSize = PrefManager.getVal(PrefName.FontSize).toFloat()
playerView.subtitleView?.let { subtitles ->
@@ -369,8 +362,8 @@ class ExoplayerView :
subWindow,
outline,
secondaryColor,
- font,
- ),
+ font
+ )
)
subtitles.alpha =
@@ -394,17 +387,16 @@ class ExoplayerView :
val fontSize = PrefManager.getVal(PrefName.FontSize).toFloat()
- val font =
- when (PrefManager.getVal(PrefName.Font)) {
- 0 -> ResourcesCompat.getFont(this, R.font.poppins_semi_bold)
- 1 -> ResourcesCompat.getFont(this, R.font.poppins_bold)
- 2 -> ResourcesCompat.getFont(this, R.font.poppins)
- 3 -> ResourcesCompat.getFont(this, R.font.poppins_thin)
- 4 -> ResourcesCompat.getFont(this, R.font.century_gothic_regular)
- 5 -> ResourcesCompat.getFont(this, R.font.levenim_mt_bold)
- 6 -> ResourcesCompat.getFont(this, R.font.blocky)
- else -> ResourcesCompat.getFont(this, R.font.poppins_semi_bold)
- }
+ val font = when (PrefManager.getVal(PrefName.Font)) {
+ 0 -> ResourcesCompat.getFont(this, R.font.poppins_semi_bold)
+ 1 -> ResourcesCompat.getFont(this, R.font.poppins_bold)
+ 2 -> ResourcesCompat.getFont(this, R.font.poppins)
+ 3 -> ResourcesCompat.getFont(this, R.font.poppins_thin)
+ 4 -> ResourcesCompat.getFont(this, R.font.century_gothic_regular)
+ 5 -> ResourcesCompat.getFont(this, R.font.levenim_mt_bold)
+ 6 -> ResourcesCompat.getFont(this, R.font.blocky)
+ else -> ResourcesCompat.getFont(this, R.font.poppins_semi_bold)
+ }
textView.setBackgroundColor(subBackground)
textView.setTextColor(primaryColor)
@@ -439,9 +431,8 @@ class ExoplayerView :
binding = ActivityExoplayerBinding.inflate(layoutInflater)
setContentView(binding.root)
- // Initialize
- isCastApiAvailable = GoogleApiAvailability
- .getInstance()
+ //Initialize
+ isCastApiAvailable = GoogleApiAvailability.getInstance()
.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS
try {
castContext =
@@ -540,34 +531,27 @@ class ExoplayerView :
isPlayerPlaying = savedInstanceState.getBoolean(playerOnPlay)
}
- // BackButton
+ //BackButton
playerView.findViewById(R.id.exo_back).setOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
- // TimeStamps
+ //TimeStamps
model.timeStamps.observe(this) { it ->
isTimeStampsLoaded = true
- exoSkipOpEd.visibility =
- if (it != null) {
- val adGroups =
- it
- .flatMap {
- listOf(
- it.interval.startTime.toLong() * 1000,
- it.interval.endTime.toLong() * 1000,
- )
- }.toLongArray()
- val playedAdGroups =
- it
- .flatMap {
- listOf(false, false)
- }.toBooleanArray()
- playerView.setExtraAdGroupMarkers(adGroups, playedAdGroups)
- View.VISIBLE
- } else {
- View.GONE
- }
+ exoSkipOpEd.visibility = if (it != null) {
+ val adGroups = it.flatMap {
+ listOf(
+ it.interval.startTime.toLong() * 1000,
+ it.interval.endTime.toLong() * 1000
+ )
+ }.toLongArray()
+ val playedAdGroups = it.flatMap {
+ listOf(false, false)
+ }.toBooleanArray()
+ playerView.setExtraAdGroupMarkers(adGroups, playedAdGroups)
+ View.VISIBLE
+ } else View.GONE
}
exoSkipOpEd.alpha = if (PrefManager.getVal(PrefName.AutoSkipOPED)) 1f else 0.3f
@@ -582,7 +566,7 @@ class ExoplayerView :
exoSkipOpEd.alpha = if (PrefManager.getVal(PrefName.AutoSkipOPED)) 1f else 0.3f
}
- // Play Pause
+ //Play Pause
exoPlay.setOnClickListener {
if (isInitialized) {
isPlayerPlaying = exoPlayer.isPlaying
@@ -606,21 +590,19 @@ class ExoplayerView :
// Picture-in-picture
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
pipEnabled =
- packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE) &&
- PrefManager.getVal(
- PrefName.Pip,
- )
+ packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE) && PrefManager.getVal(
+ PrefName.Pip
+ )
if (pipEnabled) {
exoPip.visibility = View.VISIBLE
exoPip.setOnClickListener {
enterPipMode()
}
- } else {
- exoPip.visibility = View.GONE
- }
+ } else exoPip.visibility = View.GONE
}
- // Lock Button
+
+ //Lock Button
var locked = false
val container = playerView.findViewById(R.id.exo_controller_cont)
val screen = playerView.findViewById(R.id.exo_black_screen)
@@ -642,14 +624,13 @@ class ExoplayerView :
timeline.setForceDisabled(false)
}
- // Skip Time Button
+ //Skip Time Button
var skipTime = PrefManager.getVal(PrefName.SkipTime)
if (skipTime > 0) {
exoSkip.findViewById(R.id.exo_skip_time).text = skipTime.toString()
exoSkip.setOnClickListener {
- if (isInitialized) {
+ if (isInitialized)
exoPlayer.seekTo(exoPlayer.currentPosition + skipTime * 1000)
- }
}
exoSkip.setOnLongClickListener {
val dialog = Dialog(this, R.style.MyPopup)
@@ -658,7 +639,7 @@ class ExoplayerView :
dialog.setCanceledOnTouchOutside(true)
dialog.window?.setLayout(
ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
)
if (skipTime <= 120) {
dialog.findViewById(R.id.seekbar).value = skipTime.toFloat()
@@ -667,24 +648,20 @@ class ExoplayerView :
}
dialog.findViewById(R.id.seekbar).addOnChangeListener { _, value, _ ->
skipTime = value.toInt()
- // saveData(player, settings)
+ //saveData(player, settings)
PrefManager.setVal(PrefName.SkipTime, skipTime)
playerView.findViewById(R.id.exo_skip_time).text =
skipTime.toString()
dialog.findViewById(R.id.seekbar_value).text =
skipTime.toString()
}
- dialog
- .findViewById(R.id.seekbar)
- .addOnSliderTouchListener(
- object : Slider.OnSliderTouchListener {
- override fun onStartTrackingTouch(slider: Slider) {}
-
- override fun onStopTrackingTouch(slider: Slider) {
- dialog.dismiss()
- }
- },
- )
+ dialog.findViewById(R.id.seekbar)
+ .addOnSliderTouchListener(object : Slider.OnSliderTouchListener {
+ override fun onStartTrackingTouch(slider: Slider) {}
+ override fun onStopTrackingTouch(slider: Slider) {
+ dialog.dismiss()
+ }
+ })
dialog.findViewById(R.id.seekbar_title).text =
getString(R.string.skip_time)
dialog.findViewById(R.id.seekbar_value).text =
@@ -699,136 +676,99 @@ class ExoplayerView :
}
val gestureSpeed = (300 * PrefManager.getVal(PrefName.AnimationSpeed)).toLong()
- // Player UI Visibility Handler
- val brightnessRunnable =
- Runnable {
- if (exoBrightnessCont.alpha == 1f) {
- lifecycleScope.launch {
- ObjectAnimator
- .ofFloat(exoBrightnessCont, "alpha", 1f, 0f)
- .setDuration(gestureSpeed)
- .start()
- delay(gestureSpeed)
- exoBrightnessCont.visibility = View.GONE
- checkNotch()
- }
+ //Player UI Visibility Handler
+ val brightnessRunnable = Runnable {
+ if (exoBrightnessCont.alpha == 1f)
+ lifecycleScope.launch {
+ ObjectAnimator.ofFloat(exoBrightnessCont, "alpha", 1f, 0f)
+ .setDuration(gestureSpeed).start()
+ delay(gestureSpeed)
+ exoBrightnessCont.visibility = View.GONE
+ checkNotch()
}
+ }
+ val volumeRunnable = Runnable {
+ if (exoVolumeCont.alpha == 1f)
+ lifecycleScope.launch {
+ ObjectAnimator.ofFloat(exoVolumeCont, "alpha", 1f, 0f).setDuration(gestureSpeed)
+ .start()
+ delay(gestureSpeed)
+ exoVolumeCont.visibility = View.GONE
+ checkNotch()
+ }
+ }
+ playerView.setControllerVisibilityListener(PlayerView.ControllerVisibilityListener { visibility ->
+ if (visibility == View.GONE) {
+ hideSystemBars()
+ brightnessRunnable.run()
+ volumeRunnable.run()
}
- val volumeRunnable =
- Runnable {
- if (exoVolumeCont.alpha == 1f) {
- lifecycleScope.launch {
- ObjectAnimator
- .ofFloat(exoVolumeCont, "alpha", 1f, 0f)
- .setDuration(gestureSpeed)
- .start()
- delay(gestureSpeed)
- exoVolumeCont.visibility = View.GONE
- checkNotch()
- }
- }
- }
- playerView.setControllerVisibilityListener(
- PlayerView.ControllerVisibilityListener { visibility ->
- if (visibility == View.GONE) {
- hideSystemBars()
- brightnessRunnable.run()
- volumeRunnable.run()
- }
- },
- )
+ })
val overshoot = AnimationUtils.loadInterpolator(this, R.anim.over_shoot)
val controllerDuration = (300 * PrefManager.getVal(PrefName.AnimationSpeed)).toLong()
-
fun handleController() {
if (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) !isInPictureInPictureMode else true) {
if (playerView.isControllerFullyVisible) {
- ObjectAnimator
- .ofFloat(
- playerView.findViewById(R.id.exo_controller),
- "alpha",
- 1f,
- 0f,
- ).setDuration(controllerDuration)
- .start()
- ObjectAnimator
- .ofFloat(
- playerView.findViewById(R.id.exo_bottom_cont),
- "translationY",
- 0f,
- 128f,
- ).apply {
- interpolator = overshoot
- duration = controllerDuration
- start()
- }
- ObjectAnimator
- .ofFloat(
- playerView.findViewById(R.id.exo_timeline_cont),
- "translationY",
- 0f,
- 128f,
- ).apply {
- interpolator = overshoot
- duration = controllerDuration
- start()
- }
- ObjectAnimator
- .ofFloat(
- playerView.findViewById(R.id.exo_top_cont),
- "translationY",
- 0f,
- -128f,
- ).apply {
- interpolator = overshoot
- duration = controllerDuration
- start()
- }
+ ObjectAnimator.ofFloat(
+ playerView.findViewById(R.id.exo_controller),
+ "alpha",
+ 1f,
+ 0f
+ )
+ .setDuration(controllerDuration).start()
+ ObjectAnimator.ofFloat(
+ playerView.findViewById(R.id.exo_bottom_cont),
+ "translationY",
+ 0f,
+ 128f
+ )
+ .apply { interpolator = overshoot;duration = controllerDuration;start() }
+ ObjectAnimator.ofFloat(
+ playerView.findViewById(R.id.exo_timeline_cont),
+ "translationY",
+ 0f,
+ 128f
+ )
+ .apply { interpolator = overshoot;duration = controllerDuration;start() }
+ ObjectAnimator.ofFloat(
+ playerView.findViewById(R.id.exo_top_cont),
+ "translationY",
+ 0f,
+ -128f
+ )
+ .apply { interpolator = overshoot;duration = controllerDuration;start() }
playerView.postDelayed({ playerView.hideController() }, controllerDuration)
} else {
checkNotch()
playerView.showController()
- ObjectAnimator
- .ofFloat(
- playerView.findViewById(R.id.exo_controller),
- "alpha",
- 0f,
- 1f,
- ).setDuration(controllerDuration)
- .start()
- ObjectAnimator
- .ofFloat(
- playerView.findViewById(R.id.exo_bottom_cont),
- "translationY",
- 128f,
- 0f,
- ).apply {
- interpolator = overshoot
- duration = controllerDuration
- start()
- }
- ObjectAnimator
- .ofFloat(
- playerView.findViewById(R.id.exo_timeline_cont),
- "translationY",
- 128f,
- 0f,
- ).apply {
- interpolator = overshoot
- duration = controllerDuration
- start()
- }
- ObjectAnimator
- .ofFloat(
- playerView.findViewById(R.id.exo_top_cont),
- "translationY",
- -128f,
- 0f,
- ).apply {
- interpolator = overshoot
- duration = controllerDuration
- start()
- }
+ ObjectAnimator.ofFloat(
+ playerView.findViewById(R.id.exo_controller),
+ "alpha",
+ 0f,
+ 1f
+ )
+ .setDuration(controllerDuration).start()
+ ObjectAnimator.ofFloat(
+ playerView.findViewById(R.id.exo_bottom_cont),
+ "translationY",
+ 128f,
+ 0f
+ )
+ .apply { interpolator = overshoot;duration = controllerDuration;start() }
+ ObjectAnimator.ofFloat(
+ playerView.findViewById(R.id.exo_timeline_cont),
+ "translationY",
+ 128f,
+ 0f
+ )
+ .apply { interpolator = overshoot;duration = controllerDuration;start() }
+ ObjectAnimator.ofFloat(
+ playerView.findViewById(R.id.exo_top_cont),
+ "translationY",
+ -128f,
+ 0f
+ )
+ .apply { interpolator = overshoot;duration = controllerDuration;start() }
}
}
}
@@ -842,29 +782,26 @@ class ExoplayerView :
val fastForwardCard = playerView.findViewById(R.id.exo_fast_forward)
val fastRewindCard = playerView.findViewById(R.id.exo_fast_rewind)
- // Seeking
+
+ //Seeking
val seekTimerF = ResettableTimer()
val seekTimerR = ResettableTimer()
var seekTimesF = 0
var seekTimesR = 0
- fun seek(
- forward: Boolean,
- event: MotionEvent? = null,
- ) {
+ fun seek(forward: Boolean, event: MotionEvent? = null) {
val seekTime = PrefManager.getVal(PrefName.SeekTime)
- val (card, text) =
- if (forward) {
- val text = "+${seekTime * ++seekTimesF}"
- forwardText.text = text
- handler.post { exoPlayer.seekTo(exoPlayer.currentPosition + seekTime * 1000) }
- fastForwardCard to forwardText
- } else {
- val text = "-${seekTime * ++seekTimesR}"
- rewindText.text = text
- handler.post { exoPlayer.seekTo(exoPlayer.currentPosition - seekTime * 1000) }
- fastRewindCard to rewindText
- }
+ val (card, text) = if (forward) {
+ val text = "+${seekTime * ++seekTimesF}"
+ forwardText.text = text
+ handler.post { exoPlayer.seekTo(exoPlayer.currentPosition + seekTime * 1000) }
+ fastForwardCard to forwardText
+ } else {
+ val text = "-${seekTime * ++seekTimesR}"
+ rewindText.text = text
+ handler.post { exoPlayer.seekTo(exoPlayer.currentPosition - seekTime * 1000) }
+ fastRewindCard to rewindText
+ }
//region Double Tap Animation
val showCardAnim = ObjectAnimator.ofFloat(card, "alpha", 0f, 1f).setDuration(300)
@@ -899,27 +836,21 @@ class ExoplayerView :
isSeeking = true
if (forward) {
- seekTimerR.reset(
- object : TimerTask() {
- override fun run() {
- isSeeking = false
- stopAnim()
- seekTimesF = 0
- }
- },
- 850,
- )
+ seekTimerR.reset(object : TimerTask() {
+ override fun run() {
+ isSeeking = false
+ stopAnim()
+ seekTimesF = 0
+ }
+ }, 850)
} else {
- seekTimerF.reset(
- object : TimerTask() {
- override fun run() {
- isSeeking = false
- stopAnim()
- seekTimesR = 0
- }
- },
- 850,
- )
+ seekTimerF.reset(object : TimerTask() {
+ override fun run() {
+ isSeeking = false
+ stopAnim()
+ seekTimesR = 0
+ }
+ }, 850)
}
}
@@ -943,30 +874,27 @@ class ExoplayerView :
keyMap[KEYCODE_DPAD_RIGHT] = { seek(true) }
keyMap[KEYCODE_DPAD_LEFT] = { seek(false) }
- // Screen Gestures
+ //Screen Gestures
if (PrefManager.getVal(PrefName.Gestures) || PrefManager.getVal(PrefName.DoubleTap)) {
- fun doubleTap(
- forward: Boolean,
- event: MotionEvent,
- ) {
+
+ fun doubleTap(forward: Boolean, event: MotionEvent) {
if (!locked && isInitialized && PrefManager.getVal(PrefName.DoubleTap)) {
seek(forward, event)
}
}
- // Brightness
+ //Brightness
var brightnessTimer = Timer()
exoBrightnessCont.visibility = View.GONE
fun brightnessHide() {
brightnessTimer.cancel()
brightnessTimer.purge()
- val timerTask: TimerTask =
- object : TimerTask() {
- override fun run() {
- handler.post(brightnessRunnable)
- }
+ val timerTask: TimerTask = object : TimerTask() {
+ override fun run() {
+ handler.post(brightnessRunnable)
}
+ }
brightnessTimer = Timer()
brightnessTimer.schedule(timerTask, 3000)
}
@@ -980,22 +908,20 @@ class ExoplayerView :
brightnessHide()
}
- // Volume
+ //Volume
var volumeTimer = Timer()
exoVolumeCont.visibility = View.GONE
val volumeMax = audioManager.getStreamMaxVolume(STREAM_MUSIC)
exoVolume.value = audioManager.getStreamVolume(STREAM_MUSIC).toFloat() / volumeMax * 10
-
fun volumeHide() {
volumeTimer.cancel()
volumeTimer.purge()
- val timerTask: TimerTask =
- object : TimerTask() {
- override fun run() {
- handler.post(volumeRunnable)
- }
+ val timerTask: TimerTask = object : TimerTask() {
+ override fun run() {
+ handler.post(volumeRunnable)
}
+ }
volumeTimer = Timer()
volumeTimer.schedule(timerTask, 3000)
}
@@ -1005,7 +931,6 @@ class ExoplayerView :
volumeHide()
}
val fastForward = playerView.findViewById(R.id.exo_fast_forward_text)
-
fun fastForward() {
isFastForwarding = true
exoPlayer.setPlaybackSpeed(exoPlayer.playbackParameters.speed * 2)
@@ -1022,33 +947,29 @@ class ExoplayerView :
}
}
- // FastRewind (Left Panel)
- val fastRewindDetector =
- GestureDetector(
- this,
- object : GesturesListener() {
- override fun onLongClick(event: MotionEvent) {
- if (PrefManager.getVal(PrefName.FastForward)) fastForward()
- }
+ //FastRewind (Left Panel)
+ val fastRewindDetector = GestureDetector(this, object : GesturesListener() {
+ override fun onLongClick(event: MotionEvent) {
+ if (PrefManager.getVal(PrefName.FastForward)) fastForward()
+ }
- override fun onDoubleClick(event: MotionEvent) {
- doubleTap(false, event)
- }
+ override fun onDoubleClick(event: MotionEvent) {
+ doubleTap(false, event)
+ }
- override fun onScrollYClick(y: Float) {
- if (!locked && PrefManager.getVal(PrefName.Gestures)) {
- exoBrightness.value = clamp(exoBrightness.value + y / 100, 0f, 10f)
- if (exoBrightnessCont.visibility != View.VISIBLE) {
- exoBrightnessCont.visibility = View.VISIBLE
- }
- exoBrightnessCont.alpha = 1f
- }
+ override fun onScrollYClick(y: Float) {
+ if (!locked && PrefManager.getVal(PrefName.Gestures)) {
+ exoBrightness.value = clamp(exoBrightness.value + y / 100, 0f, 10f)
+ if (exoBrightnessCont.visibility != View.VISIBLE) {
+ exoBrightnessCont.visibility = View.VISIBLE
}
+ exoBrightnessCont.alpha = 1f
+ }
+ }
- override fun onSingleClick(event: MotionEvent) =
- if (isSeeking) doubleTap(false, event) else handleController()
- },
- )
+ override fun onSingleClick(event: MotionEvent) =
+ if (isSeeking) doubleTap(false, event) else handleController()
+ })
val rewindArea = playerView.findViewById(R.id.exo_rewind_area)
rewindArea.isClickable = true
rewindArea.setOnTouchListener { v, event ->
@@ -1058,33 +979,29 @@ class ExoplayerView :
true
}
- // FastForward (Right Panel)
- val fastForwardDetector =
- GestureDetector(
- this,
- object : GesturesListener() {
- override fun onLongClick(event: MotionEvent) {
- if (PrefManager.getVal(PrefName.FastForward)) fastForward()
- }
+ //FastForward (Right Panel)
+ val fastForwardDetector = GestureDetector(this, object : GesturesListener() {
+ override fun onLongClick(event: MotionEvent) {
+ if (PrefManager.getVal(PrefName.FastForward)) fastForward()
+ }
- override fun onDoubleClick(event: MotionEvent) {
- doubleTap(true, event)
- }
+ override fun onDoubleClick(event: MotionEvent) {
+ doubleTap(true, event)
+ }
- override fun onScrollYClick(y: Float) {
- if (!locked && PrefManager.getVal(PrefName.Gestures)) {
- exoVolume.value = clamp(exoVolume.value + y / 100, 0f, 10f)
- if (exoVolumeCont.visibility != View.VISIBLE) {
- exoVolumeCont.visibility = View.VISIBLE
- }
- exoVolumeCont.alpha = 1f
- }
+ override fun onScrollYClick(y: Float) {
+ if (!locked && PrefManager.getVal(PrefName.Gestures)) {
+ exoVolume.value = clamp(exoVolume.value + y / 100, 0f, 10f)
+ if (exoVolumeCont.visibility != View.VISIBLE) {
+ exoVolumeCont.visibility = View.VISIBLE
}
+ exoVolumeCont.alpha = 1f
+ }
+ }
- override fun onSingleClick(event: MotionEvent) =
- if (isSeeking) doubleTap(true, event) else handleController()
- },
- )
+ override fun onSingleClick(event: MotionEvent) =
+ if (isSeeking) doubleTap(true, event) else handleController()
+ })
val forwardArea = playerView.findViewById(R.id.exo_forward_area)
forwardArea.isClickable = true
forwardArea.setOnTouchListener { v, event ->
@@ -1095,7 +1012,7 @@ class ExoplayerView :
}
}
- // Handle Media
+ //Handle Media
if (!initialized) return startMainActivity(this)
model.setMedia(media)
title = media.userPreferredName
@@ -1109,7 +1026,8 @@ class ExoplayerView :
epChanging = !it
}
- // Anime Title
+
+ //Anime Title
animeTitle.text = media.userPreferredName
episodeArr = episodes.keys.toList()
@@ -1119,18 +1037,16 @@ class ExoplayerView :
episodes.forEach {
val episode = it.value
val cleanedTitle = MediaNameAdapter.removeEpisodeNumberCompletely(episode.title ?: "")
- episodeTitleArr.add(
- "Episode ${episode.number}${if (episode.filler) " [Filler]" else ""}${if (cleanedTitle.isNotBlank() && cleanedTitle != "null") ": $cleanedTitle" else ""}",
- )
+ episodeTitleArr.add("Episode ${episode.number}${if (episode.filler) " [Filler]" else ""}${if (cleanedTitle.isNotBlank() && cleanedTitle != "null") ": $cleanedTitle" else ""}")
}
- // Episode Change
+ //Episode Change
fun change(index: Int) {
if (isInitialized) {
changingServer = false
PrefManager.setCustomVal(
"${media.id}_${episodeArr[currentEpisodeIndex]}",
- exoPlayer.currentPosition,
+ exoPlayer.currentPosition
)
exoPlayer.seekTo(0)
val prev = episodeArr[currentEpisodeIndex]
@@ -1141,37 +1057,29 @@ class ExoplayerView :
model.epChanged.postValue(false)
model.setEpisode(episodes[media.anime!!.selectedEpisode!!]!!, "change")
model.onEpisodeClick(
- media,
- media.anime!!.selectedEpisode!!,
- this.supportFragmentManager,
+ media, media.anime!!.selectedEpisode!!, this.supportFragmentManager,
false,
- prev,
+ prev
)
}
}
- // EpisodeSelector
+ //EpisodeSelector
episodeTitle.adapter = NoPaddingArrayAdapter(this, R.layout.item_dropdown, episodeTitleArr)
episodeTitle.setSelection(currentEpisodeIndex)
- episodeTitle.onItemSelectedListener =
- object : AdapterView.OnItemSelectedListener {
- override fun onItemSelected(
- p0: AdapterView<*>?,
- p1: View?,
- position: Int,
- p3: Long,
- ) {
- if (position != currentEpisodeIndex) {
- disappeared = false
- functionstarted = false
- change(position)
- }
+ episodeTitle.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
+ override fun onItemSelected(p0: AdapterView<*>?, p1: View?, position: Int, p3: Long) {
+ if (position != currentEpisodeIndex) {
+ disappeared = false
+ functionstarted = false
+ change(position)
}
-
- override fun onNothingSelected(parent: AdapterView<*>) {}
}
- // Next Episode
+ override fun onNothingSelected(parent: AdapterView<*>) {}
+ }
+
+ //Next Episode
exoNext = playerView.findViewById(R.id.exo_next_ep)
exoNext.setOnClickListener {
if (isInitialized) {
@@ -1183,15 +1091,14 @@ class ExoplayerView :
}
}
}
- // Prev Episode
+ //Prev Episode
exoPrev = playerView.findViewById(R.id.exo_prev_ep)
exoPrev.setOnClickListener {
if (currentEpisodeIndex > 0) {
disappeared = false
change(currentEpisodeIndex - 1)
- } else {
+ } else
snackString(getString(R.string.first_episode))
- }
}
model.getEpisode().observe(this) { ep ->
@@ -1203,48 +1110,45 @@ class ExoplayerView :
currentEpisodeIndex = episodeArr.indexOf(ep.number)
episodeTitle.setSelection(currentEpisodeIndex)
if (isInitialized) releasePlayer()
- playbackPosition =
- PrefManager.getCustomVal(
- "${media.id}_${ep.number}",
- 0,
- )
+ playbackPosition = PrefManager.getCustomVal(
+ "${media.id}_${ep.number}",
+ 0
+ )
initPlayer()
preloading = false
updateProgress()
}
}
- // FullScreen
+ //FullScreen
isFullscreen = PrefManager.getCustomVal("${media.id}_fullscreenInt", isFullscreen)
- playerView.resizeMode =
- when (isFullscreen) {
+ playerView.resizeMode = when (isFullscreen) {
+ 0 -> AspectRatioFrameLayout.RESIZE_MODE_FIT
+ 1 -> AspectRatioFrameLayout.RESIZE_MODE_ZOOM
+ 2 -> AspectRatioFrameLayout.RESIZE_MODE_FILL
+ else -> AspectRatioFrameLayout.RESIZE_MODE_FIT
+ }
+
+ exoScreen.setOnClickListener {
+ if (isFullscreen < 2) isFullscreen += 1 else isFullscreen = 0
+ playerView.resizeMode = when (isFullscreen) {
0 -> AspectRatioFrameLayout.RESIZE_MODE_FIT
1 -> AspectRatioFrameLayout.RESIZE_MODE_ZOOM
2 -> AspectRatioFrameLayout.RESIZE_MODE_FILL
else -> AspectRatioFrameLayout.RESIZE_MODE_FIT
}
-
- exoScreen.setOnClickListener {
- if (isFullscreen < 2) isFullscreen += 1 else isFullscreen = 0
- playerView.resizeMode =
- when (isFullscreen) {
- 0 -> AspectRatioFrameLayout.RESIZE_MODE_FIT
- 1 -> AspectRatioFrameLayout.RESIZE_MODE_ZOOM
- 2 -> AspectRatioFrameLayout.RESIZE_MODE_FILL
- else -> AspectRatioFrameLayout.RESIZE_MODE_FIT
- }
snackString(
when (isFullscreen) {
0 -> "Original"
1 -> "Zoom"
2 -> "Stretch"
else -> "Original"
- },
+ }
)
PrefManager.setCustomVal("${media.id}_fullscreenInt", isFullscreen)
}
- // Cast
+ //Cast
if (PrefManager.getVal(PrefName.Cast)) {
playerView.findViewById(R.id.exo_cast).apply {
visibility = View.VISIBLE
@@ -1261,25 +1165,24 @@ class ExoplayerView :
}
}
- // Settings
+ //Settings
exoSettings.setOnClickListener {
PrefManager.setCustomVal(
"${media.id}_${media.anime!!.selectedEpisode}",
- exoPlayer.currentPosition,
+ exoPlayer.currentPosition
)
- val intent =
- Intent(this, PlayerSettingsActivity::class.java).apply {
- putExtra("subtitle", subtitle)
- }
+ val intent = Intent(this, PlayerSettingsActivity::class.java).apply {
+ putExtra("subtitle", subtitle)
+ }
exoPlayer.pause()
onChangeSettings.launch(intent)
}
- // Speed
+ //Speed
val speeds =
- if (PrefManager.getVal(PrefName.CursedSpeeds)) {
+ if (PrefManager.getVal(PrefName.CursedSpeeds))
arrayOf(1f, 1.25f, 1.5f, 1.75f, 2f, 2.5f, 3f, 4f, 5f, 10f, 25f, 50f)
- } else {
+ else
arrayOf(
0.25f,
0.33f,
@@ -1293,39 +1196,38 @@ class ExoplayerView :
1.5f,
1.66f,
1.75f,
- 2f,
+ 2f
)
- }
val speedsName = speeds.map { "${it}x" }.toTypedArray()
- // var curSpeed = loadData("${media.id}_speed", this) ?: settings.defaultSpeed
- var curSpeed =
- PrefManager.getCustomVal(
- "${media.id}_speed",
- PrefManager.getVal(PrefName.DefaultSpeed),
- )
+ //var curSpeed = loadData("${media.id}_speed", this) ?: settings.defaultSpeed
+ var curSpeed = PrefManager.getCustomVal(
+ "${media.id}_speed",
+ PrefManager.getVal(PrefName.DefaultSpeed)
+ )
playbackParameters = PlaybackParameters(speeds[curSpeed])
var speed: Float
+ val speedDialog =
+ AlertDialog.Builder(this, R.style.MyPopup).setTitle(getString(R.string.speed))
exoSpeed.setOnClickListener {
- customAlertDialog().apply {
- setTitle(R.string.speed)
- singleChoiceItems(speedsName, curSpeed) { i ->
+ val dialog = speedDialog.setSingleChoiceItems(speedsName, curSpeed) { dialog, i ->
+ if (isInitialized) {
PrefManager.setCustomVal("${media.id}_speed", i)
speed = speeds[i]
curSpeed = i
playbackParameters = PlaybackParameters(speed)
exoPlayer.playbackParameters = playbackParameters
+ dialog.dismiss()
hideSystemBars()
}
- setOnCancelListener { hideSystemBars() }
- show()
- }
+ }.show()
+ dialog.window?.setDimAmount(0.8f)
}
+ speedDialog.setOnCancelListener { hideSystemBars() }
if (PrefManager.getVal(PrefName.AutoPlay)) {
var touchTimer = Timer()
-
fun touched() {
interacted = true
touchTimer.apply {
@@ -1333,14 +1235,11 @@ class ExoplayerView :
purge()
}
touchTimer = Timer()
- touchTimer.schedule(
- object : TimerTask() {
- override fun run() {
- interacted = false
- }
- },
- 1000 * 60 * 60,
- )
+ touchTimer.schedule(object : TimerTask() {
+ override fun run() {
+ interacted = false
+ }
+ }, 1000 * 60 * 60)
}
playerView.findViewById(R.id.exo_touch_view).setOnTouchListener { _, _ ->
touched()
@@ -1349,73 +1248,62 @@ class ExoplayerView :
}
isFullscreen = PrefManager.getVal(PrefName.Resize)
- playerView.resizeMode =
- when (isFullscreen) {
- 0 -> AspectRatioFrameLayout.RESIZE_MODE_FIT
- 1 -> AspectRatioFrameLayout.RESIZE_MODE_ZOOM
- 2 -> AspectRatioFrameLayout.RESIZE_MODE_FILL
- else -> AspectRatioFrameLayout.RESIZE_MODE_FIT
- }
+ playerView.resizeMode = when (isFullscreen) {
+ 0 -> AspectRatioFrameLayout.RESIZE_MODE_FIT
+ 1 -> AspectRatioFrameLayout.RESIZE_MODE_ZOOM
+ 2 -> AspectRatioFrameLayout.RESIZE_MODE_FILL
+ else -> AspectRatioFrameLayout.RESIZE_MODE_FIT
+ }
preloading = false
val incognito: Boolean = PrefManager.getVal(PrefName.Incognito)
val showProgressDialog =
- if (PrefManager.getVal(PrefName.AskIndividualPlayer)) {
- PrefManager.getCustomVal(
- "${media.id}_ProgressDialog",
- true,
- )
- } else {
- false
- }
- if (!incognito &&
- showProgressDialog &&
- Anilist.userid != null &&
- if (media.isAdult) {
- PrefManager.getVal(
- PrefName.UpdateForHPlayer,
- )
- } else {
+ if (PrefManager.getVal(PrefName.AskIndividualPlayer)) PrefManager.getCustomVal(
+ "${media.id}_ProgressDialog",
true
- }
+ ) else false
+ if (!incognito && showProgressDialog && Anilist.userid != null && if (media.isAdult) PrefManager.getVal(
+ PrefName.UpdateForHPlayer
+ ) else true
) {
- customAlertDialog().apply {
- setTitle(getString(R.string.auto_update, media.userPreferredName))
- setCancelable(false)
- setPosButton(R.string.yes) {
- PrefManager.setCustomVal(
- "${media.id}_ProgressDialog",
- false,
- )
- PrefManager.setCustomVal(
- "${media.id}_save_progress",
- true,
- )
- model.setEpisode(episodes[media.anime!!.selectedEpisode!!]!!, "invoke")
+ AlertDialog.Builder(this, R.style.MyPopup)
+ .setTitle(getString(R.string.auto_update, media.userPreferredName))
+ .apply {
+ setOnCancelListener { hideSystemBars() }
+ setCancelable(false)
+ setPositiveButton(getString(R.string.yes)) { dialog, _ ->
+ PrefManager.setCustomVal(
+ "${media.id}_ProgressDialog",
+ false
+ )
+ PrefManager.setCustomVal(
+ "${media.id}_save_progress",
+ true
+ )
+ dialog.dismiss()
+ model.setEpisode(episodes[media.anime!!.selectedEpisode!!]!!, "invoke")
+ }
+ setNegativeButton(getString(R.string.no)) { dialog, _ ->
+ PrefManager.setCustomVal(
+ "${media.id}_ProgressDialog",
+ false
+ )
+ PrefManager.setCustomVal(
+ "${media.id}_save_progress",
+ false
+ )
+ toast(getString(R.string.reset_auto_update))
+ dialog.dismiss()
+ model.setEpisode(episodes[media.anime!!.selectedEpisode!!]!!, "invoke")
+ }
+ show()
}
- setNegButton(R.string.no) {
- PrefManager.setCustomVal(
- "${media.id}_ProgressDialog",
- false,
- )
- PrefManager.setCustomVal(
- "${media.id}_save_progress",
- false,
- )
- toast(getString(R.string.reset_auto_update))
- model.setEpisode(episodes[media.anime!!.selectedEpisode!!]!!, "invoke")
- }
- setOnCancelListener { hideSystemBars() }
- show()
- }
- } else {
- model.setEpisode(episodes[media.anime!!.selectedEpisode!!]!!, "invoke")
- }
+ } else model.setEpisode(episodes[media.anime!!.selectedEpisode!!]!!, "invoke")
- // Start the recursive Fun
- if (PrefManager.getVal(PrefName.TimeStampsEnabled)) {
+ //Start the recursive Fun
+ if (PrefManager.getVal(PrefName.TimeStampsEnabled))
updateTimeStamp()
- }
+
}
private fun discordRPC() {
@@ -1427,68 +1315,60 @@ class ExoplayerView :
if ((isOnline(context) && !offline) && Discord.token != null && !incognito && rpcenabled) {
lifecycleScope.launch {
val discordMode = PrefManager.getCustomVal("discord_mode", "dantotsu")
- val buttons =
- when (discordMode) {
- "nothing" ->
- mutableListOf(
- RPC.Link(getString(R.string.view_anime), media.shareLink ?: ""),
- )
+ val buttons = when (discordMode) {
+ "nothing" -> mutableListOf(
+ RPC.Link(getString(R.string.view_anime), media.shareLink ?: ""),
+ )
- "dantotsu" ->
- mutableListOf(
- RPC.Link(getString(R.string.view_anime), media.shareLink ?: ""),
- RPC.Link("Watch on Dantotsu", getString(R.string.dantotsu)),
- )
+ "dantotsu" -> mutableListOf(
+ RPC.Link(getString(R.string.view_anime), media.shareLink ?: ""),
+ RPC.Link("Watch on Dantotsu", getString(R.string.dantotsu))
+ )
- "anilist" -> {
- val userId = PrefManager.getVal(PrefName.AnilistUserId)
- val anilistLink = "https://anilist.co/user/$userId/"
- mutableListOf(
- RPC.Link(getString(R.string.view_anime), media.shareLink ?: ""),
- RPC.Link("View My AniList", anilistLink),
- )
- }
-
- else -> mutableListOf()
+ "anilist" -> {
+ val userId = PrefManager.getVal(PrefName.AnilistUserId)
+ val anilistLink = "https://anilist.co/user/$userId/"
+ mutableListOf(
+ RPC.Link(getString(R.string.view_anime), media.shareLink ?: ""),
+ RPC.Link("View My AniList", anilistLink)
+ )
}
+
+ else -> mutableListOf()
+ }
val startTimestamp = Calendar.getInstance()
val durationInSeconds =
if (exoPlayer.duration != C.TIME_UNSET) (exoPlayer.duration / 1000).toInt() else 1440
- val endTimestamp =
- Calendar.getInstance().apply {
- timeInMillis = startTimestamp.timeInMillis
- add(Calendar.SECOND, durationInSeconds)
- }
- val presence =
- RPC.createPresence(
- RPC.Companion.RPCData(
- applicationId = Discord.application_Id,
- type = RPC.Type.WATCHING,
- activityName = media.userPreferredName,
- details =
- ep.title?.takeIf { it.isNotEmpty() } ?: getString(
- R.string.episode_num,
- ep.number,
- ),
- startTimestamp = startTimestamp.timeInMillis,
- stopTimestamp = endTimestamp.timeInMillis,
- state = "Episode : ${ep.number}/${media.anime?.totalEpisodes ?: "??"}",
- largeImage =
- media.cover?.let {
- RPC.Link(
- media.userPreferredName,
- it,
- )
- },
- smallImage = RPC.Link("Dantotsu", Discord.small_Image),
- buttons = buttons,
+ val endTimestamp = Calendar.getInstance().apply {
+ timeInMillis = startTimestamp.timeInMillis
+ add(Calendar.SECOND, durationInSeconds)
+ }
+ val presence = RPC.createPresence(
+ RPC.Companion.RPCData(
+ applicationId = Discord.application_Id,
+ type = RPC.Type.WATCHING,
+ activityName = media.userPreferredName,
+ details = ep.title?.takeIf { it.isNotEmpty() } ?: getString(
+ R.string.episode_num,
+ ep.number
),
+ startTimestamp = startTimestamp.timeInMillis,
+ stopTimestamp = endTimestamp.timeInMillis,
+ state = "Episode : ${ep.number}/${media.anime?.totalEpisodes ?: "??"}",
+ largeImage = media.cover?.let {
+ RPC.Link(
+ media.userPreferredName,
+ it
+ )
+ },
+ smallImage = RPC.Link("Dantotsu", Discord.small_Image),
+ buttons = buttons
)
- val intent =
- Intent(context, DiscordService::class.java).apply {
- putExtra("presence", presence)
- }
+ )
+ val intent = Intent(context, DiscordService::class.java).apply {
+ putExtra("presence", presence)
+ }
DiscordServiceRunningSingleton.running = true
startService(intent)
}
@@ -1500,18 +1380,15 @@ class ExoplayerView :
PrefManager.setCustomVal(
"${media.id}_current_ep",
- media.anime!!.selectedEpisode!!,
+ media.anime!!.selectedEpisode!!
)
@Suppress("UNCHECKED_CAST")
- val list =
- (
- PrefManager.getNullableCustomVal(
- "continueAnimeList",
- listOf(),
- List::class.java,
- ) as List
- ).toMutableList()
+ val list = (PrefManager.getNullableCustomVal(
+ "continueAnimeList",
+ listOf(),
+ List::class.java
+ ) as List).toMutableList()
if (list.contains(media.id)) list.remove(media.id)
list.add(media.id)
PrefManager.setCustomVal("continueAnimeList", list)
@@ -1523,71 +1400,62 @@ class ExoplayerView :
val ext = episode.extractors?.find { it.server.name == episode.selectedExtractor } ?: return
extractor = ext
video = ext.videos.getOrNull(episode.selectedVideo) ?: return
- val subLanguages =
- arrayOf(
- "Albanian",
- "Arabic",
- "Bosnian",
- "Bulgarian",
- "Chinese",
- "Croatian",
- "Czech",
- "Danish",
- "Dutch",
- "English",
- "Estonian",
- "Finnish",
- "French",
- "Georgian",
- "German",
- "Greek",
- "Hebrew",
- "Hindi",
- "Indonesian",
- "Irish",
- "Italian",
- "Japanese",
- "Korean",
- "Lithuanian",
- "Luxembourgish",
- "Macedonian",
- "Mongolian",
- "Norwegian",
- "Polish",
- "Portuguese",
- "Punjabi",
- "Romanian",
- "Russian",
- "Serbian",
- "Slovak",
- "Slovenian",
- "Spanish",
- "Turkish",
- "Ukrainian",
- "Urdu",
- "Vietnamese",
- )
+ val subLanguages = arrayOf(
+ "Albanian",
+ "Arabic",
+ "Bosnian",
+ "Bulgarian",
+ "Chinese",
+ "Croatian",
+ "Czech",
+ "Danish",
+ "Dutch",
+ "English",
+ "Estonian",
+ "Finnish",
+ "French",
+ "Georgian",
+ "German",
+ "Greek",
+ "Hebrew",
+ "Hindi",
+ "Indonesian",
+ "Irish",
+ "Italian",
+ "Japanese",
+ "Korean",
+ "Lithuanian",
+ "Luxembourgish",
+ "Macedonian",
+ "Mongolian",
+ "Norwegian",
+ "Polish",
+ "Portuguese",
+ "Punjabi",
+ "Romanian",
+ "Russian",
+ "Serbian",
+ "Slovak",
+ "Slovenian",
+ "Spanish",
+ "Turkish",
+ "Ukrainian",
+ "Urdu",
+ "Vietnamese",
+ )
val lang = subLanguages[PrefManager.getVal(PrefName.SubLanguage)]
subtitle = intent.getSerialized("subtitle")
- ?: when (
- val subLang: String? =
- PrefManager.getNullableCustomVal(
- "subLang_${media.id}",
- null,
- String::class.java
- )
- ) {
+ ?: when (val subLang: String? =
+ PrefManager.getNullableCustomVal("subLang_${media.id}", null, String::class.java)) {
null -> {
when (episode.selectedSubtitle) {
null -> null
- -1 ->
- ext.subtitles.find {
- it.language.contains(lang, ignoreCase = true) ||
- it.language.contains(
- getLanguageCode(lang),
- ignoreCase = true
- )
- }
+ -1 -> ext.subtitles.find {
+ it.language.contains(
+ lang,
+ ignoreCase = true
+ ) || it.language.contains(getLanguageCode(lang), ignoreCase = true)
+ }
else -> ext.subtitles.getOrNull(episode.selectedSubtitle!!)
}
@@ -1597,7 +1465,7 @@ class ExoplayerView :
else -> ext.subtitles.find { it.language == subLang }
}
- // Subtitles
+ //Subtitles
hasExtSubtitles = ext.subtitles.isNotEmpty()
if (hasExtSubtitles) {
exoSubtitle.isVisible = hasExtSubtitles
@@ -1609,43 +1477,43 @@ class ExoplayerView :
emptyList().toMutableList()
ext.subtitles.forEach { subtitle ->
val subtitleUrl = if (!hasExtSubtitles) video!!.file.url else subtitle.file.url
- // var localFile: String? = null
+ //var localFile: String? = null
if (subtitle.type == SubtitleType.UNKNOWN) {
runBlocking {
val type = SubtitleDownloader.loadSubtitleType(subtitleUrl)
val fileUri = Uri.parse(subtitleUrl)
- sub +=
- MediaItem.SubtitleConfiguration
- .Builder(fileUri)
- .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
- .setMimeType(
- when (type) {
- SubtitleType.VTT -> MimeTypes.TEXT_SSA
- SubtitleType.ASS -> MimeTypes.TEXT_SSA
- SubtitleType.SRT -> MimeTypes.TEXT_SSA
- else -> MimeTypes.TEXT_SSA
- },
- ).setId("69")
- .setLanguage(subtitle.language)
- .build()
+ sub += MediaItem.SubtitleConfiguration
+ .Builder(fileUri)
+ .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
+ .setMimeType(
+ when (type) {
+ SubtitleType.VTT -> MimeTypes.TEXT_SSA
+ SubtitleType.ASS -> MimeTypes.TEXT_SSA
+ SubtitleType.SRT -> MimeTypes.TEXT_SSA
+ else -> MimeTypes.TEXT_SSA
+ }
+ )
+ .setId("69")
+ .setLanguage(subtitle.language)
+ .build()
}
println("sub: $sub")
} else {
val subUri = Uri.parse(subtitleUrl)
- sub +=
- MediaItem.SubtitleConfiguration
- .Builder(subUri)
- .setSelectionFlags(C.SELECTION_FLAG_FORCED)
- .setMimeType(
- when (subtitle.type) {
- SubtitleType.VTT -> MimeTypes.TEXT_VTT
- SubtitleType.ASS -> MimeTypes.TEXT_SSA
- SubtitleType.SRT -> MimeTypes.APPLICATION_SUBRIP
- else -> MimeTypes.TEXT_UNKNOWN
- },
- ).setId("69")
- .setLanguage(subtitle.language)
- .build()
+ sub += MediaItem.SubtitleConfiguration
+ .Builder(subUri)
+ .setSelectionFlags(C.SELECTION_FLAG_FORCED)
+ .setMimeType(
+ when (subtitle.type) {
+ SubtitleType.VTT -> MimeTypes.TEXT_VTT
+ SubtitleType.ASS -> MimeTypes.TEXT_SSA
+ SubtitleType.SRT -> MimeTypes.APPLICATION_SUBRIP
+ else -> MimeTypes.TEXT_UNKNOWN
+ }
+ )
+ .setId("69")
+ .setLanguage(subtitle.language)
+ .build()
}
}
@@ -1653,140 +1521,98 @@ class ExoplayerView :
ext.onVideoPlayed(video)
}
- val httpClient =
- okHttpClient
- .newBuilder()
- .apply {
- ignoreAllSSLErrors()
- followRedirects(true)
- followSslRedirects(true)
- }.build()
- val dataSourceFactory =
- DataSource.Factory {
- val dataSource: HttpDataSource =
- OkHttpDataSource.Factory(httpClient).createDataSource()
- defaultHeaders.forEach {
- dataSource.setRequestProperty(it.key, it.value)
- }
- video?.file?.headers?.forEach {
- dataSource.setRequestProperty(it.key, it.value)
- }
- dataSource
+ val httpClient = okHttpClient.newBuilder().apply {
+ ignoreAllSSLErrors()
+ followRedirects(true)
+ followSslRedirects(true)
+ }.build()
+ val dataSourceFactory = DataSource.Factory {
+ val dataSource: HttpDataSource = OkHttpDataSource.Factory(httpClient).createDataSource()
+ defaultHeaders.forEach {
+ dataSource.setRequestProperty(it.key, it.value)
}
+ video?.file?.headers?.forEach {
+ dataSource.setRequestProperty(it.key, it.value)
+ }
+ dataSource
+ }
val dafuckDataSourceFactory = DefaultDataSource.Factory(this)
- cacheFactory =
- CacheDataSource.Factory().apply {
- setCache(VideoCache.getInstance(this@ExoplayerView))
- if (ext.server.offline) {
- setUpstreamDataSourceFactory(dafuckDataSourceFactory)
- } else {
- setUpstreamDataSourceFactory(dataSourceFactory)
- }
- setCacheWriteDataSinkFactory(null)
- }
-
- val mimeType =
- when (video?.format) {
- VideoType.M3U8 -> MimeTypes.APPLICATION_M3U8
- VideoType.DASH -> MimeTypes.APPLICATION_MPD
- else -> MimeTypes.APPLICATION_MP4
- }
-
- val downloadedMediaItem =
+ cacheFactory = CacheDataSource.Factory().apply {
+ setCache(VideoCache.getInstance(this@ExoplayerView))
if (ext.server.offline) {
- val titleName =
- ext.server.name
- .split("/")
- .first()
- val episodeName =
- ext.server.name
- .split("/")
- .last()
- downloadId = PrefManager
- .getAnimeDownloadPreferences()
- .getString("$titleName - $episodeName", null)
- ?: PrefManager
- .getAnimeDownloadPreferences()
- .getString(ext.server.name, null)
- val exoItem =
- if (downloadId != null) {
- Helper
- .downloadManager(this)
- .downloadIndex
- .getDownload(downloadId!!)
- ?.request
- ?.toMediaItem()
- } else {
- null
- }
- if (exoItem != null) {
- exoItem
- } else {
- val directory =
- getSubDirectory(this, MediaType.ANIME, false, titleName, episodeName)
- if (directory != null) {
- val files = directory.listFiles()
- println(files)
- val docFile =
- directory.listFiles().firstOrNull {
- it.name?.endsWith(".mp4") == true ||
- it.name?.endsWith(".mkv") == true ||
- it.name?.endsWith(
- ".${
- Injekt
- .get()
- .extension
- ?.extension
- ?.getFileExtension()
- ?.first ?: "ts"
- }",
- ) ==
- true
- }
- if (docFile != null) {
- val uri = docFile.uri
- val downloadedMimeType =
- when (docFile.extension) {
- "mp4" -> MimeTypes.APPLICATION_MP4
- "mkv" -> MimeTypes.APPLICATION_MATROSKA
- else -> MimeTypes.APPLICATION_MP4
- }
- MediaItem
- .Builder()
- .setUri(uri)
- .setMimeType(downloadedMimeType)
- .build()
- } else {
- snackString("File not found")
- null
- }
- } else {
- snackString("Directory not found")
- null
- }
- }
+ setUpstreamDataSourceFactory(dafuckDataSourceFactory)
} else {
- null
+ setUpstreamDataSourceFactory(dataSourceFactory)
}
+ setCacheWriteDataSinkFactory(null)
+ }
- mediaItem =
- if (downloadedMediaItem == null) {
- val builder = MediaItem.Builder().setUri(video!!.file.url).setMimeType(mimeType)
- Logger.log("url: ${video!!.file.url}")
- Logger.log("mimeType: $mimeType")
- builder.setSubtitleConfigurations(sub)
- builder.build()
+ val mimeType = when (video?.format) {
+ VideoType.M3U8 -> MimeTypes.APPLICATION_M3U8
+ VideoType.DASH -> MimeTypes.APPLICATION_MPD
+ else -> MimeTypes.APPLICATION_MP4
+ }
+
+ val downloadedMediaItem = if (ext.server.offline) {
+ val titleName = ext.server.name.split("/").first()
+ val episodeName = ext.server.name.split("/").last()
+ downloadId = PrefManager.getAnimeDownloadPreferences()
+ .getString("$titleName - $episodeName", null)
+ ?: PrefManager.getAnimeDownloadPreferences()
+ .getString(ext.server.name, null)
+ val exoItem = if (downloadId != null) {
+ Helper.downloadManager(this)
+ .downloadIndex.getDownload(downloadId!!)?.request?.toMediaItem()
+ } else null
+ if (exoItem != null) {
+ exoItem
} else {
- if (sub.isNotEmpty()) {
- val addedSubsDownloadedMediaItem = downloadedMediaItem.buildUpon()
- val addLanguage = sub[0].buildUpon().setLanguage("en").build()
- addedSubsDownloadedMediaItem.setSubtitleConfigurations(listOf(addLanguage))
- episode.selectedSubtitle = 0
- addedSubsDownloadedMediaItem.build()
+
+ val directory =
+ getSubDirectory(this, MediaType.ANIME, false, titleName, episodeName)
+ if (directory != null) {
+ val files = directory.listFiles()
+ println(files)
+ val docFile = directory.listFiles().firstOrNull {
+ it.name?.endsWith(".mp4") == true || it.name?.endsWith(".mkv") == true
+ || it.name?.endsWith(".${Injekt.get().extension?.extension?.getFileExtension()?.first ?: "ts"}") == true
+ }
+ if (docFile != null) {
+ val uri = docFile.uri
+ val downloadedMimeType = when (docFile.extension) {
+ "mp4" -> MimeTypes.APPLICATION_MP4
+ "mkv" -> MimeTypes.APPLICATION_MATROSKA
+ else -> MimeTypes.APPLICATION_MP4
+ }
+ MediaItem.Builder().setUri(uri).setMimeType(downloadedMimeType).build()
+ } else {
+ snackString("File not found")
+ null
+ }
} else {
- downloadedMediaItem
+ snackString("Directory not found")
+ null
}
}
+ } else null
+
+ mediaItem = if (downloadedMediaItem == null) {
+ val builder = MediaItem.Builder().setUri(video!!.file.url).setMimeType(mimeType)
+ Logger.log("url: ${video!!.file.url}")
+ Logger.log("mimeType: $mimeType")
+ builder.setSubtitleConfigurations(sub)
+ builder.build()
+ } else {
+ if (sub.isNotEmpty()) {
+ val addedSubsDownloadedMediaItem = downloadedMediaItem.buildUpon()
+ val addLanguage = sub[0].buildUpon().setLanguage("en").build()
+ addedSubsDownloadedMediaItem.setSubtitleConfigurations(listOf(addLanguage))
+ episode.selectedSubtitle = 0
+ addedSubsDownloadedMediaItem.build()
+ } else {
+ downloadedMediaItem
+ }
+ }
val audioMediaItem = mutableListOf()
audioLanguages.clear()
@@ -1795,203 +1621,179 @@ class ExoplayerView :
if (code == "all") code = "un"
audioLanguages.add(Pair(it.lang, code))
audioMediaItem.add(
- MediaItem
- .Builder()
+ MediaItem.Builder()
.setUri(it.url)
.setMimeType(MimeTypes.AUDIO_UNKNOWN)
.setTag(code)
- .build(),
+ .build()
)
}
- val audioSources =
- audioMediaItem
- .map { mediaItem ->
- if (mediaItem.localConfiguration
- ?.uri
- .toString()
- .contains(".m3u8")
- ) {
- HlsMediaSource.Factory(cacheFactory).createMediaSource(mediaItem)
- } else {
- DefaultMediaSourceFactory(cacheFactory).createMediaSource(mediaItem)
- }
- }.toTypedArray()
- val videoMediaSource =
- DefaultMediaSourceFactory(cacheFactory)
- .createMediaSource(mediaItem)
+ val audioSources = audioMediaItem.map { mediaItem ->
+ if (mediaItem.localConfiguration?.uri.toString().contains(".m3u8")) {
+ HlsMediaSource.Factory(cacheFactory).createMediaSource(mediaItem)
+ } else {
+ DefaultMediaSourceFactory(cacheFactory).createMediaSource(mediaItem)
+ }
+ }.toTypedArray()
+ val videoMediaSource = DefaultMediaSourceFactory(cacheFactory)
+ .createMediaSource(mediaItem)
mediaSource = MergingMediaSource(videoMediaSource, *audioSources)
- // Source
+
+ //Source
exoSource.setOnClickListener {
sourceClick()
}
- // Quality Track
+ //Quality Track
trackSelector = DefaultTrackSelector(this)
- val parameters =
- trackSelector
- .buildUponParameters()
- .setAllowVideoMixedMimeTypeAdaptiveness(true)
- .setAllowVideoNonSeamlessAdaptiveness(true)
- .setSelectUndeterminedTextLanguage(true)
- .setAllowAudioMixedMimeTypeAdaptiveness(true)
- .setAllowMultipleAdaptiveSelections(true)
- .setPreferredTextLanguage(subtitle?.language ?: Locale.getDefault().language)
- .setPreferredTextRoleFlags(C.ROLE_FLAG_SUBTITLE)
- .setRendererDisabled(TRACK_TYPE_VIDEO, false)
- .setRendererDisabled(TRACK_TYPE_AUDIO, false)
- .setRendererDisabled(TRACK_TYPE_TEXT, false)
- .setMaxVideoSize(1, 1)
+ val parameters = trackSelector.buildUponParameters()
+ .setAllowVideoMixedMimeTypeAdaptiveness(true)
+ .setAllowVideoNonSeamlessAdaptiveness(true)
+ .setSelectUndeterminedTextLanguage(true)
+ .setAllowAudioMixedMimeTypeAdaptiveness(true)
+ .setAllowMultipleAdaptiveSelections(true)
+ .setPreferredTextLanguage(subtitle?.language ?: Locale.getDefault().language)
+ .setPreferredTextRoleFlags(C.ROLE_FLAG_SUBTITLE)
+ .setRendererDisabled(TRACK_TYPE_VIDEO, false)
+ .setRendererDisabled(TRACK_TYPE_AUDIO, false)
+ .setRendererDisabled(TRACK_TYPE_TEXT, false)
+ .setMaxVideoSize(1, 1)
// .setOverrideForType(TrackSelectionOverride(trackSelector, TRACK_TYPE_VIDEO))
- if (PrefManager.getVal(PrefName.SettingsPreferDub)) {
+ if (PrefManager.getVal(PrefName.SettingsPreferDub))
parameters.setPreferredAudioLanguage(Locale.getDefault().language)
- }
trackSelector.setParameters(parameters)
if (playbackPosition != 0L && !changingServer && !PrefManager.getVal(PrefName.AlwaysContinue)) {
- val time =
- String.format(
- "%02d:%02d:%02d",
- TimeUnit.MILLISECONDS.toHours(playbackPosition),
- TimeUnit.MILLISECONDS.toMinutes(playbackPosition) -
- TimeUnit.HOURS.toMinutes(
- TimeUnit.MILLISECONDS.toHours(
- playbackPosition,
- ),
- ),
- TimeUnit.MILLISECONDS.toSeconds(playbackPosition) -
- TimeUnit.MINUTES.toSeconds(
- TimeUnit.MILLISECONDS.toMinutes(
- playbackPosition,
- ),
- ),
+ val time = String.format(
+ "%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(playbackPosition),
+ TimeUnit.MILLISECONDS.toMinutes(playbackPosition) - TimeUnit.HOURS.toMinutes(
+ TimeUnit.MILLISECONDS.toHours(
+ playbackPosition
+ )
+ ),
+ TimeUnit.MILLISECONDS.toSeconds(playbackPosition) - TimeUnit.MINUTES.toSeconds(
+ TimeUnit.MILLISECONDS.toMinutes(
+ playbackPosition
+ )
)
- customAlertDialog().apply {
- setTitle(getString(R.string.continue_from, time))
- setCancelable(false)
- setPosButton(getString(R.string.yes)) {
- buildExoplayer()
- }
- setNegButton(getString(R.string.no)) {
- playbackPosition = 0L
- buildExoplayer()
- }
- show()
- }
- } else {
- buildExoplayer()
- }
+ )
+ val dialog = AlertDialog.Builder(this, R.style.MyPopup)
+ .setTitle(getString(R.string.continue_from, time)).apply {
+ setCancelable(false)
+ setPositiveButton(getString(R.string.yes)) { d, _ ->
+ buildExoplayer()
+ d.dismiss()
+ }
+ setNegativeButton(getString(R.string.no)) { d, _ ->
+ playbackPosition = 0L
+ buildExoplayer()
+ d.dismiss()
+ }
+ }.show()
+ dialog.window?.setDimAmount(0.8f)
+ } else buildExoplayer()
}
private fun buildExoplayer() {
- // Player
- val loadControl =
- DefaultLoadControl
- .Builder()
- .setBackBuffer(1000 * 60 * 2, true)
- .setBufferDurationsMs(
- DEFAULT_MIN_BUFFER_MS,
- DEFAULT_MAX_BUFFER_MS,
- BUFFER_FOR_PLAYBACK_MS,
- BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS,
- ).build()
+ //Player
+ val loadControl = DefaultLoadControl.Builder()
+ .setBackBuffer(1000 * 60 * 2, true)
+ .setBufferDurationsMs(
+ DEFAULT_MIN_BUFFER_MS,
+ DEFAULT_MAX_BUFFER_MS,
+ BUFFER_FOR_PLAYBACK_MS,
+ BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS
+ )
+ .build()
hideSystemBars()
val useExtensionDecoder = PrefManager.getVal(PrefName.UseAdditionalCodec)
- val decoder =
- if (useExtensionDecoder) {
- DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER
- } else {
- DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF
- }
- val renderersFactory =
- NextRenderersFactory(this)
- .setEnableDecoderFallback(true)
- .setExtensionRendererMode(decoder)
+ val decoder = if (useExtensionDecoder) {
+ DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER
+ } else {
+ DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF
+ }
+ val renderersFactory = NextRenderersFactory(this)
+ .setEnableDecoderFallback(true)
+ .setExtensionRendererMode(decoder)
- exoPlayer =
- ExoPlayer
- .Builder(this, renderersFactory)
- .setMediaSourceFactory(DefaultMediaSourceFactory(cacheFactory))
- .setTrackSelector(trackSelector)
- .setLoadControl(loadControl)
- .build()
- .apply {
- playWhenReady = true
- this.playbackParameters = this@ExoplayerView.playbackParameters
- setMediaSource(mediaSource)
- prepare()
- PrefManager
- .getCustomVal(
- "${media.id}_${media.anime!!.selectedEpisode}_max",
- Long.MAX_VALUE,
- ).takeIf { it != Long.MAX_VALUE }
- ?.let { if (it <= playbackPosition) playbackPosition = max(0, it - 5) }
- seekTo(playbackPosition)
- }
+ exoPlayer = ExoPlayer.Builder(this, renderersFactory)
+ .setMediaSourceFactory(DefaultMediaSourceFactory(cacheFactory))
+ .setTrackSelector(trackSelector)
+ .setLoadControl(loadControl)
+ .build().apply {
+ playWhenReady = true
+ this.playbackParameters = this@ExoplayerView.playbackParameters
+ setMediaSource(mediaSource)
+ prepare()
+ PrefManager.getCustomVal(
+ "${media.id}_${media.anime!!.selectedEpisode}_max",
+ Long.MAX_VALUE
+ )
+ .takeIf { it != Long.MAX_VALUE }
+ ?.let { if (it <= playbackPosition) playbackPosition = max(0, it - 5) }
+ seekTo(playbackPosition)
+ }
playerView.player = exoPlayer
- exoPlayer.addListener(
- object : Player.Listener {
- var activeSubtitles = ArrayDeque(3)
- var lastSubtitle: String? = null
- var lastPosition: Long = 0
+ exoPlayer.addListener(object : Player.Listener {
+ var activeSubtitles = ArrayDeque(3)
+ var lastSubtitle: String? = null
+ var lastPosition: Long = 0
- override fun onCues(cueGroup: CueGroup) {
- if (PrefManager.getVal(PrefName.TextviewSubtitles)) {
- exoSubtitleView.visibility = View.GONE
- customSubtitleView.visibility = View.VISIBLE
- val newCues = cueGroup.cues.map { it.text.toString() }
+ override fun onCues(cueGroup: CueGroup) {
+ if (PrefManager.getVal(PrefName.TextviewSubtitles)) {
+ exoSubtitleView.visibility = View.GONE
+ customSubtitleView.visibility = View.VISIBLE
+ val newCues = cueGroup.cues.map { it.text.toString() }
- if (newCues.isEmpty()) {
- customSubtitleView.text = ""
- activeSubtitles.clear()
- lastSubtitle = null
- lastPosition = 0
- return
- }
-
- val currentPosition = exoPlayer.currentPosition
-
- if ((lastSubtitle?.length
- ?: 0) < 20 || (lastPosition != 0L && currentPosition - lastPosition > 1500)
- ) {
- activeSubtitles.clear()
- }
-
- for (newCue in newCues) {
- if (newCue !in activeSubtitles) {
- if (activeSubtitles.size >= 2) {
- activeSubtitles.removeLast()
- }
- activeSubtitles.addFirst(newCue)
- lastSubtitle = newCue
- lastPosition = currentPosition
- }
- }
-
- customSubtitleView.text = activeSubtitles.joinToString("\n")
- } else {
+ if (newCues.isEmpty()) {
customSubtitleView.text = ""
- customSubtitleView.visibility = View.GONE
- exoSubtitleView.visibility = View.VISIBLE
+ activeSubtitles.clear()
+ lastSubtitle = null
+ lastPosition = 0
+ return
}
+
+ val currentPosition = exoPlayer.currentPosition
+
+ if ((lastSubtitle?.length
+ ?: 0) < 20 || (lastPosition != 0L && currentPosition - lastPosition > 1500)
+ ) {
+ activeSubtitles.clear()
+ }
+
+ for (newCue in newCues) {
+ if (newCue !in activeSubtitles) {
+ if (activeSubtitles.size >= 2) {
+ activeSubtitles.removeLast()
+ }
+ activeSubtitles.addFirst(newCue)
+ lastSubtitle = newCue
+ lastPosition = currentPosition
+ }
+ }
+
+ customSubtitleView.text = activeSubtitles.joinToString("\n")
+ } else {
+ customSubtitleView.text = ""
+ customSubtitleView.visibility = View.GONE
+ exoSubtitleView.visibility = View.VISIBLE
}
- },
- )
+ }
+ })
applySubtitleStyles(customSubtitleView)
setupSubFormatting(playerView)
try {
val rightNow = Calendar.getInstance()
- mediaSession =
- MediaSession
- .Builder(this, exoPlayer)
- .setId(rightNow.timeInMillis.toString())
- .build()
+ mediaSession = MediaSession.Builder(this, exoPlayer)
+ .setId(rightNow.timeInMillis.toString())
+ .build()
} catch (e: Exception) {
toast(e.toString())
}
@@ -2005,11 +1807,10 @@ class ExoplayerView :
}
val isDisabled = (subtitle == null && hasExtSubtitles)
- exoPlayer.trackSelectionParameters =
- exoPlayer.trackSelectionParameters
- .buildUpon()
- .setTrackTypeDisabled(TRACK_TYPE_TEXT, isDisabled)
- .build()
+ exoPlayer.trackSelectionParameters = exoPlayer.trackSelectionParameters
+ .buildUpon()
+ .setTrackTypeDisabled(TRACK_TYPE_TEXT, isDisabled)
+ .build()
}
private fun releasePlayer() {
@@ -2025,6 +1826,7 @@ class ExoplayerView :
DiscordServiceRunningSingleton.running = false
stopService(stopIntent)
}
+
}
override fun onSaveInstanceState(outState: Bundle) {
@@ -2042,22 +1844,18 @@ class ExoplayerView :
media.selected!!.server = null
PrefManager.setCustomVal(
- "${media.id}_${media.anime!!.selectedEpisode}",
- exoPlayer.currentPosition,
+ "${media.id}_${media.anime!!.selectedEpisode}", exoPlayer.currentPosition
)
model.saveSelected(media.id, media.selected!!)
model.onEpisodeClick(
- media,
- episode.number,
- this.supportFragmentManager,
- launch = false,
+ media, episode.number, this.supportFragmentManager,
+ launch = false
)
}
private fun subClick() {
PrefManager.setCustomVal(
- "${media.id}_${media.anime!!.selectedEpisode}",
- exoPlayer.currentPosition,
+ "${media.id}_${media.anime!!.selectedEpisode}", exoPlayer.currentPosition
)
model.saveSelected(media.id, media.selected!!)
SubtitleDialogFragment().show(supportFragmentManager, "dialog")
@@ -2073,7 +1871,7 @@ class ExoplayerView :
if (exoPlayer.currentPosition > 5000) {
PrefManager.setCustomVal(
"${media.id}_${media.anime!!.selectedEpisode}",
- exoPlayer.currentPosition,
+ exoPlayer.currentPosition
)
}
}
@@ -2097,7 +1895,6 @@ class ExoplayerView :
}
private var wasPlaying = false
-
override fun onWindowFocusChanged(hasFocus: Boolean) {
if (PrefManager.getVal(PrefName.FocusPause) && !epChanging) {
if (isInitialized && !hasFocus) wasPlaying = exoPlayer.isPlaying
@@ -2115,12 +1912,9 @@ class ExoplayerView :
isPlayerPlaying = isPlaying
playerView.keepScreenOn = isPlaying
(exoPlay.drawable as Animatable?)?.start()
- if (!this.isDestroyed) {
- Glide
- .with(this)
- .load(if (isPlaying) R.drawable.anim_play_to_pause else R.drawable.anim_pause_to_play)
- .into(exoPlay)
- }
+ if (!this.isDestroyed) Glide.with(this)
+ .load(if (isPlaying) R.drawable.anim_play_to_pause else R.drawable.anim_pause_to_play)
+ .into(exoPlay)
}
}
@@ -2128,7 +1922,7 @@ class ExoplayerView :
super.onRenderedFirstFrame()
PrefManager.setCustomVal(
"${media.id}_${media.anime!!.selectedEpisode}_max",
- exoPlayer.duration,
+ exoPlayer.duration
)
val height = (exoPlayer.videoFormat ?: return).height
val width = (exoPlayer.videoFormat ?: return).width
@@ -2137,11 +1931,10 @@ class ExoplayerView :
videoInfo.text = getString(R.string.video_quality, height)
- if (exoPlayer.duration < playbackPosition) {
+ if (exoPlayer.duration < playbackPosition)
exoPlayer.seekTo(0)
- }
- // if playbackPosition is within 92% of the episode length, reset it to 0
+ //if playbackPosition is within 92% of the episode length, reset it to 0
if (playbackPosition > exoPlayer.duration.toFloat() * 0.92) {
playbackPosition = 0
exoPlayer.seekTo(0)
@@ -2152,25 +1945,20 @@ class ExoplayerView :
lifecycleScope.launch(Dispatchers.IO) {
model.loadTimeStamps(
media.idMAL,
- media.anime
- ?.selectedEpisode
- ?.trim()
- ?.toIntOrNull(),
+ media.anime?.selectedEpisode?.trim()?.toIntOrNull(),
dur / 1000,
- PrefManager.getVal(PrefName.UseProxyForTimeStamps),
+ PrefManager.getVal(PrefName.UseProxyForTimeStamps)
)
}
}
}
- // Link Preloading
+ //Link Preloading
private var preloading = false
-
private fun updateProgress() {
if (isInitialized) {
- if (exoPlayer.currentPosition.toFloat() / exoPlayer.duration >
- PrefManager.getVal(
- PrefName.WatchPercentage,
+ if (exoPlayer.currentPosition.toFloat() / exoPlayer.duration > PrefManager.getVal(
+ PrefName.WatchPercentage
)
) {
preloading = true
@@ -2178,150 +1966,134 @@ class ExoplayerView :
val ep = episodes[episodeArr[currentEpisodeIndex + i]] ?: return@nextEpisode
val selected = media.selected ?: return@nextEpisode
lifecycleScope.launch(Dispatchers.IO) {
- if (media.selected!!.server != null) {
+ if (media.selected!!.server != null)
model.loadEpisodeSingleVideo(ep, selected, false)
- } else {
+ else
model.loadEpisodeVideos(ep, selected.sourceIndex, false)
- }
}
}
}
}
- if (!preloading) {
- handler.postDelayed({
- updateProgress()
- }, 2500)
- }
+ if (!preloading) handler.postDelayed({
+ updateProgress()
+ }, 2500)
}
- // TimeStamp Updating
+ //TimeStamp Updating
private var currentTimeStamp: AniSkip.Stamp? = null
private var skippedTimeStamps: MutableList = mutableListOf()
-
private fun updateTimeStamp() {
if (isInitialized) {
val playerCurrentTime = exoPlayer.currentPosition / 1000
- currentTimeStamp =
- model.timeStamps.value?.find { timestamp ->
- timestamp.interval.startTime < playerCurrentTime &&
- playerCurrentTime < (timestamp.interval.endTime - 1)
- }
+ currentTimeStamp = model.timeStamps.value?.find { timestamp ->
+ timestamp.interval.startTime < playerCurrentTime
+ && playerCurrentTime < (timestamp.interval.endTime - 1)
+ }
val new = currentTimeStamp
- timeStampText.text =
- if (new != null) {
- fun disappearSkip() {
- functionstarted = true
+ timeStampText.text = if (new != null) {
+ fun disappearSkip() {
+ functionstarted = true
+ skipTimeButton.visibility = View.VISIBLE
+ exoSkip.visibility = View.GONE
+ skipTimeText.text = new.skipType.getType()
+ skipTimeButton.setOnClickListener {
+ exoPlayer.seekTo((new.interval.endTime * 1000).toLong())
+ }
+ var timer: CountDownTimer? = null
+ fun cancelTimer() {
+ timer?.cancel()
+ timer = null
+ return
+ }
+ timer = object : CountDownTimer(5000, 1000) {
+ override fun onTick(millisUntilFinished: Long) {
+ if (new == null) {
+ skipTimeButton.visibility = View.GONE
+ exoSkip.isVisible = PrefManager.getVal(PrefName.SkipTime) > 0
+ disappeared = false
+ functionstarted = false
+ cancelTimer()
+ }
+ }
+
+ override fun onFinish() {
+ skipTimeButton.visibility = View.GONE
+ exoSkip.isVisible = PrefManager.getVal(PrefName.SkipTime) > 0
+ disappeared = true
+ functionstarted = false
+ cancelTimer()
+ }
+ }
+ timer?.start()
+
+ }
+ if (PrefManager.getVal(PrefName.ShowTimeStampButton)) {
+
+ if (!functionstarted && !disappeared && PrefManager.getVal(PrefName.AutoHideTimeStamps)) {
+ disappearSkip()
+ } else if (!PrefManager.getVal(PrefName.AutoHideTimeStamps)) {
skipTimeButton.visibility = View.VISIBLE
exoSkip.visibility = View.GONE
skipTimeText.text = new.skipType.getType()
skipTimeButton.setOnClickListener {
exoPlayer.seekTo((new.interval.endTime * 1000).toLong())
}
- var timer: CountDownTimer? = null
+ }
- fun cancelTimer() {
- timer?.cancel()
- timer = null
- return
- }
- timer =
- object : CountDownTimer(5000, 1000) {
- override fun onTick(millisUntilFinished: Long) {
- if (new == null) {
- skipTimeButton.visibility = View.GONE
- exoSkip.isVisible =
- PrefManager.getVal(PrefName.SkipTime) > 0
- disappeared = false
- functionstarted = false
- cancelTimer()
- }
- }
-
- override fun onFinish() {
- skipTimeButton.visibility = View.GONE
- exoSkip.isVisible =
- PrefManager.getVal(PrefName.SkipTime) > 0
- disappeared = true
- functionstarted = false
- cancelTimer()
- }
- }
- timer?.start()
- }
- if (PrefManager.getVal(PrefName.ShowTimeStampButton)) {
- if (!functionstarted && !disappeared && PrefManager.getVal(PrefName.AutoHideTimeStamps)) {
- disappearSkip()
- } else if (!PrefManager.getVal(PrefName.AutoHideTimeStamps)) {
- skipTimeButton.visibility = View.VISIBLE
- exoSkip.visibility = View.GONE
- skipTimeText.text = new.skipType.getType()
- skipTimeButton.setOnClickListener {
- exoPlayer.seekTo((new.interval.endTime * 1000).toLong())
- }
- }
- }
- if (PrefManager.getVal(PrefName.AutoSkipOPED) &&
- (new.skipType == "op" || new.skipType == "ed") &&
- !skippedTimeStamps.contains(new)
- ) {
- exoPlayer.seekTo((new.interval.endTime * 1000).toLong())
- skippedTimeStamps.add(new)
- }
- if (PrefManager.getVal(PrefName.AutoSkipRecap) &&
- new.skipType == "recap" &&
- !skippedTimeStamps.contains(
- new,
- )
- ) {
- exoPlayer.seekTo((new.interval.endTime * 1000).toLong())
- skippedTimeStamps.add(new)
- }
- new.skipType.getType()
- } else {
- disappeared = false
- functionstarted = false
- skipTimeButton.visibility = View.GONE
- exoSkip.isVisible = PrefManager.getVal(PrefName.SkipTime) > 0
- ""
}
+ if (PrefManager.getVal(PrefName.AutoSkipOPED) && (new.skipType == "op" || new.skipType == "ed")
+ && !skippedTimeStamps.contains(new)
+ ) {
+ exoPlayer.seekTo((new.interval.endTime * 1000).toLong())
+ skippedTimeStamps.add(new)
+ }
+ if (PrefManager.getVal(PrefName.AutoSkipRecap) && new.skipType == "recap" && !skippedTimeStamps.contains(
+ new
+ )
+ ) {
+ exoPlayer.seekTo((new.interval.endTime * 1000).toLong())
+ skippedTimeStamps.add(new)
+ }
+ new.skipType.getType()
+ } else {
+ disappeared = false
+ functionstarted = false
+ skipTimeButton.visibility = View.GONE
+ exoSkip.isVisible = PrefManager.getVal(PrefName.SkipTime) > 0
+ ""
+ }
}
handler.postDelayed({
updateTimeStamp()
}, 500)
}
- fun onSetTrackGroupOverride(
- trackGroup: Tracks.Group,
- type: @C.TrackType Int,
- index: Int = 0,
- ) {
+ fun onSetTrackGroupOverride(trackGroup: Tracks.Group, type: @C.TrackType Int, index: Int = 0) {
val isDisabled = trackGroup.getTrackFormat(0).language == "none"
- exoPlayer.trackSelectionParameters =
- exoPlayer.trackSelectionParameters
- .buildUpon()
- .setTrackTypeDisabled(TRACK_TYPE_TEXT, isDisabled)
- .setOverrideForType(
- TrackSelectionOverride(trackGroup.mediaTrackGroup, index),
- ).build()
+ exoPlayer.trackSelectionParameters = exoPlayer.trackSelectionParameters
+ .buildUpon()
+ .setTrackTypeDisabled(TRACK_TYPE_TEXT, isDisabled)
+ .setOverrideForType(
+ TrackSelectionOverride(trackGroup.mediaTrackGroup, index)
+ )
+ .build()
if (type == TRACK_TYPE_TEXT) {
setupSubFormatting(playerView)
applySubtitleStyles(customSubtitleView)
}
- playerView.subtitleView?.alpha =
- when (isDisabled) {
- false -> PrefManager.getVal(PrefName.SubAlpha)
- true -> 0f
- }
+ playerView.subtitleView?.alpha = when (isDisabled) {
+ false -> PrefManager.getVal(PrefName.SubAlpha)
+ true -> 0f
+ }
}
- private val dummyTrack =
- Tracks.Group(
- TrackGroup("Dummy Track", Format.Builder().apply { setLanguage("none") }.build()),
- true,
- intArrayOf(1),
- booleanArrayOf(false),
- )
+ private val dummyTrack = Tracks.Group(
+ TrackGroup("Dummy Track", Format.Builder().apply { setLanguage("none") }.build()),
+ true,
+ intArrayOf(1),
+ booleanArrayOf(false)
+ )
override fun onTracksChanged(tracks: Tracks) {
val audioTracks: ArrayList = arrayListOf()
@@ -2329,7 +2101,7 @@ class ExoplayerView :
tracks.groups.forEach {
println(
"Track__: $it\nTrack__: ${it.length}\nTrack__: ${it.isSelected}\n" +
- "Track__: ${it.type}\nTrack__: ${it.mediaTrackGroup.id}",
+ "Track__: ${it.type}\nTrack__: ${it.mediaTrackGroup.id}"
)
when (it.type) {
TRACK_TYPE_AUDIO -> {
@@ -2358,33 +2130,31 @@ class ExoplayerView :
}
}
- private val onChangeSettings =
- registerForActivityResult(
- ActivityResultContracts.StartActivityForResult(),
- ) { _: ActivityResult ->
- if (!hasExtSubtitles) {
- exoPlayer.currentTracks.groups.forEach { trackGroup ->
- when (trackGroup.type) {
- TRACK_TYPE_TEXT -> {
- if (PrefManager.getVal(PrefName.Subtitles)) {
- onSetTrackGroupOverride(trackGroup, TRACK_TYPE_TEXT)
- } else {
- onSetTrackGroupOverride(dummyTrack, TRACK_TYPE_TEXT)
- }
+ private val onChangeSettings = registerForActivityResult(
+ ActivityResultContracts.StartActivityForResult()
+ ) { _: ActivityResult ->
+ if (!hasExtSubtitles) {
+ exoPlayer.currentTracks.groups.forEach { trackGroup ->
+ when (trackGroup.type) {
+ TRACK_TYPE_TEXT -> {
+ if (PrefManager.getVal(PrefName.Subtitles)) {
+ onSetTrackGroupOverride(trackGroup, TRACK_TYPE_TEXT)
+ } else {
+ onSetTrackGroupOverride(dummyTrack, TRACK_TYPE_TEXT)
}
-
- else -> {}
}
+
+ else -> {}
}
}
- if (isInitialized) exoPlayer.play()
}
+ if (isInitialized) exoPlayer.play()
+ }
override fun onPlayerError(error: PlaybackException) {
when (error.errorCode) {
PlaybackException.ERROR_CODE_IO_BAD_HTTP_STATUS,
- PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED,
- -> {
+ PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED -> {
toast("Source Exception : ${error.message}")
isPlayerPlaying = true
sourceClick()
@@ -2398,7 +2168,6 @@ class ExoplayerView :
}
private var isBuffering = true
-
override fun onPlaybackStateChanged(playbackState: Int) {
if (playbackState == ExoPlayer.STATE_READY) {
exoPlayer.play()
@@ -2409,30 +2178,24 @@ class ExoplayerView :
}
isBuffering = playbackState == Player.STATE_BUFFERING
if (playbackState == Player.STATE_ENDED && PrefManager.getVal(PrefName.AutoPlay)) {
- if (interacted) {
- exoNext.performClick()
- } else {
- toast(getString(R.string.autoplay_cancelled))
- }
+ if (interacted) exoNext.performClick()
+ else toast(getString(R.string.autoplay_cancelled))
}
super.onPlaybackStateChanged(playbackState)
}
private fun updateAniProgress() {
val incognito: Boolean = PrefManager.getVal(PrefName.Incognito)
- val episodeEnd =
- exoPlayer.currentPosition / episodeLength >
- PrefManager.getVal(
- PrefName.WatchPercentage,
- )
+ val episodeEnd = exoPlayer.currentPosition / episodeLength > PrefManager.getVal(
+ PrefName.WatchPercentage
+ )
val episode0 = currentEpisodeIndex == 0 && PrefManager.getVal(PrefName.ChapterZeroPlayer)
if (!incognito && (episodeEnd || episode0) && Anilist.userid != null
- ) {
+ )
if (PrefManager.getCustomVal(
"${media.id}_save_progress",
- true,
- ) &&
- (if (media.isAdult) PrefManager.getVal(PrefName.UpdateForHPlayer) else true)
+ true
+ ) && (if (media.isAdult) PrefManager.getVal(PrefName.UpdateForHPlayer) else true)
) {
if (episode0) {
updateProgress(media, "0")
@@ -2442,30 +2205,21 @@ class ExoplayerView :
}
}
}
- }
}
- private fun nextEpisode(
- toast: Boolean = true,
- runnable: ((Int) -> Unit),
- ) {
+ private fun nextEpisode(toast: Boolean = true, runnable: ((Int) -> Unit)) {
var isFiller = true
var i = 1
while (isFiller) {
if (episodeArr.size > currentEpisodeIndex + i) {
isFiller =
- if (PrefManager.getVal(PrefName.AutoSkipFiller)) {
- episodes[episodeArr[currentEpisodeIndex + i]]?.filler
- ?: false
- } else {
- false
- }
+ if (PrefManager.getVal(PrefName.AutoSkipFiller)) episodes[episodeArr[currentEpisodeIndex + i]]?.filler
+ ?: false else false
if (!isFiller) runnable.invoke(i)
i++
} else {
- if (toast) {
+ if (toast)
toast(getString(R.string.no_next_episode))
- }
isFiller = false
}
}
@@ -2508,7 +2262,7 @@ class ExoplayerView :
if (subtitle != null) shareVideo.putExtra("subtitle", subtitleUrl)
shareVideo.putExtra(
"title",
- media.userPreferredName + " : Ep " + episodeTitleArr[currentEpisodeIndex],
+ media.userPreferredName + " : Ep " + episodeTitleArr[currentEpisodeIndex]
)
shareVideo.putExtra("poster", episode.thumb?.url ?: media.cover)
val headers = Bundle()
@@ -2541,7 +2295,7 @@ class ExoplayerView :
PictureInPictureParams
.Builder()
.setAspectRatio(aspectRatio)
- .build(),
+ .build()
)
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
enterPictureInPictureMode()
@@ -2562,7 +2316,7 @@ class ExoplayerView :
if (isInitialized) {
PrefManager.setCustomVal(
"${media.id}_${episode.number}",
- exoPlayer.currentPosition,
+ exoPlayer.currentPosition
)
if (wasPlaying) exoPlayer.play()
}
@@ -2583,65 +2337,59 @@ class ExoplayerView :
@RequiresApi(Build.VERSION_CODES.O)
override fun onPictureInPictureModeChanged(
isInPictureInPictureMode: Boolean,
- newConfig: Configuration,
+ newConfig: Configuration
) {
onPiPChanged(isInPictureInPictureMode)
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
}
- private val keyMap: MutableMap Unit)?> =
- mutableMapOf(
- KEYCODE_DPAD_RIGHT to null,
- KEYCODE_DPAD_LEFT to null,
- KEYCODE_SPACE to { exoPlay.performClick() },
- KEYCODE_N to { exoNext.performClick() },
- KEYCODE_B to { exoPrev.performClick() },
- )
+ private val keyMap: MutableMap Unit)?> = mutableMapOf(
+ KEYCODE_DPAD_RIGHT to null,
+ KEYCODE_DPAD_LEFT to null,
+ KEYCODE_SPACE to { exoPlay.performClick() },
+ KEYCODE_N to { exoNext.performClick() },
+ KEYCODE_B to { exoPrev.performClick() }
+ )
- override fun dispatchKeyEvent(event: KeyEvent): Boolean =
- if (keyMap.containsKey(event.keyCode)) {
+ override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+ return if (keyMap.containsKey(event.keyCode)) {
(event.action == ACTION_UP).also {
if (isInitialized && it) keyMap[event.keyCode]?.invoke()
}
} else {
super.dispatchKeyEvent(event)
}
+ }
+
private fun startCastPlayer() {
if (!isCastApiAvailable) {
snackString("Cast API not available")
return
}
- // make sure mediaItem is initialized and castPlayer is not null
+ //make sure mediaItem is initialized and castPlayer is not null
if (!this::mediaItem.isInitialized || castPlayer == null) return
castPlayer?.setMediaItem(mediaItem)
castPlayer?.prepare()
playerView.player = castPlayer
exoPlayer.stop()
- castPlayer?.addListener(
- object : Player.Listener {
- // if the player is paused changed, we want to update the UI
- override fun onPlayWhenReadyChanged(
- playWhenReady: Boolean,
- reason: Int,
- ) {
- super.onPlayWhenReadyChanged(playWhenReady, reason)
- if (playWhenReady) {
- (exoPlay.drawable as Animatable?)?.start()
- Glide
- .with(this@ExoplayerView)
- .load(R.drawable.anim_play_to_pause)
- .into(exoPlay)
- } else {
- (exoPlay.drawable as Animatable?)?.start()
- Glide
- .with(this@ExoplayerView)
- .load(R.drawable.anim_pause_to_play)
- .into(exoPlay)
- }
+ castPlayer?.addListener(object : Player.Listener {
+ //if the player is paused changed, we want to update the UI
+ override fun onPlayWhenReadyChanged(playWhenReady: Boolean, reason: Int) {
+ super.onPlayWhenReadyChanged(playWhenReady, reason)
+ if (playWhenReady) {
+ (exoPlay.drawable as Animatable?)?.start()
+ Glide.with(this@ExoplayerView)
+ .load(R.drawable.anim_play_to_pause)
+ .into(exoPlay)
+ } else {
+ (exoPlay.drawable as Animatable?)?.start()
+ Glide.with(this@ExoplayerView)
+ .load(R.drawable.anim_pause_to_play)
+ .into(exoPlay)
}
- },
- )
+ }
+ })
}
private fun startExoPlayer() {
@@ -2661,14 +2409,14 @@ class ExoplayerView :
startExoPlayer()
}
+
@SuppressLint("ViewConstructor")
class ExtendedTimeBar(
context: Context,
- attrs: AttributeSet?,
+ attrs: AttributeSet?
) : DefaultTimeBar(context, attrs) {
private var enabled = false
private var forceDisabled = false
-
override fun setEnabled(enabled: Boolean) {
this.enabled = enabled
super.setEnabled(!forceDisabled && this.enabled)
@@ -2682,6 +2430,7 @@ class ExoplayerView :
}
class CustomCastButton : MediaRouteButton {
+
private var castCallback: (() -> Unit)? = null
fun setCastCallback(castCallback: () -> Unit) {
@@ -2695,14 +2444,15 @@ class CustomCastButton : MediaRouteButton {
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
context,
attrs,
- defStyleAttr,
+ defStyleAttr
)
- override fun performClick(): Boolean =
- if (PrefManager.getVal(PrefName.UseInternalCast)) {
+ override fun performClick(): Boolean {
+ return if (PrefManager.getVal(PrefName.UseInternalCast)) {
super.performClick()
} else {
castCallback?.let { it() }
true
}
-}
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ani/dantotsu/media/manga/MangaReadAdapter.kt b/app/src/main/java/ani/dantotsu/media/manga/MangaReadAdapter.kt
index ddf98974..a76d44a4 100644
--- a/app/src/main/java/ani/dantotsu/media/manga/MangaReadAdapter.kt
+++ b/app/src/main/java/ani/dantotsu/media/manga/MangaReadAdapter.kt
@@ -7,11 +7,9 @@ import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.CheckBox
-import android.widget.EditText
import android.widget.ImageButton
import android.widget.LinearLayout
import android.widget.NumberPicker
-import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.getString
import androidx.core.content.ContextCompat.startActivity
@@ -267,22 +265,19 @@ class MangaReadAdapter(
}
// Multi download
- //downloadNo.text = "0"
+ downloadNo.text = "0"
mediaDownloadTop.setOnClickListener {
+ // Alert dialog asking for the number of chapters to download
fragment.requireContext().customAlertDialog().apply {
setTitle("Multi Chapter Downloader")
setMessage("Enter the number of chapters to download")
- val input = View.inflate(currContext(), R.layout.dialog_layout, null)
- val editText = input.findViewById(R.id.downloadNo)
+ val input = NumberPicker(currContext())
+ input.minValue = 1
+ input.maxValue = 20
+ input.value = 1
setCustomView(input)
setPosButton(R.string.ok) {
- val value = editText.text.toString().toIntOrNull()
- if (value != null && value > 0) {
- downloadNo.setText(value.toString(), TextView.BufferType.EDITABLE)
- fragment.multiDownload(value)
- } else {
- toast("Please enter a valid number")
- }
+ downloadNo.text = "${input.value}"
}
setNegButton(R.string.cancel)
show()
@@ -387,9 +382,8 @@ class MangaReadAdapter(
setCustomView(root)
setPosButton("OK") {
if (run) fragment.onIconPressed(style, reversed)
- val value = downloadNo.text.toString().toIntOrNull()
- if (value != null && value > 0) {
- fragment.multiDownload(value)
+ if (downloadNo.text != "0") {
+ fragment.multiDownload(downloadNo.text.toString().toInt())
}
if (refresh) fragment.loadChapters(source, true)
}
diff --git a/app/src/main/java/ani/dantotsu/media/manga/MangaReadFragment.kt b/app/src/main/java/ani/dantotsu/media/manga/MangaReadFragment.kt
index 63ef7408..6b7eb6bc 100644
--- a/app/src/main/java/ani/dantotsu/media/manga/MangaReadFragment.kt
+++ b/app/src/main/java/ani/dantotsu/media/manga/MangaReadFragment.kt
@@ -474,7 +474,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
scanlator = chapter.scanlator ?: "Unknown",
imageData = images,
sourceMedia = media,
- retries = 25,
+ retries = 2,
simultaneousDownloads = 2
)
diff --git a/app/src/main/java/ani/dantotsu/others/CrashActivity.kt b/app/src/main/java/ani/dantotsu/others/CrashActivity.kt
index c8a0af8b..c410d687 100644
--- a/app/src/main/java/ani/dantotsu/others/CrashActivity.kt
+++ b/app/src/main/java/ani/dantotsu/others/CrashActivity.kt
@@ -24,11 +24,11 @@ class CrashActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
ThemeManager(this).applyTheme()
initActivity(this)
+ binding = ActivityCrashBinding.inflate(layoutInflater)
window.setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE
)
- binding = ActivityCrashBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.root.updateLayoutParams {
topMargin = statusBarHeight
diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsAnimeActivity.kt b/app/src/main/java/ani/dantotsu/settings/SettingsAnimeActivity.kt
index 73f90595..2a5c6aee 100644
--- a/app/src/main/java/ani/dantotsu/settings/SettingsAnimeActivity.kt
+++ b/app/src/main/java/ani/dantotsu/settings/SettingsAnimeActivity.kt
@@ -19,7 +19,6 @@ import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.statusBarHeight
import ani.dantotsu.themes.ThemeManager
-import ani.dantotsu.util.customAlertDialog
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@@ -58,16 +57,23 @@ class SettingsAnimeActivity : AppCompatActivity() {
desc = getString(R.string.purge_anime_downloads_desc),
icon = R.drawable.ic_round_delete_24,
onClick = {
- context.customAlertDialog().apply {
- setTitle(R.string.purge_anime_downloads)
- setMessage(R.string.purge_confirm, getString(R.string.anime))
- setPosButton(R.string.yes, onClick = {
+ val dialog = AlertDialog.Builder(context, R.style.MyPopup)
+ .setTitle(R.string.purge_anime_downloads)
+ .setMessage(
+ getString(
+ R.string.purge_confirm,
+ getString(R.string.anime)
+ )
+ )
+ .setPositiveButton(R.string.yes) { dialog, _ ->
val downloadsManager = Injekt.get()
downloadsManager.purgeDownloads(MediaType.ANIME)
- })
- setNegButton(R.string.no)
- show()
- }
+ dialog.dismiss()
+ }.setNegativeButton(R.string.no) { dialog, _ ->
+ dialog.dismiss()
+ }.create()
+ dialog.window?.setDimAmount(0.8f)
+ dialog.show()
}
),
@@ -137,4 +143,4 @@ class SettingsAnimeActivity : AppCompatActivity() {
}
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsCommonActivity.kt b/app/src/main/java/ani/dantotsu/settings/SettingsCommonActivity.kt
index f0bf91d0..8cfa7160 100644
--- a/app/src/main/java/ani/dantotsu/settings/SettingsCommonActivity.kt
+++ b/app/src/main/java/ani/dantotsu/settings/SettingsCommonActivity.kt
@@ -45,6 +45,7 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.UUID
+
class SettingsCommonActivity : AppCompatActivity() {
private lateinit var binding: ActivitySettingsCommonBinding
private lateinit var launcher: LauncherWrapper
@@ -61,27 +62,23 @@ class SettingsCommonActivity : AppCompatActivity() {
registerForActivityResult(ActivityResultContracts.OpenDocument()) { uri ->
if (uri != null) {
try {
- val jsonString =
- contentResolver.openInputStream(uri)?.readBytes()
- ?: throw Exception("Error reading file")
+ val jsonString = contentResolver.openInputStream(uri)?.readBytes()
+ ?: throw Exception("Error reading file")
val name = DocumentFile.fromSingleUri(this, uri)?.name ?: "settings"
- // .sani is encrypted, .ani is not
+ //.sani is encrypted, .ani is not
if (name.endsWith(".sani")) {
passwordAlertDialog(false) { password ->
if (password != null) {
val salt = jsonString.copyOfRange(0, 16)
val encrypted = jsonString.copyOfRange(16, jsonString.size)
- val decryptedJson =
- try {
- PreferenceKeystore.decryptWithPassword(
- password,
- encrypted,
- salt,
- )
- } catch (e: Exception) {
- toast(getString(R.string.incorrect_password))
- return@passwordAlertDialog
- }
+ val decryptedJson = try {
+ PreferenceKeystore.decryptWithPassword(
+ password, encrypted, salt
+ )
+ } catch (e: Exception) {
+ toast(getString(R.string.incorrect_password))
+ return@passwordAlertDialog
+ }
if (PreferencePackager.unpack(decryptedJson)) restartApp()
} else {
toast(getString(R.string.password_cannot_be_empty))
@@ -103,6 +100,7 @@ class SettingsCommonActivity : AppCompatActivity() {
launcher = LauncherWrapper(this, contract)
binding.apply {
+
settingsCommonLayout.updateLayoutParams {
topMargin = statusBarHeight
bottomMargin = navBarHeight
@@ -110,30 +108,27 @@ class SettingsCommonActivity : AppCompatActivity() {
commonSettingsBack.setOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
- val exDns =
- listOf(
- "None",
- "Cloudflare",
- "Google",
- "AdGuard",
- "Quad9",
- "AliDNS",
- "DNSPod",
- "360",
- "Quad101",
- "Mullvad",
- "Controld",
- "Njalla",
- "Shecan",
- "Libre",
- )
+ val exDns = listOf(
+ "None",
+ "Cloudflare",
+ "Google",
+ "AdGuard",
+ "Quad9",
+ "AliDNS",
+ "DNSPod",
+ "360",
+ "Quad101",
+ "Mullvad",
+ "Controld",
+ "Njalla",
+ "Shecan",
+ "Libre"
+ )
settingsExtensionDns.setText(exDns[PrefManager.getVal(PrefName.DohProvider)])
settingsExtensionDns.setAdapter(
ArrayAdapter(
- context,
- R.layout.item_dropdown,
- exDns,
- ),
+ context, R.layout.item_dropdown, exDns
+ )
)
settingsExtensionDns.setOnItemClickListener { _, _, i, _ ->
PrefManager.setVal(PrefName.DohProvider, i)
@@ -141,287 +136,283 @@ class SettingsCommonActivity : AppCompatActivity() {
restartApp()
}
- settingsRecyclerView.adapter =
- SettingsAdapter(
- arrayListOf(
- Settings(
- type = 1,
- name = getString(R.string.ui_settings),
- desc = getString(R.string.ui_settings_desc),
- icon = R.drawable.ic_round_auto_awesome_24,
- onClick = {
- startActivity(
- Intent(
- context,
- UserInterfaceSettingsActivity::class.java,
- ),
+ settingsRecyclerView.adapter = SettingsAdapter(
+ arrayListOf(
+ Settings(
+ type = 1,
+ name = getString(R.string.ui_settings),
+ desc = getString(R.string.ui_settings_desc),
+ icon = R.drawable.ic_round_auto_awesome_24,
+ onClick = {
+ startActivity(
+ Intent(
+ context,
+ UserInterfaceSettingsActivity::class.java
)
- },
- isActivity = true,
- ),
- Settings(
- type = 1,
- name = getString(R.string.download_manager_select),
- desc = getString(R.string.download_manager_select_desc),
- icon = R.drawable.ic_download_24,
- onClick = {
- val managers = arrayOf("Default", "1DM", "ADM")
- customAlertDialog().apply {
- setTitle(getString(R.string.download_manager))
- singleChoiceItems(
- managers,
- PrefManager.getVal(PrefName.DownloadManager),
- ) { count ->
- PrefManager.setVal(PrefName.DownloadManager, count)
- }
- show()
+ )
+ },
+ isActivity = true
+ ),
+ Settings(
+ type = 2,
+ name = getString(R.string.open_animanga_directly),
+ desc = getString(R.string.open_animanga_directly_info),
+ icon = R.drawable.ic_round_search_24,
+ isChecked = PrefManager.getVal(PrefName.AniMangaSearchDirect),
+ switch = { isChecked, _ ->
+ PrefManager.setVal(PrefName.AniMangaSearchDirect, isChecked)
+ }
+ ),
+ Settings(
+ type = 1,
+ name = getString(R.string.download_manager_select),
+ desc = getString(R.string.download_manager_select_desc),
+ icon = R.drawable.ic_download_24,
+ onClick = {
+ val managers = arrayOf("Default", "1DM", "ADM")
+ customAlertDialog().apply {
+ setTitle(getString(R.string.download_manager))
+ singleChoiceItems(
+ managers,
+ PrefManager.getVal(PrefName.DownloadManager)
+ ) { count ->
+ PrefManager.setVal(PrefName.DownloadManager, count)
}
- },
- ),
- Settings(
- type = 1,
- name = getString(R.string.app_lock),
- desc = getString(R.string.app_lock_desc),
- icon = R.drawable.ic_round_lock_open_24,
- onClick = {
- customAlertDialog().apply {
- val view = DialogSetPasswordBinding.inflate(layoutInflater)
- setTitle(R.string.app_lock)
- setCustomView(view.root)
- setPosButton(R.string.ok) {
- if (view.forgotPasswordCheckbox.isChecked) {
- PrefManager.setVal(PrefName.OverridePassword, true)
- }
- val password = view.passwordInput.text.toString()
- val confirmPassword =
- view.confirmPasswordInput.text.toString()
- if (password == confirmPassword && password.isNotEmpty()) {
- PrefManager.setVal(PrefName.AppPassword, password)
- if (view.biometricCheckbox.isChecked) {
- val canBiometricPrompt =
- BiometricManager
- .from(applicationContext)
- .canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK) ==
- BiometricManager.BIOMETRIC_SUCCESS
+ show()
+ }
+ }
+ ),
+ Settings(
+ type = 1,
+ name = getString(R.string.app_lock),
+ desc = getString(R.string.app_lock_desc),
+ icon = R.drawable.ic_round_lock_open_24,
+ onClick = {
+ customAlertDialog().apply {
+ val view = DialogSetPasswordBinding.inflate(layoutInflater)
+ setTitle(R.string.app_lock)
+ setCustomView(view.root)
+ setPosButton(R.string.ok) {
+ if (view.forgotPasswordCheckbox.isChecked) {
+ PrefManager.setVal(PrefName.OverridePassword, true)
+ }
+ val password = view.passwordInput.text.toString()
+ val confirmPassword = view.confirmPasswordInput.text.toString()
+ if (password == confirmPassword && password.isNotEmpty()) {
+ PrefManager.setVal(PrefName.AppPassword, password)
+ if (view.biometricCheckbox.isChecked) {
+ val canBiometricPrompt =
+ BiometricManager.from(applicationContext)
+ .canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK) == BiometricManager.BIOMETRIC_SUCCESS
- if (canBiometricPrompt) {
- val biometricPrompt =
- BiometricPromptUtils.createBiometricPrompt(
- this@SettingsCommonActivity
- ) { _ ->
- val token = UUID.randomUUID().toString()
- PrefManager.setVal(
- PrefName.BiometricToken,
- token,
- )
- toast(R.string.success)
- }
- val promptInfo =
- BiometricPromptUtils.createPromptInfo(this@SettingsCommonActivity)
- biometricPrompt.authenticate(promptInfo)
- }
+ if (canBiometricPrompt) {
+ val biometricPrompt =
+ BiometricPromptUtils.createBiometricPrompt(this@SettingsCommonActivity) { _ ->
+ val token = UUID.randomUUID().toString()
+ PrefManager.setVal(
+ PrefName.BiometricToken,
+ token
+ )
+ toast(R.string.success)
+ }
+ val promptInfo =
+ BiometricPromptUtils.createPromptInfo(this@SettingsCommonActivity)
+ biometricPrompt.authenticate(promptInfo)
+ }
+
+ } else {
+ PrefManager.setVal(PrefName.BiometricToken, "")
+ toast(R.string.success)
+ }
+ } else {
+ toast(R.string.password_mismatch)
+ }
+ }
+ setNegButton(R.string.cancel)
+ setNeutralButton(R.string.remove) {
+ PrefManager.setVal(PrefName.AppPassword, "")
+ PrefManager.setVal(PrefName.BiometricToken, "")
+ PrefManager.setVal(PrefName.OverridePassword, false)
+ toast(R.string.success)
+ }
+ setOnShowListener {
+ view.passwordInput.requestFocus()
+ val canAuthenticate =
+ BiometricManager.from(applicationContext).canAuthenticate(
+ BiometricManager.Authenticators.BIOMETRIC_WEAK
+ ) == BiometricManager.BIOMETRIC_SUCCESS
+ view.biometricCheckbox.isVisible = canAuthenticate
+ view.biometricCheckbox.isChecked =
+ PrefManager.getVal(PrefName.BiometricToken, "").isNotEmpty()
+ view.forgotPasswordCheckbox.isChecked =
+ PrefManager.getVal(PrefName.OverridePassword)
+ }
+ show()
+ }
+ }
+
+ ),
+ Settings(
+ type = 1,
+ name = getString(R.string.backup_restore),
+ desc = getString(R.string.backup_restore_desc),
+ icon = R.drawable.backup_restore,
+ onClick = {
+ StoragePermissions.downloadsPermission(context)
+ val selectedArray = mutableListOf(false)
+ val filteredLocations = Location.entries.filter { it.exportable }
+ selectedArray.addAll(List(filteredLocations.size - 1) { false })
+ val dialog = AlertDialog.Builder(context, R.style.MyPopup)
+ .setTitle(R.string.backup_restore).setMultiChoiceItems(
+ filteredLocations.map { it.name }.toTypedArray(),
+ selectedArray.toBooleanArray()
+ ) { _, which, isChecked ->
+ selectedArray[which] = isChecked
+ }.setPositiveButton(R.string.button_restore) { dialog, _ ->
+ openDocumentLauncher.launch(arrayOf("*/*"))
+ dialog.dismiss()
+ }.setNegativeButton(R.string.button_backup) { dialog, _ ->
+ if (!selectedArray.contains(true)) {
+ toast(R.string.no_location_selected)
+ return@setNegativeButton
+ }
+ dialog.dismiss()
+ val selected =
+ filteredLocations.filterIndexed { index, _ -> selectedArray[index] }
+ if (selected.contains(Location.Protected)) {
+ passwordAlertDialog(true) { password ->
+ if (password != null) {
+ savePrefsToDownloads(
+ "DantotsuSettings",
+ PrefManager.exportAllPrefs(selected),
+ context,
+ password
+ )
} else {
- PrefManager.setVal(PrefName.BiometricToken, "")
- toast(R.string.success)
+ toast(R.string.password_cannot_be_empty)
}
- } else {
- toast(R.string.password_mismatch)
}
+ } else {
+ savePrefsToDownloads(
+ "DantotsuSettings",
+ PrefManager.exportAllPrefs(selected),
+ context,
+ null
+ )
}
- setNegButton(R.string.cancel)
- setNeutralButton(R.string.remove) {
- PrefManager.setVal(PrefName.AppPassword, "")
- PrefManager.setVal(PrefName.BiometricToken, "")
- PrefManager.setVal(PrefName.OverridePassword, false)
- toast(R.string.success)
- }
- setOnShowListener {
- view.passwordInput.requestFocus()
- val canAuthenticate =
- BiometricManager.from(applicationContext)
- .canAuthenticate(
- BiometricManager.Authenticators.BIOMETRIC_WEAK,
- ) == BiometricManager.BIOMETRIC_SUCCESS
- view.biometricCheckbox.isVisible = canAuthenticate
- view.biometricCheckbox.isChecked =
- PrefManager.getVal(PrefName.BiometricToken, "")
- .isNotEmpty()
- view.forgotPasswordCheckbox.isChecked =
- PrefManager.getVal(PrefName.OverridePassword)
- }
- show()
- }
- },
- ),
- Settings(
- type = 1,
- name = getString(R.string.backup_restore),
- desc = getString(R.string.backup_restore_desc),
- icon = R.drawable.backup_restore,
- onClick = {
- StoragePermissions.downloadsPermission(context)
- val filteredLocations = Location.entries.filter { it.exportable }
- val selectedArray = BooleanArray(filteredLocations.size) { false }
- context.customAlertDialog().apply {
- setTitle(R.string.backup_restore)
- multiChoiceItems(
- filteredLocations.map { it.name }.toTypedArray(),
- selectedArray,
- ) { updatedSelection ->
- for (i in updatedSelection.indices) {
- selectedArray[i] = updatedSelection[i]
- }
- }
- setPosButton(R.string.button_restore) {
- openDocumentLauncher.launch(arrayOf("*/*"))
- }
- setNegButton(R.string.button_backup) {
- if (!selectedArray.contains(true)) {
- toast(R.string.no_location_selected)
- return@setNegButton
- }
- val selected =
- filteredLocations.filterIndexed { index, _ -> selectedArray[index] }
- if (selected.contains(Location.Protected)) {
- passwordAlertDialog(true) { password ->
- if (password != null) {
- savePrefsToDownloads(
- "DantotsuSettings",
- PrefManager.exportAllPrefs(selected),
- context,
- password,
- )
- } else {
- toast(R.string.password_cannot_be_empty)
- }
- }
- } else {
- savePrefsToDownloads(
- "DantotsuSettings",
- PrefManager.exportAllPrefs(selected),
- context,
- null,
- )
- }
- }
- setNeutralButton(R.string.cancel) {}
- show()
- }
- },
- ),
- Settings(
- type = 1,
- name = getString(R.string.change_download_location),
- desc = getString(R.string.change_download_location_desc),
- icon = R.drawable.ic_round_source_24,
- onClick = {
- context.customAlertDialog().apply {
- setTitle(R.string.change_download_location)
- setMessage(R.string.download_location_msg)
- setPosButton(R.string.ok) {
- val oldUri =
- PrefManager.getVal(PrefName.DownloadsDir)
- launcher.registerForCallback { success ->
- if (success) {
- toast(getString(R.string.please_wait))
- val newUri =
- PrefManager.getVal(PrefName.DownloadsDir)
- GlobalScope.launch(Dispatchers.IO) {
- Injekt.get().moveDownloadsDir(
- context,
- Uri.parse(oldUri),
- Uri.parse(newUri),
- ) { finished, message ->
- if (finished) {
- toast(getString(R.string.success))
- } else {
- toast(message)
- }
+ }.setNeutralButton(R.string.cancel) { dialog, _ ->
+ dialog.dismiss()
+ }.create()
+ dialog.window?.setDimAmount(0.8f)
+ dialog.show()
+ },
+ ),
+ Settings(
+ type = 1,
+ name = getString(R.string.change_download_location),
+ desc = getString(R.string.change_download_location_desc),
+ icon = R.drawable.ic_round_source_24,
+ onClick = {
+ context.customAlertDialog().apply {
+ setTitle(R.string.change_download_location)
+ setMessage(R.string.download_location_msg)
+ setPosButton(R.string.ok) {
+ val oldUri = PrefManager.getVal(PrefName.DownloadsDir)
+ launcher.registerForCallback { success ->
+ if (success) {
+ toast(getString(R.string.please_wait))
+ val newUri =
+ PrefManager.getVal(PrefName.DownloadsDir)
+ GlobalScope.launch(Dispatchers.IO) {
+ Injekt.get().moveDownloadsDir(
+ context, Uri.parse(oldUri), Uri.parse(newUri)
+ ) { finished, message ->
+ if (finished) {
+ toast(getString(R.string.success))
+ } else {
+ toast(message)
}
}
- } else {
- toast(getString(R.string.error))
}
+ } else {
+ toast(getString(R.string.error))
}
- launcher.launch()
}
- setNegButton(R.string.cancel)
- show()
+ launcher.launch()
}
- },
- ),
- Settings(
- type = 2,
- name = getString(R.string.always_continue_content),
- desc = getString(R.string.always_continue_content_desc),
- icon = R.drawable.ic_round_delete_24,
- isChecked = PrefManager.getVal(PrefName.ContinueMedia),
- switch = { isChecked, _ ->
- PrefManager.setVal(PrefName.ContinueMedia, isChecked)
- },
- ),
- Settings(
- type = 2,
- name = getString(R.string.hide_private),
- desc = getString(R.string.hide_private_desc),
- icon = R.drawable.ic_round_remove_red_eye_24,
- isChecked = PrefManager.getVal(PrefName.HidePrivate),
- switch = { isChecked, _ ->
- PrefManager.setVal(PrefName.HidePrivate, isChecked)
- restartApp()
- },
- ),
- Settings(
- type = 2,
- name = getString(R.string.search_source_list),
- desc = getString(R.string.search_source_list_desc),
- icon = R.drawable.ic_round_search_sources_24,
- isChecked = PrefManager.getVal(PrefName.SearchSources),
- switch = { isChecked, _ ->
- PrefManager.setVal(PrefName.SearchSources, isChecked)
- },
- ),
- Settings(
- type = 2,
- name = getString(R.string.recentlyListOnly),
- desc = getString(R.string.recentlyListOnly_desc),
- icon = R.drawable.ic_round_new_releases_24,
- isChecked = PrefManager.getVal(PrefName.RecentlyListOnly),
- switch = { isChecked, _ ->
- PrefManager.setVal(PrefName.RecentlyListOnly, isChecked)
- },
- ),
- Settings(
- type = 2,
- name = getString(R.string.adult_only_content),
- desc = getString(R.string.adult_only_content_desc),
- icon = R.drawable.ic_round_nsfw_24,
- isChecked = PrefManager.getVal(PrefName.AdultOnly),
- switch = { isChecked, _ ->
- PrefManager.setVal(PrefName.AdultOnly, isChecked)
- restartApp()
- },
- isVisible = Anilist.adult,
- ),
+ setNegButton(R.string.cancel)
+ show()
+ }
+ }
+ ),
+ Settings(
+ type = 2,
+ name = getString(R.string.always_continue_content),
+ desc = getString(R.string.always_continue_content_desc),
+ icon = R.drawable.ic_round_delete_24,
+ isChecked = PrefManager.getVal(PrefName.ContinueMedia),
+ switch = { isChecked, _ ->
+ PrefManager.setVal(PrefName.ContinueMedia, isChecked)
+ }
+ ),
+ Settings(
+ type = 2,
+ name = getString(R.string.hide_private),
+ desc = getString(R.string.hide_private_desc),
+ icon = R.drawable.ic_round_remove_red_eye_24,
+ isChecked = PrefManager.getVal(PrefName.HidePrivate),
+ switch = { isChecked, _ ->
+ PrefManager.setVal(PrefName.HidePrivate, isChecked)
+ restartApp()
+ }
+ ),
+ Settings(
+ type = 2,
+ name = getString(R.string.search_source_list),
+ desc = getString(R.string.search_source_list_desc),
+ icon = R.drawable.ic_round_search_sources_24,
+ isChecked = PrefManager.getVal(PrefName.SearchSources),
+ switch = { isChecked, _ ->
+ PrefManager.setVal(PrefName.SearchSources, isChecked)
+ }
+ ),
+ Settings(
+ type = 2,
+ name = getString(R.string.recentlyListOnly),
+ desc = getString(R.string.recentlyListOnly_desc),
+ icon = R.drawable.ic_round_new_releases_24,
+ isChecked = PrefManager.getVal(PrefName.RecentlyListOnly),
+ switch = { isChecked, _ ->
+ PrefManager.setVal(PrefName.RecentlyListOnly, isChecked)
+ }
+ ),
+ Settings(
+ type = 2,
+ name = getString(R.string.adult_only_content),
+ desc = getString(R.string.adult_only_content_desc),
+ icon = R.drawable.ic_round_nsfw_24,
+ isChecked = PrefManager.getVal(PrefName.AdultOnly),
+ switch = { isChecked, _ ->
+ PrefManager.setVal(PrefName.AdultOnly, isChecked)
+ restartApp()
+ },
+ isVisible = Anilist.adult
+
),
)
+ )
settingsRecyclerView.apply {
layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
setHasFixedSize(true)
}
- var previousStart: View =
- when (PrefManager.getVal(PrefName.DefaultStartUpTab)) {
- 0 -> uiSettingsAnime
- 1 -> uiSettingsHome
- 2 -> uiSettingsManga
- else -> uiSettingsHome
- }
+ var previousStart: View = when (PrefManager.getVal(PrefName.DefaultStartUpTab)) {
+ 0 -> uiSettingsAnime
+ 1 -> uiSettingsHome
+ 2 -> uiSettingsManga
+ else -> uiSettingsHome
+ }
previousStart.alpha = 1f
-
- fun uiDefault(
- mode: Int,
- current: View,
- ) {
+ fun uiDefault(mode: Int, current: View) {
previousStart.alpha = 0.33f
previousStart = current
current.alpha = 1f
@@ -440,13 +431,11 @@ class SettingsCommonActivity : AppCompatActivity() {
uiSettingsManga.setOnClickListener {
uiDefault(2, it)
}
+
}
}
- private fun passwordAlertDialog(
- isExporting: Boolean,
- callback: (CharArray?) -> Unit,
- ) {
+ private fun passwordAlertDialog(isExporting: Boolean, callback: (CharArray?) -> Unit) {
val password = CharArray(16).apply { fill('0') }
// Inflate the dialog layout
@@ -456,9 +445,7 @@ class SettingsCommonActivity : AppCompatActivity() {
box.setSingleLine()
val dialog =
- AlertDialog
- .Builder(this, R.style.MyPopup)
- .setTitle(getString(R.string.enter_password))
+ AlertDialog.Builder(this, R.style.MyPopup).setTitle(getString(R.string.enter_password))
.setView(dialogView.root)
.setPositiveButton(R.string.ok, null)
.setNegativeButton(R.string.cancel) { dialog, _ ->
@@ -470,10 +457,7 @@ class SettingsCommonActivity : AppCompatActivity() {
fun handleOkAction() {
val editText = dialogView.userAgentTextBox
if (editText.text?.isNotBlank() == true) {
- editText.text
- ?.toString()
- ?.trim()
- ?.toCharArray(password)
+ editText.text?.toString()?.trim()?.toCharArray(password)
dialog.dismiss()
callback(password)
} else {
@@ -489,20 +473,18 @@ class SettingsCommonActivity : AppCompatActivity() {
}
}
dialogView.subtitle.visibility = View.VISIBLE
- if (!isExporting) {
- dialogView.subtitle.text =
- getString(R.string.enter_password_to_decrypt_file)
- }
+ if (!isExporting) dialogView.subtitle.text =
+ getString(R.string.enter_password_to_decrypt_file)
- dialog.window?.apply {
- setDimAmount(0.8f)
- attributes.windowAnimations = android.R.style.Animation_Dialog
- }
+
+ dialog.window?.setDimAmount(0.8f)
dialog.show()
// Override the positive button here
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
handleOkAction()
}
+
}
-}
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsNotificationActivity.kt b/app/src/main/java/ani/dantotsu/settings/SettingsNotificationActivity.kt
index f1225ed4..ae3f08f5 100644
--- a/app/src/main/java/ani/dantotsu/settings/SettingsNotificationActivity.kt
+++ b/app/src/main/java/ani/dantotsu/settings/SettingsNotificationActivity.kt
@@ -128,27 +128,26 @@ class SettingsNotificationActivity : AppCompatActivity() {
PrefManager.getVal>(PrefName.AnilistFilteredTypes)
.toMutableSet()
val selected = types.map { filteredTypes.contains(it) }.toBooleanArray()
- context.customAlertDialog().apply {
- setTitle(R.string.anilist_notification_filters)
- multiChoiceItems(
+ val dialog = AlertDialog.Builder(context, R.style.MyPopup)
+ .setTitle(R.string.anilist_notification_filters)
+ .setMultiChoiceItems(
types.map { name ->
name.replace("_", " ").lowercase().replaceFirstChar {
if (it.isLowerCase()) it.titlecase(Locale.ROOT) else it.toString()
}
}.toTypedArray(),
selected
- ) { updatedSelected ->
- types.forEachIndexed { index, type ->
- if (updatedSelected[index]) {
- filteredTypes.add(type)
- } else {
- filteredTypes.remove(type)
- }
+ ) { _, which, isChecked ->
+ val type = types[which]
+ if (isChecked) {
+ filteredTypes.add(type)
+ } else {
+ filteredTypes.remove(type)
}
PrefManager.setVal(PrefName.AnilistFilteredTypes, filteredTypes)
- }
- show()
- }
+ }.create()
+ dialog.window?.setDimAmount(0.8f)
+ dialog.show()
}
),
@@ -161,24 +160,27 @@ class SettingsNotificationActivity : AppCompatActivity() {
desc = getString(R.string.anilist_notifications_checking_time_desc),
icon = R.drawable.ic_round_notifications_none_24,
onClick = {
- context.customAlertDialog().apply {
- setTitle(R.string.subscriptions_checking_time)
- singleChoiceItems(
+ val selected =
+ PrefManager.getVal(PrefName.AnilistNotificationInterval)
+ val dialog = AlertDialog.Builder(context, R.style.MyPopup)
+ .setTitle(R.string.subscriptions_checking_time)
+ .setSingleChoiceItems(
aItems.toTypedArray(),
- PrefManager.getVal(PrefName.AnilistNotificationInterval)
- ) { i ->
+ selected
+ ) { dialog, i ->
PrefManager.setVal(PrefName.AnilistNotificationInterval, i)
it.settingsTitle.text =
getString(
R.string.anilist_notifications_checking_time,
aItems[i]
)
+ dialog.dismiss()
TaskScheduler.create(
context, PrefManager.getVal(PrefName.UseAlarmManager)
).scheduleAllTasks(context)
- }
- show()
- }
+ }.create()
+ dialog.window?.setDimAmount(0.8f)
+ dialog.show()
}
),
Settings(
@@ -190,24 +192,27 @@ class SettingsNotificationActivity : AppCompatActivity() {
desc = getString(R.string.comment_notification_checking_time_desc),
icon = R.drawable.ic_round_notifications_none_24,
onClick = {
- context.customAlertDialog().apply {
- setTitle(R.string.subscriptions_checking_time)
- singleChoiceItems(
+ val selected =
+ PrefManager.getVal(PrefName.CommentNotificationInterval)
+ val dialog = AlertDialog.Builder(context, R.style.MyPopup)
+ .setTitle(R.string.subscriptions_checking_time)
+ .setSingleChoiceItems(
cItems.toTypedArray(),
- PrefManager.getVal(PrefName.CommentNotificationInterval)
- ) { i ->
+ selected
+ ) { dialog, i ->
PrefManager.setVal(PrefName.CommentNotificationInterval, i)
it.settingsTitle.text =
getString(
R.string.comment_notification_checking_time,
cItems[i]
)
+ dialog.dismiss()
TaskScheduler.create(
context, PrefManager.getVal(PrefName.UseAlarmManager)
).scheduleAllTasks(context)
- }
- show()
- }
+ }.create()
+ dialog.window?.setDimAmount(0.8f)
+ dialog.show()
}
),
Settings(
@@ -234,10 +239,10 @@ class SettingsNotificationActivity : AppCompatActivity() {
isChecked = PrefManager.getVal(PrefName.UseAlarmManager),
switch = { isChecked, view ->
if (isChecked) {
- context.customAlertDialog().apply {
- setTitle(R.string.use_alarm_manager)
- setMessage(R.string.use_alarm_manager_confirm)
- setPosButton(R.string.use) {
+ val alertDialog = AlertDialog.Builder(context, R.style.MyPopup)
+ .setTitle(R.string.use_alarm_manager)
+ .setMessage(R.string.use_alarm_manager_confirm)
+ .setPositiveButton(R.string.use) { dialog, _ ->
PrefManager.setVal(PrefName.UseAlarmManager, true)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
if (!(getSystemService(Context.ALARM_SERVICE) as AlarmManager).canScheduleExactAlarms()) {
@@ -247,13 +252,15 @@ class SettingsNotificationActivity : AppCompatActivity() {
view.settingsButton.isChecked = true
}
}
- }
- setNegButton(R.string.cancel) {
+ dialog.dismiss()
+ }.setNegativeButton(R.string.cancel) { dialog, _ ->
view.settingsButton.isChecked = false
PrefManager.setVal(PrefName.UseAlarmManager, false)
- }
- show()
- }
+
+ dialog.dismiss()
+ }.create()
+ alertDialog.window?.setDimAmount(0.8f)
+ alertDialog.show()
} else {
PrefManager.setVal(PrefName.UseAlarmManager, false)
TaskScheduler.create(context, true).cancelAllTasks()
@@ -270,4 +277,4 @@ class SettingsNotificationActivity : AppCompatActivity() {
}
}
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/ani/dantotsu/settings/SettingsThemeActivity.kt b/app/src/main/java/ani/dantotsu/settings/SettingsThemeActivity.kt
index 648c26bd..8133640a 100644
--- a/app/src/main/java/ani/dantotsu/settings/SettingsThemeActivity.kt
+++ b/app/src/main/java/ani/dantotsu/settings/SettingsThemeActivity.kt
@@ -96,8 +96,7 @@ class SettingsThemeActivity : AppCompatActivity(), SimpleDialog.OnDialogResultLi
themeSwitcher.apply {
setText(themeText)
setAdapter(
- ArrayAdapter(
- context,
+ ArrayAdapter(context,
R.layout.item_dropdown,
ThemeManager.Companion.Theme.entries.map {
it.theme.substring(
diff --git a/app/src/main/java/ani/dantotsu/settings/SubscriptionsBottomDialog.kt b/app/src/main/java/ani/dantotsu/settings/SubscriptionsBottomDialog.kt
index 188da9d3..9fa7552e 100644
--- a/app/src/main/java/ani/dantotsu/settings/SubscriptionsBottomDialog.kt
+++ b/app/src/main/java/ani/dantotsu/settings/SubscriptionsBottomDialog.kt
@@ -52,15 +52,14 @@ class SubscriptionsBottomDialog : BottomSheetDialogFragment() {
}
groupedSubscriptions.forEach { (parserName, mediaList) ->
- adapter.add(
- SubscriptionSource(
- parserName,
- mediaList.toMutableList(),
- adapter,
- getParserIcon(parserName)
- ) { group ->
- adapter.remove(group)
- })
+ adapter.add(SubscriptionSource(
+ parserName,
+ mediaList.toMutableList(),
+ adapter,
+ getParserIcon(parserName)
+ ) { group ->
+ adapter.remove(group)
+ })
}
}
diff --git a/app/src/main/res/layout/dialog_layout.xml b/app/src/main/res/layout/dialog_layout.xml
index 3c9df3b8..3db06395 100644
--- a/app/src/main/res/layout/dialog_layout.xml
+++ b/app/src/main/res/layout/dialog_layout.xml
@@ -8,7 +8,7 @@
android:padding="16dp">
@@ -160,8 +160,8 @@
android:orientation="horizontal">
-
-
-
-
-
-
-
-
-
+ tools:text="number" />