Add option to hide save storage warning.
This commit is contained in:
parent
83af313305
commit
f128df7d95
9 changed files with 84 additions and 36 deletions
|
@ -2381,7 +2381,7 @@ class ConversationFragment :
|
|||
|
||||
val attachments = SaveAttachmentUtil.getAttachmentsForRecord(record)
|
||||
|
||||
SaveAttachmentUtil.showWarningDialog(requireContext(), attachments.size) { _, _ ->
|
||||
SaveAttachmentUtil.showWarningDialogIfNecessary(requireContext()) {
|
||||
if (StorageUtil.canWriteToMediaStore()) {
|
||||
performAttachmentSave(attachments)
|
||||
} else {
|
||||
|
|
|
@ -31,6 +31,7 @@ public class UiHintValues extends SignalStoreValues {
|
|||
private static final String HAS_SEEN_CHAT_FOLDERS_EDUCATION_SHEET = "uihints.has_seen_chat_folders_education_sheet";
|
||||
private static final String HAS_SEEN_LINK_DEVICE_QR_EDUCATION_SHEET = "uihints.has_seen_link_device_qr_education_sheet";
|
||||
private static final String HAS_SEEN_LINK_DEVICE_AUTH_SHEET = "uihints.has_seen_link_device_auth_sheet";
|
||||
private static final String HAS_DISMISSED_SAVE_STORAGE_WARNING = "uihints.has_dismissed_save_storage_warning";
|
||||
|
||||
UiHintValues(@NonNull KeyValueStore store) {
|
||||
super(store);
|
||||
|
@ -236,4 +237,12 @@ public class UiHintValues extends SignalStoreValues {
|
|||
public boolean hasSeenLinkDeviceAuthSheet() {
|
||||
return getBoolean(HAS_SEEN_LINK_DEVICE_AUTH_SHEET, false);
|
||||
}
|
||||
|
||||
public boolean hasDismissedSaveStorageWarning() {
|
||||
return getBoolean(HAS_DISMISSED_SAVE_STORAGE_WARNING, false);
|
||||
}
|
||||
|
||||
public void markDismissedSaveStorageWarning() {
|
||||
putBoolean(HAS_DISMISSED_SAVE_STORAGE_WARNING, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,11 +16,9 @@ import org.thoughtcrime.securesms.database.MediaTable;
|
|||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceDeleteSyncJob;
|
||||
import org.thoughtcrime.securesms.permissions.Permissions;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.AttachmentUtil;
|
||||
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
|
||||
import org.thoughtcrime.securesms.util.StorageUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
|
||||
|
||||
|
@ -46,13 +44,13 @@ final class MediaActions {
|
|||
return;
|
||||
}
|
||||
|
||||
SaveAttachmentTask.showWarningDialog(context, (dialogInterface, which) -> Permissions.with(fragment)
|
||||
SaveAttachmentTask.showWarningDialogIfNecessary(context, () -> Permissions.with(fragment)
|
||||
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
.ifNecessary()
|
||||
.withPermanentDenialDialog(fragment.getString(R.string.MediaPreviewActivity_signal_needs_the_storage_permission_in_order_to_write_to_external_storage_but_it_has_been_permanently_denied))
|
||||
.onAnyDenied(() -> Toast.makeText(context, R.string.MediaPreviewActivity_unable_to_write_to_external_storage_without_permission, Toast.LENGTH_LONG).show())
|
||||
.onAllGranted(() -> performSaveToDisk(context, mediaRecords, postExecute))
|
||||
.execute(), mediaRecords.size());
|
||||
.execute());
|
||||
}
|
||||
|
||||
static void handleDeleteMedia(@NonNull Context context,
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.Manifest
|
|||
import android.annotation.SuppressLint
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.PorterDuffColorFilter
|
||||
|
@ -558,10 +557,10 @@ class MediaPreviewV2Fragment : LoggingFragment(R.layout.fragment_media_preview_v
|
|||
}
|
||||
|
||||
private fun saveToDisk(mediaItem: MediaTable.MediaRecord) {
|
||||
SaveAttachmentTask.showWarningDialog(requireContext()) { _: DialogInterface?, _: Int ->
|
||||
SaveAttachmentTask.showWarningDialogIfNecessary(requireContext()) {
|
||||
if (StorageUtil.canWriteToMediaStore()) {
|
||||
performSaveToDisk(mediaItem)
|
||||
return@showWarningDialog
|
||||
return@showWarningDialogIfNecessary
|
||||
}
|
||||
Permissions.with(this)
|
||||
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
|
|
|
@ -653,7 +653,7 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
|||
|
||||
@Override
|
||||
public void onSave() {
|
||||
SaveAttachmentTask.showWarningDialog(requireContext(), (dialogInterface, i) -> {
|
||||
SaveAttachmentTask.showWarningDialogIfNecessary(requireContext(), () -> {
|
||||
if (StorageUtil.canWriteToMediaStore()) {
|
||||
performSaveToDisk();
|
||||
return;
|
||||
|
|
|
@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.util;
|
|||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.database.Cursor;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.net.Uri;
|
||||
|
@ -11,6 +10,7 @@ import android.os.Build;
|
|||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -24,6 +24,7 @@ import org.signal.core.util.StreamUtil;
|
|||
import org.signal.core.util.logging.Log;
|
||||
import org.signal.libsignal.protocol.util.Pair;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
|
||||
|
||||
|
@ -434,20 +435,25 @@ public class SaveAttachmentTask extends ProgressDialogAsyncTask<SaveAttachmentTa
|
|||
}
|
||||
}
|
||||
|
||||
public static void showWarningDialog(Context context, OnClickListener onAcceptListener) {
|
||||
showWarningDialog(context, onAcceptListener, 1);
|
||||
public static void showWarningDialogIfNecessary(Context context, Runnable onSave) {
|
||||
if (SignalStore.uiHints().hasDismissedSaveStorageWarning()) {
|
||||
onSave.run();
|
||||
} else {
|
||||
new MaterialAlertDialogBuilder(context)
|
||||
.setView(R.layout.dialog_save_attachment)
|
||||
.setTitle(R.string.ConversationFragment__save_to_phone)
|
||||
.setCancelable(true)
|
||||
.setMessage(R.string.ConversationFragment__this_media_will_be_saved)
|
||||
.setPositiveButton(R.string.save, ((dialog, i) -> {
|
||||
CheckBox checkbox = ((AlertDialog) dialog).findViewById(R.id.checkbox);
|
||||
if (checkbox.isChecked()) {
|
||||
SignalStore.uiHints().markDismissedSaveStorageWarning();
|
||||
}
|
||||
onSave.run();
|
||||
}))
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
public static void showWarningDialog(Context context, OnClickListener onAcceptListener, int count) {
|
||||
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
|
||||
builder.setTitle(R.string.ConversationFragment_save_to_sd_card);
|
||||
builder.setIcon(R.drawable.symbol_error_triangle_fill_24);
|
||||
builder.setCancelable(true);
|
||||
builder.setMessage(context.getResources().getQuantityString(R.plurals.ConversationFragment_saving_n_media_to_storage_warning,
|
||||
count, count));
|
||||
builder.setPositiveButton(R.string.yes, onAcceptListener);
|
||||
builder.setNegativeButton(R.string.no, null);
|
||||
builder.show();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import android.annotation.SuppressLint
|
|||
import android.content.ContentResolver
|
||||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface.OnClickListener
|
||||
import android.database.Cursor
|
||||
import android.media.MediaScannerConnection
|
||||
import android.net.Uri
|
||||
|
@ -17,8 +16,10 @@ import android.os.Build
|
|||
import android.os.Environment
|
||||
import android.provider.MediaStore
|
||||
import android.webkit.MimeTypeMap
|
||||
import android.widget.CheckBox
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.WorkerThread
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.content.contentValuesOf
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
|
@ -28,6 +29,7 @@ import org.signal.core.util.orNull
|
|||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
|
@ -52,16 +54,26 @@ object SaveAttachmentUtil {
|
|||
|
||||
private val TAG = Log.tag(SaveAttachmentUtil::class.java)
|
||||
|
||||
fun showWarningDialog(context: Context, count: Int, onAcceptListener: OnClickListener) {
|
||||
fun showWarningDialogIfNecessary(context: Context, onSave: () -> Unit) {
|
||||
if (SignalStore.uiHints.hasDismissedSaveStorageWarning()) {
|
||||
onSave()
|
||||
} else {
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.ConversationFragment_save_to_sd_card)
|
||||
.setIcon(R.drawable.symbol_error_triangle_fill_24)
|
||||
.setView(R.layout.dialog_save_attachment)
|
||||
.setTitle(R.string.ConversationFragment__save_to_phone)
|
||||
.setCancelable(true)
|
||||
.setMessage(context.resources.getQuantityString(R.plurals.ConversationFragment_saving_n_media_to_storage_warning, count, count))
|
||||
.setPositiveButton(R.string.yes, onAcceptListener)
|
||||
.setNegativeButton(R.string.no, null)
|
||||
.setMessage(R.string.ConversationFragment__this_media_will_be_saved)
|
||||
.setPositiveButton(R.string.save) { dialog, _ ->
|
||||
val checkbox = (dialog as AlertDialog).findViewById<CheckBox>(R.id.checkbox)!!
|
||||
if (checkbox.isChecked) {
|
||||
SignalStore.uiHints.markDismissedSaveStorageWarning()
|
||||
}
|
||||
onSave()
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
fun getAttachmentsForRecord(record: MmsMessageRecord): Set<SaveAttachment> {
|
||||
return record.slideDeck.slides
|
||||
|
|
18
app/src/main/res/layout/dialog_save_attachment.xml
Normal file
18
app/src/main/res/layout/dialog_save_attachment.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatCheckBox
|
||||
android:id="@+id/checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ConversationFragment_dont_show_again"
|
||||
style="@style/Signal.Text.BodyMedium"
|
||||
android:textColor="@color/signal_colorOnSurfaceVariant"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginTop="12dp" />
|
||||
|
||||
</FrameLayout>
|
|
@ -586,6 +586,12 @@
|
|||
<item quantity="one">Saving attachment to storage…</item>
|
||||
<item quantity="other">Saving %1$d attachments to storage…</item>
|
||||
</plurals>
|
||||
<!-- Dialog title asking to save media to your phone's storage -->
|
||||
<string name="ConversationFragment__save_to_phone">Save to phone?</string>
|
||||
<!-- Dialog message explaining that media will be saved to your phone and can potentially be accessed by other phones. -->
|
||||
<string name="ConversationFragment__this_media_will_be_saved">This media will be saved to your phone\'s storage. Other apps may be able to access it depending on your phone\'s permissions.</string>
|
||||
<!-- Checkbox shown in dialog to not show the dialog again in future cases -->
|
||||
<string name="ConversationFragment_dont_show_again">Don\'t show again</string>
|
||||
<string name="ConversationFragment_pending">Pending…</string>
|
||||
<!-- Describes how the message was sent when looking at a message detail. Previously, messages could be through other means like SMS -->
|
||||
<string name="ConversationFragment_push">Data (Signal)</string>
|
||||
|
|
Loading…
Add table
Reference in a new issue