mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 09:20:19 +01:00
Fix missing toast message after write external storage permission is denied while saving an attachment.
`AttachmentSaver` was missing logic to show a toast message after the user denies `WRITE_EXTERNAL_STORAGE` permission. #### Changeset - Add missing toast after write external storage permission is denied. - Add unit test coverage for `AttachmentSaver` result messages. - Rename `AttachmentSaver` string resource names so they all have the same prefix.
This commit is contained in:
committed by
Cody Henthorne
parent
b6f98521c8
commit
0f72c6face
@@ -447,9 +447,9 @@ public class SaveAttachmentTask extends ProgressDialogAsyncTask<SaveAttachmentTa
|
||||
} else {
|
||||
new MaterialAlertDialogBuilder(context)
|
||||
.setView(R.layout.dialog_save_attachment)
|
||||
.setTitle(R.string.ConversationFragment__save_to_phone)
|
||||
.setTitle(R.string.AttachmentSaver__save_to_phone)
|
||||
.setCancelable(true)
|
||||
.setMessage(context.getResources().getQuantityString(R.plurals.ConversationFragment__this_media_will_be_saved, count, count))
|
||||
.setMessage(context.getResources().getQuantityString(R.plurals.AttachmentSaver__this_media_will_be_saved, count, count))
|
||||
.setPositiveButton(R.string.save, ((dialog, i) -> {
|
||||
CheckBox checkbox = ((AlertDialog) dialog).findViewById(R.id.checkbox);
|
||||
if (checkbox.isChecked()) {
|
||||
|
||||
@@ -21,6 +21,7 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.signal.core.util.StreamUtil
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.core.util.logging.logI
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority
|
||||
@@ -50,21 +51,20 @@ object SaveAttachmentUtil {
|
||||
check(attachments.isNotEmpty()) { "must pass in at least one attachment" }
|
||||
|
||||
if (!StorageUtil.canWriteToMediaStore()) {
|
||||
return SaveAttachmentsResult.ErrorNoWriteAccess(errorCount = attachments.size)
|
||||
return SaveAttachmentsResult.ErrorNoWriteAccess
|
||||
}
|
||||
|
||||
val nameCache: BatchOperationNameCache = HashMap()
|
||||
|
||||
val (successes, errors) = attachments
|
||||
val (successes, failures) = attachments
|
||||
.map { saveAttachment(it, nameCache) }
|
||||
.partition { saveResult -> saveResult is SaveAttachmentResult.Success }
|
||||
|
||||
return SaveAttachmentsResult.Completed(
|
||||
successCount = successes.size,
|
||||
errorCount = errors.size
|
||||
).also {
|
||||
Log.i(TAG, "Save attachments completed (${it.successCount} of ${attachments.size} saved successfully).")
|
||||
}
|
||||
return when {
|
||||
failures.isEmpty() -> SaveAttachmentsResult.Success(successesCount = successes.size)
|
||||
successes.isEmpty() -> SaveAttachmentsResult.Failure(failuresCount = failures.size)
|
||||
else -> SaveAttachmentsResult.PartialSuccess(successesCount = successes.size, failuresCount = failures.size)
|
||||
}.logI(TAG, "Save attachments completed (${successes.size} of ${attachments.size} saved successfully).")
|
||||
}
|
||||
|
||||
private suspend fun saveAttachment(attachment: SaveAttachment, nameCache: BatchOperationNameCache): SaveAttachmentResult = withContext(Dispatchers.IO) {
|
||||
@@ -284,38 +284,39 @@ object SaveAttachmentUtil {
|
||||
}
|
||||
|
||||
sealed interface SaveAttachmentsResult {
|
||||
val successCount: Int
|
||||
val errorCount: Int
|
||||
|
||||
fun getMessage(context: Context): CharSequence
|
||||
|
||||
data class Completed(
|
||||
override val successCount: Int,
|
||||
override val errorCount: Int
|
||||
) : SaveAttachmentsResult {
|
||||
|
||||
data class Success(val successesCount: Int) : SaveAttachmentsResult {
|
||||
override fun getMessage(context: Context): CharSequence {
|
||||
return when {
|
||||
errorCount == 0 -> context.resources.getQuantityText(R.plurals.SaveAttachment_saved_success, successCount)
|
||||
successCount == 0 -> context.resources.getQuantityText(R.plurals.SaveAttachment_error_while_saving_attachments_to_sd_card, errorCount)
|
||||
else -> {
|
||||
val numberFormat = NumberFormat.getInstance()
|
||||
context.resources.getQuantityString(
|
||||
R.plurals.SaveAttachment_saved_success_n_failures,
|
||||
errorCount,
|
||||
numberFormat.format(errorCount),
|
||||
numberFormat.format(errorCount + successCount)
|
||||
)
|
||||
}
|
||||
}
|
||||
return context.resources.getQuantityText(R.plurals.SaveAttachment_saved_success, successesCount)
|
||||
}
|
||||
}
|
||||
|
||||
data class ErrorNoWriteAccess(
|
||||
override val errorCount: Int
|
||||
) : SaveAttachmentsResult {
|
||||
override val successCount: Int = 0
|
||||
data class PartialSuccess(val successesCount: Int, val failuresCount: Int) : SaveAttachmentsResult {
|
||||
override fun getMessage(context: Context): CharSequence {
|
||||
val numberFormat = NumberFormat.getInstance()
|
||||
return context.resources.getQuantityString(
|
||||
R.plurals.SaveAttachment_saved_success_n_failures,
|
||||
failuresCount,
|
||||
numberFormat.format(failuresCount),
|
||||
numberFormat.format(failuresCount + successesCount)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class Failure(val failuresCount: Int) : SaveAttachmentsResult {
|
||||
override fun getMessage(context: Context): CharSequence {
|
||||
return context.resources.getQuantityText(R.plurals.SaveAttachment_error_while_saving_attachments_to_sd_card, failuresCount)
|
||||
}
|
||||
}
|
||||
|
||||
data object WriteStoragePermissionDenied : SaveAttachmentsResult {
|
||||
override fun getMessage(context: Context): CharSequence {
|
||||
return context.getString(R.string.AttachmentSaver__unable_to_write_to_external_storage_without_permission)
|
||||
}
|
||||
}
|
||||
|
||||
data object ErrorNoWriteAccess : SaveAttachmentsResult {
|
||||
override fun getMessage(context: Context): CharSequence {
|
||||
return context.getString(R.string.SaveAttachment_unable_to_write_to_sd_card_exclamation)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user