Option to hide media from gallery

Stephen Paul Weber created

Change summary

src/cheogram/res/drawable/browse_24dp.xml                                | 10 
src/main/java/eu/siacs/conversations/persistance/FileBackend.java        | 20 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java |  2 
src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java       | 19 
src/main/res/values/defaults.xml                                         |  1 
src/main/res/xml/preferences_attachments.xml                             |  6 
6 files changed, 58 insertions(+)

Detailed changes

src/cheogram/res/drawable/browse_24dp.xml 🔗

@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="960"
+    android:viewportHeight="960"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M120,520L120,200Q120,167 143.5,143.5Q167,120 200,120L440,120L440,520L120,520ZM520,120L760,120Q793,120 816.5,143.5Q840,167 840,200L840,360L520,360L520,120ZM520,840L520,440L840,440L840,760Q840,793 816.5,816.5Q793,840 760,840L520,840ZM120,600L440,600L440,840L200,840Q167,840 143.5,816.5Q120,793 120,760L120,600Z"/>
+</vector>

src/main/java/eu/siacs/conversations/persistance/FileBackend.java 🔗

@@ -1099,6 +1099,26 @@ public class FileBackend {
         }
     }
 
+    public void setupNomedia(final boolean nomedia) {
+        final var pictures = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
+        final var app = mXmppConnectionService.getString(R.string.app_name);
+        final var picturesNomedia = new File(new File(pictures, app), ".nomedia");
+        final var movies = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
+        final var moviesNomedia = new File(new File(movies, app), ".nomedia");
+        var rescan = false;
+        if (nomedia) {
+            rescan = rescan || picturesNomedia.mkdir();
+            rescan = rescan || moviesNomedia.mkdir();
+        } else {
+            rescan = rescan || picturesNomedia.delete();
+            rescan = rescan || moviesNomedia.delete();
+        }
+        if (rescan) {
+            updateMediaScanner(new File(pictures, app));
+            updateMediaScanner(new File(movies, app));
+        }
+    }
+
     public static boolean inConversationsDirectory(final Context context, String path) {
         final File fileDirectory = new File(path).getParentFile();
         for (final String type : STORAGE_TYPES) {

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -804,6 +804,8 @@ public class XmppConnectionService extends Service {
 
     @Override
     public int onStartCommand(final Intent intent, int flags, int startId) {
+        final var nomedia = getBooleanPreference("nomedia", R.bool.default_nomedia);
+        fileBackend.setupNomedia(nomedia);
         final String action = Strings.nullToEmpty(intent == null ? null : intent.getAction());
         final boolean needsForegroundService = intent != null && intent.getBooleanExtra(SystemEventReceiver.EXTRA_NEEDS_FOREGROUND_SERVICE, false);
         if (needsForegroundService) {

src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java 🔗

@@ -732,6 +732,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
             if (offerToDownloadStickers()) return;
             if (openBatteryOptimizationDialogIfNeeded()) return;
             if (requestNotificationPermissionIfNeeded()) return;
+            if (askAboutNomedia()) return;
             xmppConnectionService.rescanStickers();
         }
     }
@@ -777,6 +778,24 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
         return false;
     }
 
+    private boolean askAboutNomedia() {
+        if (getPreferences().contains("nomedia")) return false;
+
+        AlertDialog.Builder builder = new AlertDialog.Builder(this);
+        builder.setTitle("Show media in gallery");
+        builder.setMessage("Would you like to show received and sent media in your system gallery?");
+        builder.setPositiveButton(R.string.yes, (dialog, which) -> {
+            getPreferences().edit().putBoolean("nomedia", false).apply();
+        });
+        builder.setNegativeButton(R.string.no, (dialog, which) -> {
+            getPreferences().edit().putBoolean("nomedia", true).apply();
+        });
+        final AlertDialog dialog = builder.create();
+        dialog.setCanceledOnTouchOutside(false);
+        dialog.show();
+        return true;
+    }
+
     private boolean offerToDownloadStickers() {
         int offered = getPreferences().getInt("default_stickers_offered", 0);
         if (offered > 0) return false;

src/main/res/values/defaults.xml 🔗

@@ -57,4 +57,5 @@
     <bool name="auto_accept_unmetered">true</bool>
     <string name="default_chat_requests">spam</string>
     <bool name="default_custom_tab">true</bool>
+    <bool name="default_nomedia">true</bool>
 </resources>

src/main/res/xml/preferences_attachments.xml 🔗

@@ -32,6 +32,12 @@
             android:key="auto_accept_unmetered"
             android:title="Always Accept When Unmetered"
             android:summary="Don't use the above size limit on unmetered networks" />
+        <SwitchPreferenceCompat
+            android:defaultValue="@bool/default_nomedia"
+            android:icon="@drawable/browse_24dp"
+            android:key="nomedia"
+            android:title="Hide media in gallery"
+            android:summary="Hide received and sent media from system gallery views" />
     </PreferenceCategory>
     <PreferenceCategory android:title="Advanced">
         <Preference