Compare commits
6 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a93b4f5b11 | ||
![]() |
69c44b7d20 | ||
![]() |
a684aac0b1 | ||
![]() |
6c49839f87 | ||
![]() |
7053a7b4b2 | ||
![]() |
1c156053d0 |
14 changed files with 178 additions and 120 deletions
|
@ -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!
|
> **Dantotsu (断トツ; Dan-totsu)** literally means "the best of the best" in Japanese. Try it out for yourself and be the judge!
|
||||||
|
|
||||||
<a href="https://www.buymeacoffee.com/rebelonion"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=rebelonion&button_colour=FFDD00&font_colour=030201&font_family=Poppins&outline_colour=000000&coffee_colour=ffffff" /></a>
|
<a href="https://www.buymeacoffee.com/rebelonion"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=rebelonion&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff" /></a>
|
||||||
|
|
||||||
## Terms of Use
|
## Terms of Use
|
||||||
By downloading, installing, or using this application, you agree to:
|
By downloading, installing, or using this application, you agree to:
|
||||||
|
|
|
@ -17,9 +17,8 @@ android {
|
||||||
applicationId "ani.dantotsu"
|
applicationId "ani.dantotsu"
|
||||||
minSdk 21
|
minSdk 21
|
||||||
targetSdk 35
|
targetSdk 35
|
||||||
versionCode((System.currentTimeMillis() / 60000).toInteger())
|
versionName "3.2.2"
|
||||||
versionName "3.2.1"
|
versionCode 300200200
|
||||||
versionCode 300200100
|
|
||||||
signingConfig signingConfigs.debug
|
signingConfig signingConfigs.debug
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,9 @@ open class RPC(val token: String, val coroutineContext: CoroutineContext) {
|
||||||
val assetApi = RPCExternalAsset(data.applicationId, token!!, client, json)
|
val assetApi = RPCExternalAsset(data.applicationId, token!!, client, json)
|
||||||
suspend fun String.discordUrl() = assetApi.getDiscordUri(this)
|
suspend fun String.discordUrl() = assetApi.getDiscordUri(this)
|
||||||
|
|
||||||
return json.encodeToString(Presence.Response(
|
return json.encodeToString(
|
||||||
3,
|
Presence.Response(
|
||||||
|
3,
|
||||||
Presence(
|
Presence(
|
||||||
activities = listOf(
|
activities = listOf(
|
||||||
Activity(
|
Activity(
|
||||||
|
|
|
@ -232,12 +232,18 @@ class MangaDownloaderService : Service() {
|
||||||
image.page,
|
image.page,
|
||||||
image.source
|
image.source
|
||||||
)
|
)
|
||||||
|
if (bitmap == null) {
|
||||||
|
snackString("${task.chapter} - Retrying to download page ${index.ofLength(3)}, attempt ${retryCount + 1}.")
|
||||||
|
}
|
||||||
retryCount++
|
retryCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitmap != null) {
|
if (bitmap == null) {
|
||||||
saveToDisk("${index.ofLength(3)}.jpg", outputDir, bitmap)
|
outputDir.deleteRecursively(this@MangaDownloaderService, false)
|
||||||
|
throw Exception("${task.chapter} - Unable to download all pages after $retryCount attempts. Try again.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveToDisk("${index.ofLength(3)}.jpg", outputDir, bitmap)
|
||||||
farthest++
|
farthest++
|
||||||
|
|
||||||
builder.setProgress(task.imageData.size, farthest, false)
|
builder.setProgress(task.imageData.size, farthest, false)
|
||||||
|
|
|
@ -427,7 +427,8 @@ class ExoplayerView :
|
||||||
false -> 0f
|
false -> 0f
|
||||||
}
|
}
|
||||||
|
|
||||||
val textElevation = PrefManager.getVal<Float>(PrefName.SubBottomMargin) / 50 * resources.displayMetrics.heightPixels
|
val textElevation =
|
||||||
|
PrefManager.getVal<Float>(PrefName.SubBottomMargin) / 50 * resources.displayMetrics.heightPixels
|
||||||
textView.translationY = -textElevation
|
textView.translationY = -textElevation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,9 +607,9 @@ class ExoplayerView :
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
pipEnabled =
|
pipEnabled =
|
||||||
packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE) &&
|
packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE) &&
|
||||||
PrefManager.getVal(
|
PrefManager.getVal(
|
||||||
PrefName.Pip,
|
PrefName.Pip,
|
||||||
)
|
)
|
||||||
if (pipEnabled) {
|
if (pipEnabled) {
|
||||||
exoPip.visibility = View.VISIBLE
|
exoPip.visibility = View.VISIBLE
|
||||||
exoPip.setOnClickListener {
|
exoPip.setOnClickListener {
|
||||||
|
@ -1044,7 +1045,8 @@ class ExoplayerView :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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<View>(R.id.exo_rewind_area)
|
val rewindArea = playerView.findViewById<View>(R.id.exo_rewind_area)
|
||||||
|
@ -1079,7 +1081,8 @@ class ExoplayerView :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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<View>(R.id.exo_forward_area)
|
val forwardArea = playerView.findViewById<View>(R.id.exo_forward_area)
|
||||||
|
@ -1449,7 +1452,8 @@ class ExoplayerView :
|
||||||
else -> mutableListOf()
|
else -> mutableListOf()
|
||||||
}
|
}
|
||||||
val startTimestamp = Calendar.getInstance()
|
val startTimestamp = Calendar.getInstance()
|
||||||
val durationInSeconds = if (exoPlayer.duration != C.TIME_UNSET) (exoPlayer.duration / 1000).toInt() else 1440
|
val durationInSeconds =
|
||||||
|
if (exoPlayer.duration != C.TIME_UNSET) (exoPlayer.duration / 1000).toInt() else 1440
|
||||||
|
|
||||||
val endTimestamp =
|
val endTimestamp =
|
||||||
Calendar.getInstance().apply {
|
Calendar.getInstance().apply {
|
||||||
|
@ -1502,12 +1506,12 @@ class ExoplayerView :
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val list =
|
val list =
|
||||||
(
|
(
|
||||||
PrefManager.getNullableCustomVal(
|
PrefManager.getNullableCustomVal(
|
||||||
"continueAnimeList",
|
"continueAnimeList",
|
||||||
listOf<Int>(),
|
listOf<Int>(),
|
||||||
List::class.java,
|
List::class.java,
|
||||||
) as List<Int>
|
) as List<Int>
|
||||||
).toMutableList()
|
).toMutableList()
|
||||||
if (list.contains(media.id)) list.remove(media.id)
|
if (list.contains(media.id)) list.remove(media.id)
|
||||||
list.add(media.id)
|
list.add(media.id)
|
||||||
PrefManager.setCustomVal("continueAnimeList", list)
|
PrefManager.setCustomVal("continueAnimeList", list)
|
||||||
|
@ -1567,7 +1571,11 @@ class ExoplayerView :
|
||||||
subtitle = intent.getSerialized("subtitle")
|
subtitle = intent.getSerialized("subtitle")
|
||||||
?: when (
|
?: when (
|
||||||
val subLang: String? =
|
val subLang: String? =
|
||||||
PrefManager.getNullableCustomVal("subLang_${media.id}", null, String::class.java)
|
PrefManager.getNullableCustomVal(
|
||||||
|
"subLang_${media.id}",
|
||||||
|
null,
|
||||||
|
String::class.java
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
null -> {
|
null -> {
|
||||||
when (episode.selectedSubtitle) {
|
when (episode.selectedSubtitle) {
|
||||||
|
@ -1575,8 +1583,12 @@ class ExoplayerView :
|
||||||
-1 ->
|
-1 ->
|
||||||
ext.subtitles.find {
|
ext.subtitles.find {
|
||||||
it.language.contains(lang, ignoreCase = true) ||
|
it.language.contains(lang, ignoreCase = true) ||
|
||||||
it.language.contains(getLanguageCode(lang), ignoreCase = true)
|
it.language.contains(
|
||||||
|
getLanguageCode(lang),
|
||||||
|
ignoreCase = true
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> ext.subtitles.getOrNull(episode.selectedSubtitle!!)
|
else -> ext.subtitles.getOrNull(episode.selectedSubtitle!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1651,7 +1663,8 @@ class ExoplayerView :
|
||||||
}.build()
|
}.build()
|
||||||
val dataSourceFactory =
|
val dataSourceFactory =
|
||||||
DataSource.Factory {
|
DataSource.Factory {
|
||||||
val dataSource: HttpDataSource = OkHttpDataSource.Factory(httpClient).createDataSource()
|
val dataSource: HttpDataSource =
|
||||||
|
OkHttpDataSource.Factory(httpClient).createDataSource()
|
||||||
defaultHeaders.forEach {
|
defaultHeaders.forEach {
|
||||||
dataSource.setRequestProperty(it.key, it.value)
|
dataSource.setRequestProperty(it.key, it.value)
|
||||||
}
|
}
|
||||||
|
@ -1717,16 +1730,18 @@ class ExoplayerView :
|
||||||
val docFile =
|
val docFile =
|
||||||
directory.listFiles().firstOrNull {
|
directory.listFiles().firstOrNull {
|
||||||
it.name?.endsWith(".mp4") == true ||
|
it.name?.endsWith(".mp4") == true ||
|
||||||
it.name?.endsWith(".mkv") == true ||
|
it.name?.endsWith(".mkv") == true ||
|
||||||
it.name?.endsWith(
|
it.name?.endsWith(
|
||||||
".${Injekt
|
".${
|
||||||
.get<DownloadAddonManager>()
|
Injekt
|
||||||
.extension
|
.get<DownloadAddonManager>()
|
||||||
?.extension
|
.extension
|
||||||
?.getFileExtension()
|
?.extension
|
||||||
?.first ?: "ts"}",
|
?.getFileExtension()
|
||||||
) ==
|
?.first ?: "ts"
|
||||||
true
|
}",
|
||||||
|
) ==
|
||||||
|
true
|
||||||
}
|
}
|
||||||
if (docFile != null) {
|
if (docFile != null) {
|
||||||
val uri = docFile.uri
|
val uri = docFile.uri
|
||||||
|
@ -1840,30 +1855,30 @@ class ExoplayerView :
|
||||||
"%02d:%02d:%02d",
|
"%02d:%02d:%02d",
|
||||||
TimeUnit.MILLISECONDS.toHours(playbackPosition),
|
TimeUnit.MILLISECONDS.toHours(playbackPosition),
|
||||||
TimeUnit.MILLISECONDS.toMinutes(playbackPosition) -
|
TimeUnit.MILLISECONDS.toMinutes(playbackPosition) -
|
||||||
TimeUnit.HOURS.toMinutes(
|
TimeUnit.HOURS.toMinutes(
|
||||||
TimeUnit.MILLISECONDS.toHours(
|
TimeUnit.MILLISECONDS.toHours(
|
||||||
playbackPosition,
|
playbackPosition,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
TimeUnit.MILLISECONDS.toSeconds(playbackPosition) -
|
TimeUnit.MILLISECONDS.toSeconds(playbackPosition) -
|
||||||
TimeUnit.MINUTES.toSeconds(
|
TimeUnit.MINUTES.toSeconds(
|
||||||
TimeUnit.MILLISECONDS.toMinutes(
|
TimeUnit.MILLISECONDS.toMinutes(
|
||||||
playbackPosition,
|
playbackPosition,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
customAlertDialog().apply {
|
customAlertDialog().apply {
|
||||||
setTitle(getString(R.string.continue_from, time))
|
setTitle(getString(R.string.continue_from, time))
|
||||||
setCancelable(false)
|
setCancelable(false)
|
||||||
setPosButton(getString(R.string.yes)) {
|
setPosButton(getString(R.string.yes)) {
|
||||||
buildExoplayer()
|
buildExoplayer()
|
||||||
}
|
|
||||||
setNegButton(getString(R.string.no)) {
|
|
||||||
playbackPosition = 0L
|
|
||||||
buildExoplayer()
|
|
||||||
}
|
|
||||||
show()
|
|
||||||
}
|
}
|
||||||
|
setNegButton(getString(R.string.no)) {
|
||||||
|
playbackPosition = 0L
|
||||||
|
buildExoplayer()
|
||||||
|
}
|
||||||
|
show()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
buildExoplayer()
|
buildExoplayer()
|
||||||
}
|
}
|
||||||
|
@ -1928,7 +1943,7 @@ class ExoplayerView :
|
||||||
if (PrefManager.getVal<Boolean>(PrefName.TextviewSubtitles)) {
|
if (PrefManager.getVal<Boolean>(PrefName.TextviewSubtitles)) {
|
||||||
exoSubtitleView.visibility = View.GONE
|
exoSubtitleView.visibility = View.GONE
|
||||||
customSubtitleView.visibility = View.VISIBLE
|
customSubtitleView.visibility = View.VISIBLE
|
||||||
val newCues = cueGroup.cues.map { it.text.toString() ?: "" }
|
val newCues = cueGroup.cues.map { it.text.toString() }
|
||||||
|
|
||||||
if (newCues.isEmpty()) {
|
if (newCues.isEmpty()) {
|
||||||
customSubtitleView.text = ""
|
customSubtitleView.text = ""
|
||||||
|
@ -1940,7 +1955,9 @@ class ExoplayerView :
|
||||||
|
|
||||||
val currentPosition = exoPlayer.currentPosition
|
val currentPosition = exoPlayer.currentPosition
|
||||||
|
|
||||||
if ((lastSubtitle?.length ?: 0) < 20 || (lastPosition != 0L && currentPosition - lastPosition > 1500)) {
|
if ((lastSubtitle?.length
|
||||||
|
?: 0) < 20 || (lastPosition != 0L && currentPosition - lastPosition > 1500)
|
||||||
|
) {
|
||||||
activeSubtitles.clear()
|
activeSubtitles.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2187,7 +2204,7 @@ class ExoplayerView :
|
||||||
currentTimeStamp =
|
currentTimeStamp =
|
||||||
model.timeStamps.value?.find { timestamp ->
|
model.timeStamps.value?.find { timestamp ->
|
||||||
timestamp.interval.startTime < playerCurrentTime &&
|
timestamp.interval.startTime < playerCurrentTime &&
|
||||||
playerCurrentTime < (timestamp.interval.endTime - 1)
|
playerCurrentTime < (timestamp.interval.endTime - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
val new = currentTimeStamp
|
val new = currentTimeStamp
|
||||||
|
@ -2213,7 +2230,8 @@ class ExoplayerView :
|
||||||
override fun onTick(millisUntilFinished: Long) {
|
override fun onTick(millisUntilFinished: Long) {
|
||||||
if (new == null) {
|
if (new == null) {
|
||||||
skipTimeButton.visibility = View.GONE
|
skipTimeButton.visibility = View.GONE
|
||||||
exoSkip.isVisible = PrefManager.getVal<Int>(PrefName.SkipTime) > 0
|
exoSkip.isVisible =
|
||||||
|
PrefManager.getVal<Int>(PrefName.SkipTime) > 0
|
||||||
disappeared = false
|
disappeared = false
|
||||||
functionstarted = false
|
functionstarted = false
|
||||||
cancelTimer()
|
cancelTimer()
|
||||||
|
@ -2222,7 +2240,8 @@ class ExoplayerView :
|
||||||
|
|
||||||
override fun onFinish() {
|
override fun onFinish() {
|
||||||
skipTimeButton.visibility = View.GONE
|
skipTimeButton.visibility = View.GONE
|
||||||
exoSkip.isVisible = PrefManager.getVal<Int>(PrefName.SkipTime) > 0
|
exoSkip.isVisible =
|
||||||
|
PrefManager.getVal<Int>(PrefName.SkipTime) > 0
|
||||||
disappeared = true
|
disappeared = true
|
||||||
functionstarted = false
|
functionstarted = false
|
||||||
cancelTimer()
|
cancelTimer()
|
||||||
|
@ -2310,7 +2329,7 @@ class ExoplayerView :
|
||||||
tracks.groups.forEach {
|
tracks.groups.forEach {
|
||||||
println(
|
println(
|
||||||
"Track__: $it\nTrack__: ${it.length}\nTrack__: ${it.isSelected}\n" +
|
"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) {
|
when (it.type) {
|
||||||
TRACK_TYPE_AUDIO -> {
|
TRACK_TYPE_AUDIO -> {
|
||||||
|
@ -2365,7 +2384,7 @@ class ExoplayerView :
|
||||||
when (error.errorCode) {
|
when (error.errorCode) {
|
||||||
PlaybackException.ERROR_CODE_IO_BAD_HTTP_STATUS,
|
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}")
|
toast("Source Exception : ${error.message}")
|
||||||
isPlayerPlaying = true
|
isPlayerPlaying = true
|
||||||
sourceClick()
|
sourceClick()
|
||||||
|
@ -2403,9 +2422,9 @@ class ExoplayerView :
|
||||||
val incognito: Boolean = PrefManager.getVal(PrefName.Incognito)
|
val incognito: Boolean = PrefManager.getVal(PrefName.Incognito)
|
||||||
val episodeEnd =
|
val episodeEnd =
|
||||||
exoPlayer.currentPosition / episodeLength >
|
exoPlayer.currentPosition / episodeLength >
|
||||||
PrefManager.getVal<Float>(
|
PrefManager.getVal<Float>(
|
||||||
PrefName.WatchPercentage,
|
PrefName.WatchPercentage,
|
||||||
)
|
)
|
||||||
val episode0 = currentEpisodeIndex == 0 && PrefManager.getVal(PrefName.ChapterZeroPlayer)
|
val episode0 = currentEpisodeIndex == 0 && PrefManager.getVal(PrefName.ChapterZeroPlayer)
|
||||||
if (!incognito && (episodeEnd || episode0) && Anilist.userid != null
|
if (!incognito && (episodeEnd || episode0) && Anilist.userid != null
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -7,9 +7,11 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
import android.widget.CheckBox
|
import android.widget.CheckBox
|
||||||
|
import android.widget.EditText
|
||||||
import android.widget.ImageButton
|
import android.widget.ImageButton
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.NumberPicker
|
import android.widget.NumberPicker
|
||||||
|
import android.widget.TextView
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.ContextCompat.getString
|
import androidx.core.content.ContextCompat.getString
|
||||||
import androidx.core.content.ContextCompat.startActivity
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
|
@ -265,19 +267,22 @@ class MangaReadAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multi download
|
// Multi download
|
||||||
downloadNo.text = "0"
|
//downloadNo.text = "0"
|
||||||
mediaDownloadTop.setOnClickListener {
|
mediaDownloadTop.setOnClickListener {
|
||||||
// Alert dialog asking for the number of chapters to download
|
|
||||||
fragment.requireContext().customAlertDialog().apply {
|
fragment.requireContext().customAlertDialog().apply {
|
||||||
setTitle("Multi Chapter Downloader")
|
setTitle("Multi Chapter Downloader")
|
||||||
setMessage("Enter the number of chapters to download")
|
setMessage("Enter the number of chapters to download")
|
||||||
val input = NumberPicker(currContext())
|
val input = View.inflate(currContext(), R.layout.dialog_layout, null)
|
||||||
input.minValue = 1
|
val editText = input.findViewById<EditText>(R.id.downloadNo)
|
||||||
input.maxValue = 20
|
|
||||||
input.value = 1
|
|
||||||
setCustomView(input)
|
setCustomView(input)
|
||||||
setPosButton(R.string.ok) {
|
setPosButton(R.string.ok) {
|
||||||
downloadNo.text = "${input.value}"
|
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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setNegButton(R.string.cancel)
|
setNegButton(R.string.cancel)
|
||||||
show()
|
show()
|
||||||
|
@ -382,8 +387,9 @@ class MangaReadAdapter(
|
||||||
setCustomView(root)
|
setCustomView(root)
|
||||||
setPosButton("OK") {
|
setPosButton("OK") {
|
||||||
if (run) fragment.onIconPressed(style, reversed)
|
if (run) fragment.onIconPressed(style, reversed)
|
||||||
if (downloadNo.text != "0") {
|
val value = downloadNo.text.toString().toIntOrNull()
|
||||||
fragment.multiDownload(downloadNo.text.toString().toInt())
|
if (value != null && value > 0) {
|
||||||
|
fragment.multiDownload(value)
|
||||||
}
|
}
|
||||||
if (refresh) fragment.loadChapters(source, true)
|
if (refresh) fragment.loadChapters(source, true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -474,7 +474,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
||||||
scanlator = chapter.scanlator ?: "Unknown",
|
scanlator = chapter.scanlator ?: "Unknown",
|
||||||
imageData = images,
|
imageData = images,
|
||||||
sourceMedia = media,
|
sourceMedia = media,
|
||||||
retries = 2,
|
retries = 25,
|
||||||
simultaneousDownloads = 2
|
simultaneousDownloads = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,8 @@ class SettingsCommonActivity : AppCompatActivity() {
|
||||||
PrefManager.setVal(PrefName.OverridePassword, true)
|
PrefManager.setVal(PrefName.OverridePassword, true)
|
||||||
}
|
}
|
||||||
val password = view.passwordInput.text.toString()
|
val password = view.passwordInput.text.toString()
|
||||||
val confirmPassword = view.confirmPasswordInput.text.toString()
|
val confirmPassword =
|
||||||
|
view.confirmPasswordInput.text.toString()
|
||||||
if (password == confirmPassword && password.isNotEmpty()) {
|
if (password == confirmPassword && password.isNotEmpty()) {
|
||||||
PrefManager.setVal(PrefName.AppPassword, password)
|
PrefManager.setVal(PrefName.AppPassword, password)
|
||||||
if (view.biometricCheckbox.isChecked) {
|
if (view.biometricCheckbox.isChecked) {
|
||||||
|
@ -201,11 +202,13 @@ class SettingsCommonActivity : AppCompatActivity() {
|
||||||
BiometricManager
|
BiometricManager
|
||||||
.from(applicationContext)
|
.from(applicationContext)
|
||||||
.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK) ==
|
.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK) ==
|
||||||
BiometricManager.BIOMETRIC_SUCCESS
|
BiometricManager.BIOMETRIC_SUCCESS
|
||||||
|
|
||||||
if (canBiometricPrompt) {
|
if (canBiometricPrompt) {
|
||||||
val biometricPrompt =
|
val biometricPrompt =
|
||||||
BiometricPromptUtils.createBiometricPrompt(this@SettingsCommonActivity) { _ ->
|
BiometricPromptUtils.createBiometricPrompt(
|
||||||
|
this@SettingsCommonActivity
|
||||||
|
) { _ ->
|
||||||
val token = UUID.randomUUID().toString()
|
val token = UUID.randomUUID().toString()
|
||||||
PrefManager.setVal(
|
PrefManager.setVal(
|
||||||
PrefName.BiometricToken,
|
PrefName.BiometricToken,
|
||||||
|
@ -235,12 +238,14 @@ class SettingsCommonActivity : AppCompatActivity() {
|
||||||
setOnShowListener {
|
setOnShowListener {
|
||||||
view.passwordInput.requestFocus()
|
view.passwordInput.requestFocus()
|
||||||
val canAuthenticate =
|
val canAuthenticate =
|
||||||
BiometricManager.from(applicationContext).canAuthenticate(
|
BiometricManager.from(applicationContext)
|
||||||
BiometricManager.Authenticators.BIOMETRIC_WEAK,
|
.canAuthenticate(
|
||||||
) == BiometricManager.BIOMETRIC_SUCCESS
|
BiometricManager.Authenticators.BIOMETRIC_WEAK,
|
||||||
|
) == BiometricManager.BIOMETRIC_SUCCESS
|
||||||
view.biometricCheckbox.isVisible = canAuthenticate
|
view.biometricCheckbox.isVisible = canAuthenticate
|
||||||
view.biometricCheckbox.isChecked =
|
view.biometricCheckbox.isChecked =
|
||||||
PrefManager.getVal(PrefName.BiometricToken, "").isNotEmpty()
|
PrefManager.getVal(PrefName.BiometricToken, "")
|
||||||
|
.isNotEmpty()
|
||||||
view.forgotPasswordCheckbox.isChecked =
|
view.forgotPasswordCheckbox.isChecked =
|
||||||
PrefManager.getVal(PrefName.OverridePassword)
|
PrefManager.getVal(PrefName.OverridePassword)
|
||||||
}
|
}
|
||||||
|
@ -314,7 +319,8 @@ class SettingsCommonActivity : AppCompatActivity() {
|
||||||
setTitle(R.string.change_download_location)
|
setTitle(R.string.change_download_location)
|
||||||
setMessage(R.string.download_location_msg)
|
setMessage(R.string.download_location_msg)
|
||||||
setPosButton(R.string.ok) {
|
setPosButton(R.string.ok) {
|
||||||
val oldUri = PrefManager.getVal<String>(PrefName.DownloadsDir)
|
val oldUri =
|
||||||
|
PrefManager.getVal<String>(PrefName.DownloadsDir)
|
||||||
launcher.registerForCallback { success ->
|
launcher.registerForCallback { success ->
|
||||||
if (success) {
|
if (success) {
|
||||||
toast(getString(R.string.please_wait))
|
toast(getString(R.string.please_wait))
|
||||||
|
|
|
@ -82,9 +82,18 @@ class SettingsNotificationActivity : AppCompatActivity() {
|
||||||
setTitle(R.string.subscriptions_checking_time)
|
setTitle(R.string.subscriptions_checking_time)
|
||||||
singleChoiceItems(timeNames, curTime) { i ->
|
singleChoiceItems(timeNames, curTime) { i ->
|
||||||
curTime = i
|
curTime = i
|
||||||
it.settingsTitle.text = getString(R.string.subscriptions_checking_time_s, timeNames[i])
|
it.settingsTitle.text = getString(
|
||||||
PrefManager.setVal(PrefName.SubscriptionNotificationInterval, curTime)
|
R.string.subscriptions_checking_time_s,
|
||||||
TaskScheduler.create(context, PrefManager.getVal(PrefName.UseAlarmManager)).scheduleAllTasks(context)
|
timeNames[i]
|
||||||
|
)
|
||||||
|
PrefManager.setVal(
|
||||||
|
PrefName.SubscriptionNotificationInterval,
|
||||||
|
curTime
|
||||||
|
)
|
||||||
|
TaskScheduler.create(
|
||||||
|
context,
|
||||||
|
PrefManager.getVal(PrefName.UseAlarmManager)
|
||||||
|
).scheduleAllTasks(context)
|
||||||
}
|
}
|
||||||
show()
|
show()
|
||||||
}
|
}
|
||||||
|
@ -120,21 +129,22 @@ class SettingsNotificationActivity : AppCompatActivity() {
|
||||||
.toMutableSet()
|
.toMutableSet()
|
||||||
val selected = types.map { filteredTypes.contains(it) }.toBooleanArray()
|
val selected = types.map { filteredTypes.contains(it) }.toBooleanArray()
|
||||||
context.customAlertDialog().apply {
|
context.customAlertDialog().apply {
|
||||||
setTitle(R.string.anilist_notification_filters)
|
setTitle(R.string.anilist_notification_filters)
|
||||||
multiChoiceItems(
|
multiChoiceItems(
|
||||||
types.map { name ->
|
types.map { name ->
|
||||||
name.replace("_", " ").lowercase().replaceFirstChar {
|
name.replace("_", " ").lowercase().replaceFirstChar {
|
||||||
if (it.isLowerCase()) it.titlecase(Locale.ROOT) else it.toString()
|
if (it.isLowerCase()) it.titlecase(Locale.ROOT) else it.toString()
|
||||||
} }.toTypedArray(),
|
}
|
||||||
|
}.toTypedArray(),
|
||||||
selected
|
selected
|
||||||
) { updatedSelected ->
|
) { updatedSelected ->
|
||||||
types.forEachIndexed { index, type ->
|
types.forEachIndexed { index, type ->
|
||||||
if (updatedSelected[index]) {
|
if (updatedSelected[index]) {
|
||||||
filteredTypes.add(type)
|
filteredTypes.add(type)
|
||||||
} else {
|
} else {
|
||||||
filteredTypes.remove(type)
|
filteredTypes.remove(type)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
PrefManager.setVal(PrefName.AnilistFilteredTypes, filteredTypes)
|
PrefManager.setVal(PrefName.AnilistFilteredTypes, filteredTypes)
|
||||||
}
|
}
|
||||||
show()
|
show()
|
||||||
|
@ -152,8 +162,8 @@ class SettingsNotificationActivity : AppCompatActivity() {
|
||||||
icon = R.drawable.ic_round_notifications_none_24,
|
icon = R.drawable.ic_round_notifications_none_24,
|
||||||
onClick = {
|
onClick = {
|
||||||
context.customAlertDialog().apply {
|
context.customAlertDialog().apply {
|
||||||
setTitle(R.string.subscriptions_checking_time)
|
setTitle(R.string.subscriptions_checking_time)
|
||||||
singleChoiceItems(
|
singleChoiceItems(
|
||||||
aItems.toTypedArray(),
|
aItems.toTypedArray(),
|
||||||
PrefManager.getVal<Int>(PrefName.AnilistNotificationInterval)
|
PrefManager.getVal<Int>(PrefName.AnilistNotificationInterval)
|
||||||
) { i ->
|
) { i ->
|
||||||
|
@ -181,11 +191,11 @@ class SettingsNotificationActivity : AppCompatActivity() {
|
||||||
icon = R.drawable.ic_round_notifications_none_24,
|
icon = R.drawable.ic_round_notifications_none_24,
|
||||||
onClick = {
|
onClick = {
|
||||||
context.customAlertDialog().apply {
|
context.customAlertDialog().apply {
|
||||||
setTitle(R.string.subscriptions_checking_time)
|
setTitle(R.string.subscriptions_checking_time)
|
||||||
singleChoiceItems(
|
singleChoiceItems(
|
||||||
cItems.toTypedArray(),
|
cItems.toTypedArray(),
|
||||||
PrefManager.getVal<Int>(PrefName.CommentNotificationInterval)
|
PrefManager.getVal<Int>(PrefName.CommentNotificationInterval)
|
||||||
) { i ->
|
) { i ->
|
||||||
PrefManager.setVal(PrefName.CommentNotificationInterval, i)
|
PrefManager.setVal(PrefName.CommentNotificationInterval, i)
|
||||||
it.settingsTitle.text =
|
it.settingsTitle.text =
|
||||||
getString(
|
getString(
|
||||||
|
@ -225,9 +235,9 @@ class SettingsNotificationActivity : AppCompatActivity() {
|
||||||
switch = { isChecked, view ->
|
switch = { isChecked, view ->
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
context.customAlertDialog().apply {
|
context.customAlertDialog().apply {
|
||||||
setTitle(R.string.use_alarm_manager)
|
setTitle(R.string.use_alarm_manager)
|
||||||
setMessage(R.string.use_alarm_manager_confirm)
|
setMessage(R.string.use_alarm_manager_confirm)
|
||||||
setPosButton(R.string.use) {
|
setPosButton(R.string.use) {
|
||||||
PrefManager.setVal(PrefName.UseAlarmManager, true)
|
PrefManager.setVal(PrefName.UseAlarmManager, true)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
if (!(getSystemService(Context.ALARM_SERVICE) as AlarmManager).canScheduleExactAlarms()) {
|
if (!(getSystemService(Context.ALARM_SERVICE) as AlarmManager).canScheduleExactAlarms()) {
|
||||||
|
|
|
@ -96,7 +96,8 @@ class SettingsThemeActivity : AppCompatActivity(), SimpleDialog.OnDialogResultLi
|
||||||
themeSwitcher.apply {
|
themeSwitcher.apply {
|
||||||
setText(themeText)
|
setText(themeText)
|
||||||
setAdapter(
|
setAdapter(
|
||||||
ArrayAdapter(context,
|
ArrayAdapter(
|
||||||
|
context,
|
||||||
R.layout.item_dropdown,
|
R.layout.item_dropdown,
|
||||||
ThemeManager.Companion.Theme.entries.map {
|
ThemeManager.Companion.Theme.entries.map {
|
||||||
it.theme.substring(
|
it.theme.substring(
|
||||||
|
|
|
@ -52,14 +52,15 @@ class SubscriptionsBottomDialog : BottomSheetDialogFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
groupedSubscriptions.forEach { (parserName, mediaList) ->
|
groupedSubscriptions.forEach { (parserName, mediaList) ->
|
||||||
adapter.add(SubscriptionSource(
|
adapter.add(
|
||||||
parserName,
|
SubscriptionSource(
|
||||||
mediaList.toMutableList(),
|
parserName,
|
||||||
adapter,
|
mediaList.toMutableList(),
|
||||||
getParserIcon(parserName)
|
adapter,
|
||||||
) { group ->
|
getParserIcon(parserName)
|
||||||
adapter.remove(group)
|
) { group ->
|
||||||
})
|
adapter.remove(group)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
android:padding="16dp">
|
android:padding="16dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="326dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
@ -160,8 +160,8 @@
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="265dp"
|
android:layout_width="263dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="60dp"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -171,14 +171,23 @@
|
||||||
android:fontFamily="@font/poppins_bold"
|
android:fontFamily="@font/poppins_bold"
|
||||||
android:text="@string/download" />
|
android:text="@string/download" />
|
||||||
|
|
||||||
<TextView
|
<EditText
|
||||||
android:id="@+id/downloadNo"
|
android:id="@+id/downloadNo"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fontFamily="@font/poppins_bold"
|
android:fontFamily="@font/poppins_bold"
|
||||||
android:textColor="?attr/colorSecondary"
|
android:textColor="?attr/colorSecondary"
|
||||||
|
android:textSize="12dp"
|
||||||
tools:ignore="TextContrastCheck"
|
tools:ignore="TextContrastCheck"
|
||||||
tools:text="number" />
|
tools:text="Number" />
|
||||||
|
<!-- <TextView-->
|
||||||
|
<!-- android:id="@+id/downloadNo"-->
|
||||||
|
<!-- android:layout_width="match_parent"-->
|
||||||
|
<!-- android:layout_height="wrap_content"-->
|
||||||
|
<!-- android:fontFamily="@font/poppins_bold"-->
|
||||||
|
<!-- android:textColor="?attr/colorSecondary"-->
|
||||||
|
<!-- tools:ignore="TextContrastCheck"-->
|
||||||
|
<!-- tools:text="number" />-->
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
<androidx.cardview.widget.CardView
|
||||||
|
@ -191,7 +200,7 @@
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/mediaDownloadTop"
|
android:id="@+id/mediaDownloadTop"
|
||||||
android:layout_width="48dp"
|
android:layout_width="48dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="60dp"
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
app:srcCompat="@drawable/ic_download_24"
|
app:srcCompat="@drawable/ic_download_24"
|
||||||
app:tint="?attr/colorOnBackground"
|
app:tint="?attr/colorOnBackground"
|
||||||
|
@ -313,9 +322,9 @@
|
||||||
android:text="@string/reset" />
|
android:text="@string/reset" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/reset_progress_def"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/reset_progress_def"
|
|
||||||
android:fontFamily="@font/poppins_bold"
|
android:fontFamily="@font/poppins_bold"
|
||||||
android:text=""
|
android:text=""
|
||||||
android:textColor="?attr/colorSecondary"
|
android:textColor="?attr/colorSecondary"
|
||||||
|
|
|
@ -12,7 +12,7 @@ buildscript {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:8.7.3'
|
classpath 'com.android.tools.build:gradle:8.9.0'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
|
||||||
classpath "com.google.devtools.ksp:symbol-processing-api:$ksp_version"
|
classpath "com.google.devtools.ksp:symbol-processing-api:$ksp_version"
|
||||||
|
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
||||||
#Wed Aug 30 19:57:04 IST 2023
|
#Wed Aug 30 19:57:04 IST 2023
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue