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:
parent
75e90541c9
commit
720b40afa7
35 changed files with 1162 additions and 1018 deletions
132
app/src/main/java/ani/dantotsu/util/StoragePermissions.kt
Normal file
132
app/src/main/java/ani/dantotsu/util/StoragePermissions.kt
Normal 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)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue