feat: custom downloader and downloader location (#313)

* feat: custom downloader (novel broken)

* fix: send headers to ffmpeg

ffmpeg can be a real bitch to work with

* fix: offline page for new download system

* feat: novel to new system | load freezing

* chore: clean manifest

* fix: notification incrementing

* feat: changing the downloads dir
This commit is contained in:
rebel onion 2024-04-04 04:03:45 -05:00 committed by GitHub
parent 75e90541c9
commit 720b40afa7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 1162 additions and 1018 deletions

View file

@ -0,0 +1,132 @@
package ani.dantotsu.util
import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import ani.dantotsu.R
import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.toast
class StoragePermissions {
companion object {
fun downloadsPermission(activity: AppCompatActivity): Boolean {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) return true
val permissions = arrayOf(
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE
)
val requiredPermissions = permissions.filter {
ContextCompat.checkSelfPermission(activity, it) != PackageManager.PERMISSION_GRANTED
}.toTypedArray()
return if (requiredPermissions.isNotEmpty()) {
ActivityCompat.requestPermissions(
activity,
requiredPermissions,
DOWNLOADS_PERMISSION_REQUEST_CODE
)
false
} else {
true
}
}
fun hasDirAccess(context: Context, path: String): Boolean {
val uri = pathToUri(path)
return context.contentResolver.persistedUriPermissions.any {
it.uri == uri && it.isReadPermission && it.isWritePermission
}
}
fun hasDirAccess(context: Context, uri: Uri): Boolean {
return context.contentResolver.persistedUriPermissions.any {
it.uri == uri && it.isReadPermission && it.isWritePermission
}
}
fun hasDirAccess(context: Context): Boolean {
val path = PrefManager.getVal<String>(PrefName.DownloadsDir)
return hasDirAccess(context, path)
}
fun AppCompatActivity.accessAlertDialog(launcher: LauncherWrapper,
force: Boolean = false,
complete: (Boolean) -> Unit
) {
if ((PrefManager.getVal<String>(PrefName.DownloadsDir).isNotEmpty() || hasDirAccess(this)) && !force) {
complete(true)
return
}
val builder = AlertDialog.Builder(this, R.style.MyPopup)
builder.setTitle(getString(R.string.dir_access))
builder.setMessage(getString(R.string.dir_access_msg))
builder.setPositiveButton(getString(R.string.ok)) { dialog, _ ->
launcher.registerForCallback(complete)
launcher.launch()
dialog.dismiss()
}
builder.setNegativeButton(getString(R.string.cancel)) { dialog, _ ->
dialog.dismiss()
complete(false)
}
val dialog = builder.show()
dialog.window?.setDimAmount(0.8f)
}
private fun pathToUri(path: String): Uri {
return Uri.parse(path)
}
private const val DOWNLOADS_PERMISSION_REQUEST_CODE = 100
}
}
class LauncherWrapper(
activity: AppCompatActivity,
contract: ActivityResultContracts.OpenDocumentTree)
{
private var launcher: ActivityResultLauncher<Uri?>
var complete: (Boolean) -> Unit = {}
init{
launcher = activity.registerForActivityResult(contract) { uri ->
if (uri != null) {
activity.contentResolver.takePersistableUriPermission(
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
if (StoragePermissions.hasDirAccess(activity, uri)) {
PrefManager.setVal(PrefName.DownloadsDir, uri.toString())
complete(true)
} else {
toast(activity.getString(R.string.dir_error))
complete(false)
}
} else {
toast(activity.getString(R.string.dir_error))
complete(false)
}
}
}
fun registerForCallback(callback: (Boolean) -> Unit) {
complete = callback
}
fun launch() {
launcher.launch(null)
}
}