update permission request code in SearchStatusesFragment and SFragment, store the argument in a field saved as part of instance state.

This commit is contained in:
Christophe Beyls 2024-04-23 15:24:36 +02:00
parent 99b4629b8c
commit bb6673db59
2 changed files with 95 additions and 46 deletions

View File

@ -21,16 +21,18 @@ import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.PopupMenu
import androidx.core.app.ActivityOptionsCompat
import androidx.core.content.getSystemService
import androidx.core.view.ViewCompat
import androidx.lifecycle.lifecycleScope
import androidx.paging.PagingData
@ -41,7 +43,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import at.connyduck.calladapter.networkresult.fold
import at.connyduck.calladapter.networkresult.onFailure
import com.google.android.material.snackbar.Snackbar
import com.keylesspalace.tusky.BaseActivity
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.ViewMediaActivity
import com.keylesspalace.tusky.components.compose.ComposeActivity
@ -79,6 +80,34 @@ class SearchStatusesFragment : SearchFragment<StatusViewData.Concrete>(), Status
private val searchAdapter
get() = super.adapter as SearchStatusesAdapter
private var pendingMediaDownloads: List<String>? = null
private val downloadAllMediaPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
if (isGranted) {
pendingMediaDownloads?.let { downloadAllMedia(it) }
} else {
Toast.makeText(
context,
R.string.error_media_download_permission,
Toast.LENGTH_SHORT
).show()
}
pendingMediaDownloads = null
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
pendingMediaDownloads = savedInstanceState?.getStringArrayList(PENDING_MEDIA_DOWNLOADS_STATE_KEY)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
pendingMediaDownloads?.let {
outState.putStringArrayList(PENDING_MEDIA_DOWNLOADS_STATE_KEY, ArrayList(it))
}
}
override fun createAdapter(): PagingDataAdapter<StatusViewData.Concrete, *> {
val preferences = PreferenceManager.getDefaultSharedPreferences(
binding.searchRecyclerView.context
@ -236,10 +265,6 @@ class SearchStatusesFragment : SearchFragment<StatusViewData.Concrete>(), Status
}
}
companion object {
fun newInstance() = SearchStatusesFragment()
}
private fun reply(status: StatusViewData.Concrete) {
val actionableStatus = status.actionable
val mentionedUsernames = actionableStatus.mentions.map { it.username }
@ -499,37 +524,31 @@ class SearchStatusesFragment : SearchFragment<StatusViewData.Concrete>(), Status
)
}
private fun downloadAllMedia(status: Status) {
private fun downloadAllMedia(mediaUrls: List<String>) {
Toast.makeText(context, R.string.downloading_media, Toast.LENGTH_SHORT).show()
for ((_, url) in status.attachments) {
val uri = Uri.parse(url)
val filename = uri.lastPathSegment
val downloadManager: DownloadManager = requireContext().getSystemService()!!
val downloadManager = requireActivity().getSystemService(
Context.DOWNLOAD_SERVICE
) as DownloadManager
for (url in mediaUrls) {
val uri = Uri.parse(url)
val request = DownloadManager.Request(uri)
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename)
request.setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS,
uri.lastPathSegment
)
downloadManager.enqueue(request)
}
}
private fun requestDownloadAllMedia(status: Status) {
if (status.attachments.isEmpty()) {
return
}
val mediaUrls = status.attachments.map { it.url }
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
val permissions = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE)
(activity as BaseActivity).requestPermissions(permissions) { _, grantResults ->
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
downloadAllMedia(status)
} else {
Toast.makeText(
context,
R.string.error_media_download_permission,
Toast.LENGTH_SHORT
).show()
}
}
pendingMediaDownloads = mediaUrls
downloadAllMediaPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
} else {
downloadAllMedia(status)
downloadAllMedia(mediaUrls)
}
}
@ -628,4 +647,10 @@ class SearchStatusesFragment : SearchFragment<StatusViewData.Concrete>(), Status
)
}
}
companion object {
private const val PENDING_MEDIA_DOWNLOADS_STATE_KEY = "pending_media_downloads"
fun newInstance() = SearchStatusesFragment()
}
}

View File

@ -21,17 +21,19 @@ import android.content.ClipboardManager
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.view.MenuItem
import android.view.View
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.PopupMenu
import androidx.core.app.ActivityOptionsCompat
import androidx.core.content.getSystemService
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import at.connyduck.calladapter.networkresult.fold
@ -93,6 +95,22 @@ abstract class SFragment : Fragment(), Injectable {
@Inject
lateinit var instanceInfoRepository: InstanceInfoRepository
private var pendingMediaDownloads: List<String>? = null
private val downloadAllMediaPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
if (isGranted) {
pendingMediaDownloads?.let { downloadAllMedia(it) }
} else {
Toast.makeText(
context,
R.string.error_media_download_permission,
Toast.LENGTH_SHORT
).show()
}
pendingMediaDownloads = null
}
override fun startActivity(intent: Intent) {
requireActivity().startActivityWithSlideInAnimation(intent)
}
@ -106,6 +124,18 @@ abstract class SFragment : Fragment(), Injectable {
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
pendingMediaDownloads = savedInstanceState?.getStringArrayList(PENDING_MEDIA_DOWNLOADS_STATE_KEY)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
pendingMediaDownloads?.let {
outState.putStringArrayList(PENDING_MEDIA_DOWNLOADS_STATE_KEY, ArrayList(it))
}
}
override fun onResume() {
super.onResume()
@ -522,13 +552,11 @@ abstract class SFragment : Fragment(), Injectable {
}
}
private fun downloadAllMedia(status: Status) {
private fun downloadAllMedia(mediaUrls: List<String>) {
Toast.makeText(context, R.string.downloading_media, Toast.LENGTH_SHORT).show()
val downloadManager = requireActivity().getSystemService(
Context.DOWNLOAD_SERVICE
) as DownloadManager
val downloadManager: DownloadManager = requireContext().getSystemService()!!
for ((_, url) in status.attachments) {
for (url in mediaUrls) {
val uri = Uri.parse(url)
downloadManager.enqueue(
DownloadManager.Request(uri).apply {
@ -542,26 +570,22 @@ abstract class SFragment : Fragment(), Injectable {
}
private fun requestDownloadAllMedia(status: Status) {
if (status.attachments.isEmpty()) {
return
}
val mediaUrls = status.attachments.map { it.url }
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
val permissions = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE)
(activity as BaseActivity).requestPermissions(permissions) { _, grantResults ->
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
downloadAllMedia(status)
} else {
Toast.makeText(
context,
R.string.error_media_download_permission,
Toast.LENGTH_SHORT
).show()
}
}
pendingMediaDownloads = mediaUrls
downloadAllMediaPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
} else {
downloadAllMedia(status)
downloadAllMedia(mediaUrls)
}
}
companion object {
private const val TAG = "SFragment"
private const val PENDING_MEDIA_DOWNLOADS_STATE_KEY = "pending_media_downloads"
private fun accountIsInMentions(
account: AccountEntity?,
mentions: List<Status.Mention>