Browse Source

wip

Signed-off-by: tobiasKaminsky <tobias@kaminsky.me>
tobiasKaminsky 4 years ago
parent
commit
a470bd1f56
26 changed files with 537 additions and 270 deletions
  1. 2 8
      src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java
  2. 0 12
      src/main/java/com/owncloud/android/datamodel/OCFile.java
  3. 2 3
      src/main/java/com/owncloud/android/db/ProviderMeta.java
  4. 0 1
      src/main/java/com/owncloud/android/operations/CreateShareViaLinkOperation.java
  5. 0 1
      src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java
  6. 0 1
      src/main/java/com/owncloud/android/operations/SynchronizeFolderOperation.java
  7. 0 1
      src/main/java/com/owncloud/android/operations/UnshareOperation.java
  8. 6 0
      src/main/java/com/owncloud/android/operations/UpdateShareViaLinkOperation.java
  9. 20 6
      src/main/java/com/owncloud/android/providers/FileContentProvider.java
  10. 6 0
      src/main/java/com/owncloud/android/services/OperationsService.java
  11. 4 4
      src/main/java/com/owncloud/android/ui/activity/FileActivity.java
  12. 1 1
      src/main/java/com/owncloud/android/ui/activity/ShareActivity.java
  13. 74 0
      src/main/java/com/owncloud/android/ui/adapter/InternalShareViewHolder.java
  14. 47 0
      src/main/java/com/owncloud/android/ui/adapter/NewLinkShareViewHolder.java
  15. 37 6
      src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapter.java
  16. 4 0
      src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapterListener.java
  17. 1 0
      src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java
  18. 92 78
      src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java
  19. 10 0
      src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java
  20. 67 0
      src/main/res/layout/file_details_share_internal_share_link.xml
  21. 1 2
      src/main/res/layout/file_details_share_public_link_add_new_item.xml
  22. 21 25
      src/main/res/layout/file_details_share_share_item.xml
  23. 63 119
      src/main/res/layout/file_details_sharing_fragment.xml
  24. 68 0
      src/main/res/menu/fragment_file_detail_sharing_email_link.xml
  25. 10 1
      src/main/res/menu/fragment_file_detail_sharing_public_link.xml
  26. 1 1
      src/main/res/values/dims.xml

+ 2 - 8
src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java

@@ -230,7 +230,6 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, ocFile.getEtagOnServer());
         cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, ocFile.isSharedViaLink() ? 1 : 0);
         cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, ocFile.isSharedWithSharee() ? 1 : 0);
-        cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, ocFile.getPublicLink());
         cv.put(ProviderTableMeta.FILE_PERMISSIONS, ocFile.getPermissions());
         cv.put(ProviderTableMeta.FILE_REMOTE_ID, ocFile.getRemoteId());
         cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, ocFile.isUpdateThumbnailNeeded());
@@ -485,7 +484,6 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, folder.getEtagOnServer());
         cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, folder.isSharedViaLink() ? 1 : 0);
         cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, folder.isSharedWithSharee() ? 1 : 0);
-        cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, folder.getPublicLink());
         cv.put(ProviderTableMeta.FILE_PERMISSIONS, folder.getPermissions());
         cv.put(ProviderTableMeta.FILE_REMOTE_ID, folder.getRemoteId());
         cv.put(ProviderTableMeta.FILE_FAVORITE, folder.isFavorite());
@@ -520,7 +518,6 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, file.getEtagOnServer());
         cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, file.isSharedViaLink() ? 1 : 0);
         cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, file.isSharedWithSharee() ? 1 : 0);
-        cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
         cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions());
         cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
         cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.isUpdateThumbnailNeeded());
@@ -1006,7 +1003,6 @@ public class FileDataStorageManager {
             ocFile.setEtagOnServer(cursor.getString(cursor.getColumnIndex(ProviderTableMeta.FILE_ETAG_ON_SERVER)));
             ocFile.setSharedViaLink(cursor.getInt(cursor.getColumnIndex(ProviderTableMeta.FILE_SHARED_VIA_LINK)) == 1);
             ocFile.setSharedWithSharee(cursor.getInt(cursor.getColumnIndex(ProviderTableMeta.FILE_SHARED_WITH_SHAREE)) == 1);
-            ocFile.setPublicLink(cursor.getString(cursor.getColumnIndex(ProviderTableMeta.FILE_PUBLIC_LINK)));
             ocFile.setPermissions(cursor.getString(cursor.getColumnIndex(ProviderTableMeta.FILE_PERMISSIONS)));
             ocFile.setRemoteId(cursor.getString(cursor.getColumnIndex(ProviderTableMeta.FILE_REMOTE_ID)));
             ocFile.setUpdateThumbnailNeeded(cursor.getInt(cursor.getColumnIndex(ProviderTableMeta.FILE_UPDATE_THUMBNAIL)) == 1);
@@ -1264,6 +1260,7 @@ public class FileDataStorageManager {
         contentValues.put(ProviderTableMeta.OCSHARES_HIDE_DOWNLOAD, share.isHideFileDownload());
         contentValues.put(ProviderTableMeta.OCSHARES_SHARE_LINK, share.getShareLink());
         contentValues.put(ProviderTableMeta.OCSHARES_SHARE_LABEL, share.getLabel());
+        contentValues.put(ProviderTableMeta.OCSHARES_VIDEO_VERIFICATION, share.isSendPasswordByTalk());
 
         return contentValues;
     }
@@ -1288,6 +1285,7 @@ public class FileDataStorageManager {
         share.setHideFileDownload(getInt(cursor, ProviderTableMeta.OCSHARES_HIDE_DOWNLOAD) == 1);
         share.setShareLink(getString(cursor, ProviderTableMeta.OCSHARES_SHARE_LINK));
         share.setLabel(getString(cursor, ProviderTableMeta.OCSHARES_SHARE_LABEL));
+        share.setSendPasswordByTalk(getInt(cursor, ProviderTableMeta.OCSHARES_VIDEO_VERIFICATION) == 1);
 
         return share;
     }
@@ -1296,7 +1294,6 @@ public class FileDataStorageManager {
         ContentValues cv = new ContentValues();
         cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, Boolean.FALSE);
         cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, Boolean.FALSE);
-        cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, "");
         String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?";
         String[] whereArgs = new String[]{account.name};
 
@@ -1316,7 +1313,6 @@ public class FileDataStorageManager {
         ContentValues contentValues = new ContentValues();
         contentValues.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, Boolean.FALSE);
         contentValues.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, Boolean.FALSE);
-        contentValues.put(ProviderTableMeta.FILE_PUBLIC_LINK, "");
         String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PARENT + " = ?";
         String[] whereArgs = new String[]{account.name, String.valueOf(folder.getFileId())};
 
@@ -1336,7 +1332,6 @@ public class FileDataStorageManager {
         ContentValues contentValues = new ContentValues();
         contentValues.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, Boolean.FALSE);
         contentValues.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, Boolean.FALSE);
-        contentValues.put(ProviderTableMeta.FILE_PUBLIC_LINK, "");
         String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PATH + " = ?";
         String[] whereArgs = new String[]{account.name, filePath};
 
@@ -1447,7 +1442,6 @@ public class FileDataStorageManager {
                 cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, file.getEtagOnServer());
                 cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, file.isSharedViaLink() ? 1 : 0);
                 cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, file.isSharedWithSharee() ? 1 : 0);
-                cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
                 cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions());
                 cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
                 cv.put(ProviderTableMeta.FILE_FAVORITE, file.isFavorite());

+ 0 - 12
src/main/java/com/owncloud/android/datamodel/OCFile.java

@@ -75,7 +75,6 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
     private String etag;
     private String etagOnServer;
     private boolean sharedViaLink;
-    private String publicLink;
     private String permissions;
     private String remoteId; // The fileid namespaced by the instance fileId, globally unique
     private boolean updateThumbnailNeeded;
@@ -150,7 +149,6 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
         etag = source.readString();
         etagOnServer = source.readString();
         sharedViaLink = source.readInt() == 1;
-        publicLink = source.readString();
         permissions = source.readString();
         remoteId = source.readString();
         updateThumbnailNeeded = source.readInt() == 1;
@@ -184,7 +182,6 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
         dest.writeString(etag);
         dest.writeString(etagOnServer);
         dest.writeInt(sharedViaLink ? 1 : 0);
-        dest.writeString(publicLink);
         dest.writeString(permissions);
         dest.writeString(remoteId);
         dest.writeInt(updateThumbnailNeeded ? 1 : 0);
@@ -450,7 +447,6 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
         etag = null;
         etagOnServer = null;
         sharedViaLink = false;
-        publicLink = null;
         permissions = null;
         remoteId = null;
         updateThumbnailNeeded = false;
@@ -646,10 +642,6 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
         return this.sharedViaLink;
     }
 
-    public String getPublicLink() {
-        return this.publicLink;
-    }
-
     public String getPermissions() {
         return this.permissions;
     }
@@ -758,10 +750,6 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
         this.sharedViaLink = sharedViaLink;
     }
 
-    public void setPublicLink(String publicLink) {
-        this.publicLink = publicLink;
-    }
-
     public void setPermissions(String permissions) {
         this.permissions = permissions;
     }

+ 2 - 3
src/main/java/com/owncloud/android/db/ProviderMeta.java

@@ -35,7 +35,7 @@ import java.util.List;
  */
 public class ProviderMeta {
     public static final String DB_NAME = "filelist";
-    public static final int DB_VERSION = 59;
+    public static final int DB_VERSION = 60;
 
     private ProviderMeta() {
         // No instance
@@ -102,7 +102,6 @@ public class ProviderMeta {
         public static final String FILE_ETAG_ON_SERVER = "etag_on_server";
         public static final String FILE_SHARED_VIA_LINK = "share_by_link";
         public static final String FILE_SHARED_WITH_SHAREE = "shared_via_users";
-        public static final String FILE_PUBLIC_LINK = "public_link";
         public static final String FILE_PERMISSIONS = "permissions";
         public static final String FILE_REMOTE_ID = "remote_id";
         public static final String FILE_UPDATE_THUMBNAIL = "update_thumbnail";
@@ -137,7 +136,6 @@ public class ProviderMeta {
             FILE_ETAG_ON_SERVER,
             FILE_SHARED_VIA_LINK,
             FILE_SHARED_WITH_SHAREE,
-            FILE_PUBLIC_LINK,
             FILE_PERMISSIONS,
             FILE_REMOTE_ID,
             FILE_UPDATE_THUMBNAIL,
@@ -173,6 +171,7 @@ public class ProviderMeta {
         public static final String OCSHARES_HIDE_DOWNLOAD = "hide_download";
         public static final String OCSHARES_SHARE_LINK = "share_link";
         public static final String OCSHARES_SHARE_LABEL = "share_label";
+        public static final String OCSHARES_VIDEO_VERIFICATION = "video_verification";
 
         public static final String OCSHARES_DEFAULT_SORT_ORDER = OCSHARES_FILE_SOURCE
                 + " collate nocase asc";

+ 0 - 1
src/main/java/com/owncloud/android/operations/CreateShareViaLinkOperation.java

@@ -88,7 +88,6 @@ public class CreateShareViaLinkOperation extends SyncOperation {
         // Update OCFile with data from share: ShareByLink  and publicLink
         OCFile file = getStorageManager().getFileByEncryptedRemotePath(path);
         if (file != null) {
-            file.setPublicLink(share.getShareLink());
             file.setSharedViaLink(true);
             getStorageManager().saveFile(file);
         }

+ 0 - 1
src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java

@@ -576,7 +576,6 @@ public class RefreshFolderOperation extends RemoteOperation {
                 Log.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server");
             }
 
-            updatedFile.setPublicLink(localFile.getPublicLink());
             updatedFile.setSharedViaLink(localFile.isSharedViaLink());
             updatedFile.setSharedWithSharee(localFile.isSharedWithSharee());
         } else {

+ 0 - 1
src/main/java/com/owncloud/android/operations/SynchronizeFolderOperation.java

@@ -360,7 +360,6 @@ public class SynchronizeFolderOperation extends SyncOperation {
                 updatedFile.setUpdateThumbnailNeeded(true);
                 Log.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server");
             }
-            updatedFile.setPublicLink(localFile.getPublicLink());
             updatedFile.setSharedViaLink(localFile.isSharedViaLink());
             updatedFile.setSharedWithSharee(localFile.isSharedWithSharee());
             updatedFile.setEtagInConflict(localFile.getEtagInConflict());

+ 0 - 1
src/main/java/com/owncloud/android/operations/UnshareOperation.java

@@ -68,7 +68,6 @@ public class UnshareOperation extends SyncOperation {
 
                 if (ShareType.PUBLIC_LINK.equals(share.getShareType())) {
                     file.setSharedViaLink(false);
-                    file.setPublicLink("");
                 } else if (ShareType.USER.equals(share.getShareType()) || ShareType.GROUP.equals(share.getShareType())
                     || ShareType.FEDERATED.equals(share.getShareType())) {
                     // Check if it is the last share

+ 6 - 0
src/main/java/com/owncloud/android/operations/UpdateShareViaLinkOperation.java

@@ -39,6 +39,7 @@ public class UpdateShareViaLinkOperation extends SyncOperation {
      */
     private boolean publicUpload;
     private Boolean hideFileDownload;
+    private Boolean videoVerification;
     private long expirationDateInMillis;
     private long shareId;
     private String label;
@@ -56,6 +57,7 @@ public class UpdateShareViaLinkOperation extends SyncOperation {
         updateOp.setPassword(password);
         updateOp.setExpirationDate(expirationDateInMillis);
         updateOp.setHideFileDownload(hideFileDownload);
+        updateOp.setVideoVerification(videoVerification);
         updateOp.setLabel(label);
 
         if (publicShare.isFolder()) {
@@ -102,4 +104,8 @@ public class UpdateShareViaLinkOperation extends SyncOperation {
     public void setLabel(String label) {
         this.label = label;
     }
+
+    public void setVideoVerification(Boolean enabled) {
+        this.videoVerification = enabled;
+    }
 }

+ 20 - 6
src/main/java/com/owncloud/android/providers/FileContentProvider.java

@@ -708,7 +708,6 @@ public class FileContentProvider extends ContentProvider {
                        + ProviderTableMeta.FILE_ETAG + TEXT
                        + ProviderTableMeta.FILE_ETAG_ON_SERVER + TEXT
                        + ProviderTableMeta.FILE_SHARED_VIA_LINK + INTEGER
-                       + ProviderTableMeta.FILE_PUBLIC_LINK + TEXT
                        + ProviderTableMeta.FILE_PERMISSIONS + " TEXT null,"
                        + ProviderTableMeta.FILE_REMOTE_ID + " TEXT null,"
                        + ProviderTableMeta.FILE_UPDATE_THUMBNAIL + INTEGER //boolean
@@ -749,7 +748,8 @@ public class FileContentProvider extends ContentProvider {
                        + ProviderTableMeta.OCSHARES_NOTE + TEXT
                        + ProviderTableMeta.OCSHARES_HIDE_DOWNLOAD + INTEGER
                        + ProviderTableMeta.OCSHARES_SHARE_LINK + TEXT
-                       + ProviderTableMeta.OCSHARES_SHARE_LABEL + " TEXT );");
+                       + ProviderTableMeta.OCSHARES_SHARE_LABEL + TEXT
+                       + ProviderTableMeta.OCSHARES_VIDEO_VERIFICATION + " INTEGER );");
     }
 
     private void createCapabilitiesTable(SQLiteDatabase db) {
@@ -1148,10 +1148,6 @@ public class FileContentProvider extends ContentProvider {
                                    ADD_COLUMN + ProviderTableMeta.FILE_SHARED_VIA_LINK + " INTEGER " +
                                    " DEFAULT 0");
 
-                    db.execSQL(ALTER_TABLE + ProviderTableMeta.FILE_TABLE_NAME +
-                                   ADD_COLUMN + ProviderTableMeta.FILE_PUBLIC_LINK + " TEXT " +
-                                   " DEFAULT NULL");
-
                     // Create table OCShares
                     createOCSharesTable(db);
 
@@ -2271,6 +2267,24 @@ public class FileContentProvider extends ContentProvider {
             if (!upgraded) {
                 Log_OC.i(SQL, String.format(Locale.ENGLISH, UPGRADE_VERSION_MSG, oldVersion, newVersion));
             }
+
+            if (oldVersion < 60 && newVersion >= 60) {
+                Log_OC.i(SQL, "Entering in the #60 add video verification to share table");
+                db.beginTransaction();
+                try {
+                    db.execSQL(ALTER_TABLE + ProviderTableMeta.OCSHARES_TABLE_NAME +
+                                   ADD_COLUMN + ProviderTableMeta.OCSHARES_VIDEO_VERIFICATION + " INTEGER ");
+
+                    upgraded = true;
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                }
+            }
+
+            if (!upgraded) {
+                Log_OC.i(SQL, String.format(Locale.ENGLISH, UPGRADE_VERSION_MSG, oldVersion, newVersion));
+            }
         }
     }
 }

+ 6 - 0
src/main/java/com/owncloud/android/services/OperationsService.java

@@ -106,6 +106,7 @@ public class OperationsService extends Service {
     public static final String EXTRA_SHARE_PUBLIC_UPLOAD = "SHARE_PUBLIC_UPLOAD";
     public static final String EXTRA_SHARE_PUBLIC_LABEL = "SHARE_PUBLIC_LABEL";
     public static final String EXTRA_SHARE_HIDE_FILE_DOWNLOAD = "HIDE_FILE_DOWNLOAD";
+    public static final String EXTRA_SHARE_VIDEO_VERIFICATION = "VIDEO_VERIFICATION";
     public static final String EXTRA_SHARE_ID = "SHARE_ID";
     public static final String EXTRA_SHARE_NOTE = "SHARE_NOTE";
     public static final String EXTRA_IN_BACKGROUND = "IN_BACKGROUND";
@@ -553,6 +554,11 @@ public class OperationsService extends Service {
                                                                                        false);
                             updateLinkOperation.setHideFileDownload(hideFileDownload);
 
+                            boolean videoVerificationEnabled =
+                                operationIntent.getBooleanExtra(EXTRA_SHARE_VIDEO_VERIFICATION, false);
+
+                            updateLinkOperation.setVideoVerification(videoVerificationEnabled);
+
                             if (operationIntent.hasExtra(EXTRA_SHARE_PUBLIC_UPLOAD)) {
                                 updateLinkOperation.setPublicUpload(true);
                             }

+ 4 - 4
src/main/java/com/owncloud/android/ui/activity/FileActivity.java

@@ -746,7 +746,7 @@ public abstract class FileActivity extends DrawerActivity
 
         if (result.isSuccess()) {
             if (sharingFragment != null) {
-                sharingFragment.refreshPublicShareFromDB();
+                sharingFragment.refreshSharesFromDB();
                 sharingFragment.onUpdateShareInformation(result, getFile());
             }
         } else {
@@ -761,7 +761,7 @@ public abstract class FileActivity extends DrawerActivity
         if (result.isSuccess()) {
             updateFileFromDB();
             if (sharingFragment != null) {
-                sharingFragment.refreshPublicShareFromDB();
+                sharingFragment.refreshSharesFromDB();
                 sharingFragment.onUpdateShareInformation(result, getFile());
             }
         } else if (sharingFragment != null && sharingFragment.getView() != null) {
@@ -807,7 +807,7 @@ public abstract class FileActivity extends DrawerActivity
             copyAndShareFileLink(this, file, link);
 
             if (sharingFragment != null) {
-                sharingFragment.refreshPublicShareFromDB();
+                sharingFragment.refreshSharesFromDB();
                 sharingFragment.onUpdateShareInformation(result, getFile());
             }
         } else {
@@ -828,7 +828,7 @@ public abstract class FileActivity extends DrawerActivity
 
             } else {
                 if (sharingFragment != null) {
-                    sharingFragment.refreshPublicShareFromDB();
+                    sharingFragment.refreshSharesFromDB();
                 }
                 Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content),
                                                   ErrorMessageAdapter.getErrorCauseMessage(result,

+ 1 - 1
src/main/java/com/owncloud/android/ui/activity/ShareActivity.java

@@ -146,7 +146,7 @@ public class ShareActivity extends FileActivity {
                 && shareFileFragment.isAdded()) {   // only if added to the view hierarchy!!
             shareFileFragment.refreshCapabilitiesFromDB();
             //shareFileFragment.refrefreshUsersOrGroupsListFromDB();
-            shareFileFragment.refreshPublicShareFromDB();
+            shareFileFragment.refreshSharesFromDB();
         }
     }
 

+ 74 - 0
src/main/java/com/owncloud/android/ui/adapter/InternalShareViewHolder.java

@@ -0,0 +1,74 @@
+/*
+ *
+ * Nextcloud Android client application
+ *
+ * @author Tobias Kaminsky
+ * Copyright (C) 2020 Tobias Kaminsky
+ * Copyright (C) 2020 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package com.owncloud.android.ui.adapter;
+
+import android.content.Context;
+import android.graphics.PorterDuff;
+import android.view.View;
+
+import com.owncloud.android.R;
+import com.owncloud.android.databinding.FileDetailsShareInternalShareLinkBinding;
+import com.owncloud.android.lib.resources.shares.OCShare;
+
+import androidx.annotation.NonNull;
+import androidx.core.content.res.ResourcesCompat;
+import androidx.recyclerview.widget.RecyclerView;
+
+class InternalShareViewHolder extends RecyclerView.ViewHolder {
+    private FileDetailsShareInternalShareLinkBinding binding;
+    private Context context;
+
+    public InternalShareViewHolder(@NonNull View itemView) {
+        super(itemView);
+    }
+
+    public InternalShareViewHolder(FileDetailsShareInternalShareLinkBinding binding, Context context) {
+        this(binding.getRoot());
+        this.binding = binding;
+        this.context = context;
+    }
+
+    public void bind(OCShare share, ShareeListAdapterListener listener) {
+        binding.copyInternalLinkIcon
+            .getBackground()
+            .setColorFilter(ResourcesCompat.getColor(context.getResources(),
+                                                     R.color.grey_db,
+                                                     null),
+                            PorterDuff.Mode.SRC_IN);
+        binding.copyInternalLinkIcon
+            .getDrawable()
+            .mutate()
+            .setColorFilter(ResourcesCompat.getColor(context.getResources(),
+                                                     R.color.black,
+                                                     null),
+                            PorterDuff.Mode.SRC_IN);
+
+        if (share.isFolder()) {
+            binding.shareInternalLinkText.setText(context.getString(R.string.share_internal_link_to_folder_text));
+        } else {
+            binding.shareInternalLinkText.setText(context.getString(R.string.share_internal_link_to_file_text));
+        }
+
+        binding.copyInternalContainer.setOnClickListener(l -> listener.copyInternalLink());
+    }
+}

+ 47 - 0
src/main/java/com/owncloud/android/ui/adapter/NewLinkShareViewHolder.java

@@ -0,0 +1,47 @@
+/*
+ *
+ * Nextcloud Android client application
+ *
+ * @author Tobias Kaminsky
+ * Copyright (C) 2020 Tobias Kaminsky
+ * Copyright (C) 2020 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package com.owncloud.android.ui.adapter;
+
+import android.view.View;
+
+import com.owncloud.android.databinding.FileDetailsSharePublicLinkAddNewItemBinding;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+class NewLinkShareViewHolder extends RecyclerView.ViewHolder {
+    private FileDetailsSharePublicLinkAddNewItemBinding binding;
+
+    public NewLinkShareViewHolder(@NonNull View itemView) {
+        super(itemView);
+    }
+
+    public NewLinkShareViewHolder(FileDetailsSharePublicLinkAddNewItemBinding binding) {
+        this(binding.getRoot());
+        this.binding = binding;
+    }
+
+    public void bind(ShareeListAdapterListener listener) {
+        binding.addNewPublicShareLink.setOnClickListener(v -> listener.createPublicShareLink());
+    }
+}

+ 37 - 6
src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapter.java

@@ -32,7 +32,9 @@ import android.view.ViewGroup;
 import android.widget.ImageView;
 
 import com.owncloud.android.R;
+import com.owncloud.android.databinding.FileDetailsShareInternalShareLinkBinding;
 import com.owncloud.android.databinding.FileDetailsShareLinkShareItemBinding;
+import com.owncloud.android.databinding.FileDetailsSharePublicLinkAddNewItemBinding;
 import com.owncloud.android.databinding.FileDetailsShareShareItemBinding;
 import com.owncloud.android.lib.resources.shares.OCShare;
 import com.owncloud.android.lib.resources.shares.ShareType;
@@ -82,10 +84,21 @@ public class ShareeListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
         switch (ShareType.fromValue(viewType)) {
             case PUBLIC_LINK:
             case EMAIL:
-                return new LinkShareViewHolder(FileDetailsShareLinkShareItemBinding.inflate(LayoutInflater.from(context),
-                                                                                            parent,
-                                                                                            false),
-                                               context);
+                return new LinkShareViewHolder(
+                    FileDetailsShareLinkShareItemBinding.inflate(LayoutInflater.from(context),
+                                                                 parent,
+                                                                 false),
+                    context);
+            case NEW_PUBLIC_LINK:
+                return new NewLinkShareViewHolder(
+                    FileDetailsSharePublicLinkAddNewItemBinding.inflate(LayoutInflater.from(context),
+                                                                        parent,
+                                                                        false)
+                );
+            case INTERNAL:
+                return new InternalShareViewHolder(
+                    FileDetailsShareInternalShareLinkBinding.inflate(LayoutInflater.from(context), parent, false),
+                    context);
             default:
                 return new ShareViewHolder(FileDetailsShareShareItemBinding.inflate(LayoutInflater.from(context),
                                                                                     parent,
@@ -105,6 +118,12 @@ public class ShareeListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
         if (holder instanceof LinkShareViewHolder) {
             LinkShareViewHolder publicShareViewHolder = (LinkShareViewHolder) holder;
             publicShareViewHolder.bind(share, listener);
+        } else if (holder instanceof InternalShareViewHolder) {
+            InternalShareViewHolder internalShareViewHolder = (InternalShareViewHolder) holder;
+            internalShareViewHolder.bind(share, listener);
+        } else if (holder instanceof NewLinkShareViewHolder) {
+            NewLinkShareViewHolder newLinkShareViewHolder = (NewLinkShareViewHolder) holder;
+            newLinkShareViewHolder.bind(listener);
         } else {
             ShareViewHolder userViewHolder = (ShareViewHolder) holder;
             userViewHolder.bind(share, listener, userId, avatarRadiusDimension);
@@ -159,7 +178,7 @@ public class ShareeListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
         for (OCShare share : shares) {
             if (ShareType.PUBLIC_LINK == share.getShareType() || ShareType.EMAIL == share.getShareType()) {
                 links.add(share);
-            } else {
+            } else if (share.getShareType() != ShareType.INTERNAL) {
                 users.add(share);
             }
         }
@@ -169,9 +188,21 @@ public class ShareeListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
 
         shares = links;
         shares.addAll(users);
+
+        // add internal share link at end
+        shares.add(new OCShare().setShareType(ShareType.INTERNAL));
     }
 
-    protected List<OCShare> getShares() {
+    public List<OCShare> getShares() {
         return shares;
     }
+
+    public void removeNewPublicShare() {
+        for (OCShare share : shares) {
+            if (share.getShareType() == ShareType.NEW_PUBLIC_LINK) {
+                shares.remove(share);
+                break;
+            }
+        }
+    }
 }

+ 4 - 0
src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapterListener.java

@@ -32,4 +32,8 @@ public interface ShareeListAdapterListener {
     void showLinkOverflowMenu(OCShare publicShare, ImageView overflowMenuShareLink);
 
     void showUserOverflowMenu(OCShare share, ImageView overflowMenu);
+
+    void copyInternalLink();
+
+    void createPublicShareLink();
 }

+ 1 - 0
src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java

@@ -374,6 +374,7 @@ public class FileDetailFragment extends FileFragment implements OnClickListener,
         super.onAttach(context);
         if (context instanceof ToolbarActivity) {
             toolbarActivity = (ToolbarActivity) context;
+            toolbarActivity.hideSortListGroup();
         }
     }
 

+ 92 - 78
src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java

@@ -27,7 +27,6 @@ import android.accounts.AccountManager;
 import android.app.SearchManager;
 import android.content.Context;
 import android.content.res.Resources;
-import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.text.InputType;
@@ -69,6 +68,7 @@ import com.owncloud.android.utils.ClipboardUtil;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.ThemeUtils;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import javax.inject.Inject;
@@ -78,7 +78,6 @@ import androidx.annotation.Nullable;
 import androidx.appcompat.widget.PopupMenu;
 import androidx.fragment.app.Fragment;
 import androidx.recyclerview.widget.LinearLayoutManager;
-import butterknife.OnClick;
 
 public class FileDetailSharingFragment extends Fragment implements ShareeListAdapterListener,
     DisplayUtils.AvatarGenerationListener,
@@ -144,7 +143,7 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
         super.onActivityCreated(savedInstanceState);
 
         refreshCapabilitiesFromDB();
-        refreshPublicShareFromDB();
+        refreshSharesFromDB();
     }
 
     @Override
@@ -155,19 +154,18 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
         fileOperationsHelper = fileActivity.getFileOperationsHelper();
         fileDataStorageManager = fileActivity.getStorageManager();
 
-        setupView();
+        AccountManager accountManager = AccountManager.get(getContext());
+        String userId = accountManager.getUserData(user.toPlatformAccount(),
+                                                   com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
 
-        // todo extract
-        binding.copyInternalLinkIcon.getBackground().setColorFilter(getResources().getColor(R.color.grey_db),
-                                                                    PorterDuff.Mode.SRC_IN);
-        binding.copyInternalLinkIcon.getDrawable().mutate().setColorFilter(getResources().getColor(R.color.black),
-                                                                           PorterDuff.Mode.SRC_IN);
+        binding.sharesList.setAdapter(new ShareeListAdapter(fileActivity,
+                                                            new ArrayList<>(),
+                                                            this,
+                                                            userId));
+        binding.sharesList.setLayoutManager(new LinearLayoutManager(getContext()));
+        binding.sharesList.addItemDecoration(new SimpleListItemDividerDecoration(getContext()));
 
-        if (file.isFolder()) {
-            binding.shareInternalLinkText.setText(getString(R.string.share_internal_link_to_folder_text));
-        } else {
-            binding.shareInternalLinkText.setText(getString(R.string.share_internal_link_to_file_text));
-        }
+        setupView();
 
         return view;
     }
@@ -196,7 +194,7 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
         ThemeUtils.themeSearchView(binding.searchView, requireContext());
 
         if (file.canReshare()) {
-            setShareWithUserInfo();
+            refreshSharesFromDB();
         } else {
             binding.searchView.setQueryHint(getResources().getString(R.string.reshare_not_allowed));
             binding.searchView.setInputType(InputType.TYPE_NULL);
@@ -243,30 +241,7 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
         }
     }
 
-    private void setShareWithUserInfo() {
-        // TODO Refactoring: create a new {@link ShareUserListAdapter} instance with every call should not be needed
-        // to show share with users/groups info
-        // TODO combine this with refreshPublicShareFromDB()
-        List<OCShare> shares = fileDataStorageManager.getSharesWithForAFile(file.getRemotePath(),
-                                                                            user.toPlatformAccount().name);
-        if (shares.size() > 0) {
-            AccountManager accountManager = AccountManager.get(getContext());
-            String userId = accountManager.getUserData(user.toPlatformAccount(),
-                                                       com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
-
-            binding.sharesList.setVisibility(View.VISIBLE);
-            binding.sharesList.setAdapter(new ShareeListAdapter(fileActivity,
-                                                                shares,
-                                                                this,
-                                                                userId));
-            binding.sharesList.setLayoutManager(new LinearLayoutManager(getContext()));
-            binding.sharesList.addItemDecoration(new SimpleListItemDividerDecoration(getContext()));
-        } else {
-            binding.sharesList.setVisibility(View.GONE);
-        }
-    }
-
-    @OnClick(R.id.copy_internal_container)
+    @Override
     public void copyInternalLink() {
         OwnCloudAccount account = accountManager.getCurrentOwnCloudAccount();
 
@@ -282,7 +257,8 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
         return account.getBaseUri() + "/index.php/f/" + file.getLocalId();
     }
 
-    private void createShareLink() {
+    @Override
+    public void createPublicShareLink() {
         if (capabilities != null && (capabilities.getFilesSharingPublicPasswordEnforced().isTrue() ||
             capabilities.getFilesSharingPublicAskForOptionalPassword().isTrue())) {
             // password enforced by server, request to the user before trying to create
@@ -295,22 +271,22 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
         }
     }
 
-    private void showSendLinkTo() {
+    private void showSendLinkTo(OCShare publicShare) {
         if (file.isSharedViaLink()) {
-            if (TextUtils.isEmpty(file.getPublicLink())) {
+            if (TextUtils.isEmpty(publicShare.getShareLink())) {
                 fileOperationsHelper.getFileWithLink(file);
             } else {
-                FileDisplayActivity.showShareLinkDialog(fileActivity, file, file.getPublicLink());
+                FileDisplayActivity.showShareLinkDialog(fileActivity, file, publicShare.getShareLink());
             }
         }
     }
 
     public void copyLink(OCShare share) {
         if (file.isSharedViaLink()) {
-            if (TextUtils.isEmpty(file.getPublicLink())) {
+            if (TextUtils.isEmpty(share.getShareLink())) {
                 fileOperationsHelper.getFileWithLink(file);
             } else {
-                ClipboardUtil.copyToClipboard(getActivity(), file.getPublicLink());
+                ClipboardUtil.copyToClipboard(getActivity(), share.getShareLink());
             }
         }
     }
@@ -389,19 +365,31 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
         }
 
         PopupMenu popup = new PopupMenu(requireContext(), overflowMenuShareLink);
-        popup.inflate(R.menu.fragment_file_detail_sharing_link);
+        if (ShareType.EMAIL == publicShare.getShareType()) {
+            popup.inflate(R.menu.fragment_file_detail_sharing_email_link);
+        } else {
+            popup.inflate(R.menu.fragment_file_detail_sharing_public_link);
+        }
         prepareLinkOptionsMenu(popup.getMenu(), publicShare);
         popup.setOnMenuItemClickListener(menuItem -> linkOptionsItemSelected(menuItem, publicShare));
         popup.show();
     }
 
     private void prepareLinkOptionsMenu(Menu menu, OCShare publicShare) {
-        Resources res = requireContext().getResources();
-//        SharingMenuHelper.setupHideFileListingMenuItem(menu.findItem(R.id.action_hide_file_listing),
-//                                                       file.isFolder(),
-//                                                       menu.findItem(R.id.action_allow_editing).isChecked(),
-//                                                       publicShare.getPermissions());
+        if (publicShare.isFolder()) {
+            menu.setGroupVisible(R.id.folder_permission, true);
+            menu.findItem(R.id.allow_editing).setVisible(false);
+
+            // read only / allow upload and editing / file drop
+            MenuItem readOnly = menu.findItem(R.id.link_share_read_only);
+            MenuItem uploadAndEditing = menu.findItem(R.id.link_share_allow_upload_and_editing);
+            MenuItem fileDrop = menu.findItem(R.id.link_share_file_drop);
+        } else {
+            menu.setGroupVisible(R.id.folder_permission, false);
+            menu.findItem(R.id.allow_editing).setVisible(true);
+        }
 
+        Resources res = requireContext().getResources();
         SharingMenuHelper.setupHideFileDownload(menu.findItem(R.id.action_hide_file_download),
                                                 publicShare.isHideFileDownload(),
                                                 capabilities);
@@ -415,11 +403,18 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
 
         menu.findItem(R.id.action_share_send_note).setVisible(capabilities.getVersion().isNoteOnShareSupported());
 
-//        if (publicShare.getPermissions() > PERMISSION_EDITING_ALLOWED) {
-//            menu.findItem(R.id.action_allow_editing).setChecked(true);
-//        } else {
-//            menu.findItem(R.id.action_allow_editing).setChecked(false);
-//        }
+        MenuItem videoVerification = menu.findItem(R.id.link_share_video_verification);
+        if (videoVerification != null) {
+            videoVerification.setChecked(publicShare.isSendPasswordByTalk());
+
+
+//            -When enabling it:
+//            -If it is for a mail share, you must always set a new password (which is also different from the previous one)
+//                -If it is for a link share, you only need to set a new password if the share didn't have one yet (but you can repeat the previous password)
+//                -When disabling it:
+//            -If it is for a mail share, you must always set a new password (which is also different from the previous one)
+//                -If it is for a link share, you do not need to set a new password
+        }
     }
 
     private boolean userOptionsItemSelected(Menu menu,
@@ -498,10 +493,10 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
                 return true;
             }
             case R.id.action_share_send_link: {
-                if (file.isSharedViaLink() && !TextUtils.isEmpty(file.getPublicLink())) {
-                    FileDisplayActivity.showShareLinkDialog(fileActivity, file, file.getPublicLink());
+                if (file.isSharedViaLink() && !TextUtils.isEmpty(publicShare.getShareLink())) {
+                    FileDisplayActivity.showShareLinkDialog(fileActivity, file, publicShare.getShareLink());
                 } else {
-                    showSendLinkTo();
+                    showSendLinkTo(publicShare);
                 }
                 return true;
             }
@@ -510,11 +505,15 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
                 noteDialog.show(fileActivity.getSupportFragmentManager(), NoteDialogFragment.NOTE_FRAGMENT);
                 return true;
             case R.id.action_add_another_public_share_link:
-                createShareLink();
+                createPublicShareLink();
                 return true;
             case R.id.action_unshare:
                 fileOperationsHelper.unshareShare(file, publicShare);
                 return true;
+            case R.id.link_share_video_verification:
+                item.setChecked(!item.isChecked());
+                fileOperationsHelper.setVideoVerificationToPublicShare(publicShare, item.isChecked());
+                return true;
             default:
                 return super.onOptionsItemSelected(item);
         }
@@ -598,33 +597,48 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
 
     /**
      * Get public link from the DB to fill in the "Share link" section in the UI.
-     *
+     * <p>
      * Takes into account server capabilities before reading database.
      */
-    public void refreshPublicShareFromDB() {
+    public void refreshSharesFromDB() {
+        // TODO check if this is not called too often
+        ShareeListAdapter adapter = ((ShareeListAdapter) binding.sharesList.getAdapter());
+        adapter.getShares().clear();
+
+        // to show share with users/groups info
+        List<OCShare> shares = fileDataStorageManager.getSharesWithForAFile(file.getRemotePath(),
+                                                                            user.toPlatformAccount().name);
+
+        adapter.addShares(shares);
+
         if (FileDetailSharingFragmentHelper.isPublicShareDisabled(capabilities) || !file.canReshare()) {
             return;
         }
 
         // Get public share
-        List<OCShare> shares = fileDataStorageManager.getSharesByPathAndType(file.getRemotePath(),
-                                                                             ShareType.PUBLIC_LINK,
-                                                                             "");
-
-        if (shares.isEmpty()) {
-            binding.fileDetailsSharePublicLinkAddNewItemInclude.addPublicShare.setVisibility(View.VISIBLE);
-            ImageView icon = requireView().findViewById(R.id.copy_internal_link_icon);
-            icon.getBackground().setColorFilter(requireContext()
-                                                    .getResources()
-                                                    .getColor(R.color.primary_button_background_color),
-                                                PorterDuff.Mode.SRC_IN);
-            icon.getDrawable().mutate().setColorFilter(requireContext().getResources().getColor(R.color.black),
-                                                       PorterDuff.Mode.SRC_IN);
-            requireView().findViewById(R.id.add_new_public_share_link).setOnClickListener(v -> createShareLink());
+        List<OCShare> publicShares = fileDataStorageManager.getSharesByPathAndType(file.getRemotePath(),
+                                                                                   ShareType.PUBLIC_LINK,
+                                                                                   "");
+
+
+        if (publicShares.isEmpty() && containsNoNewPublicShare(adapter.getShares())) {
+            publicShares.add(new OCShare().setShareType(ShareType.NEW_PUBLIC_LINK));
         } else {
-            binding.fileDetailsSharePublicLinkAddNewItemInclude.addPublicShare.setVisibility(View.GONE);
-            ((ShareeListAdapter) binding.sharesList.getAdapter()).addShares(shares);
+            adapter.removeNewPublicShare();
+        }
+
+        adapter.addShares(publicShares);
+    }
+
+
+    private boolean containsNoNewPublicShare(List<OCShare> shares) {
+        for (OCShare share : shares) {
+            if (share.getShareType() == ShareType.NEW_PUBLIC_LINK) {
+                return false;
+            }
         }
+
+        return true;
     }
 
     @Override

+ 10 - 0
src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java

@@ -733,6 +733,16 @@ public class FileOperationsHelper {
         queueShareIntent(updateShareIntent);
     }
 
+    public void setVideoVerificationToPublicShare(OCShare share, boolean videoVerificationEnabled) {
+        Intent updateShareIntent = new Intent(fileActivity, OperationsService.class);
+        updateShareIntent.setAction(OperationsService.ACTION_UPDATE_PUBLIC_SHARE);
+        updateShareIntent.putExtra(OperationsService.EXTRA_ACCOUNT, fileActivity.getAccount());
+        updateShareIntent.putExtra(OperationsService.EXTRA_SHARE_ID, share.getId());
+        updateShareIntent.putExtra(OperationsService.EXTRA_SHARE_VIDEO_VERIFICATION, videoVerificationEnabled);
+
+        queueShareIntent(updateShareIntent);
+    }
+
     public void updateNoteToShare(OCShare share, String note) {
         Intent updateShareIntent = new Intent(fileActivity, OperationsService.class);
         updateShareIntent.setAction(OperationsService.ACTION_UPDATE_SHARE_NOTE);

+ 67 - 0
src/main/res/layout/file_details_share_internal_share_link.xml

@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~
+  ~ Nextcloud Android client application
+  ~
+  ~ @author Tobias Kaminsky
+  ~ Copyright (C) 2020 Tobias Kaminsky
+  ~ Copyright (C) 2020 Nextcloud GmbH
+  ~
+  ~ This program is free software: you can redistribute it and/or modify
+  ~ it under the terms of the GNU Affero General Public License as published by
+  ~ the Free Software Foundation, either version 3 of the License, or
+  ~ (at your option) any later version.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  ~ GNU Affero General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Affero General Public License
+  ~ along with this program. If not, see <https://www.gnu.org/licenses/>.
+  -->
+
+<LinearLayout android:id="@+id/copy_internal_container"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    android:orientation="horizontal"
+    android:paddingBottom="@dimen/standard_half_padding"
+    android:paddingEnd="@dimen/standard_padding"
+    android:paddingStart="@dimen/zero"
+    android:paddingTop="@dimen/standard_half_padding"
+    android:layout_weight="1"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <ImageView
+        android:background="@drawable/round_bgnd"
+        android:contentDescription="@string/share"
+        android:id="@+id/copy_internal_link_icon"
+        android:layout_gravity="top"
+        android:layout_height="@dimen/share_icon_size"
+        android:layout_marginEnd="@dimen/standard_margin"
+        android:layout_marginStart="@dimen/standard_margin"
+        android:layout_width="@dimen/share_icon_size"
+        android:padding="@dimen/standard_half_padding"
+        android:src="@drawable/ic_external" />
+
+    <LinearLayout
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/standard_half_margin"
+        android:layout_width="match_parent"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/shareInternalLink"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:text="@string/share_internal_link"
+            android:textColor="@color/text_color" />
+
+        <TextView
+            android:id="@+id/shareInternalLinkText"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            tools:text="@string/share_internal_link_to_folder_text" />
+    </LinearLayout>
+
+</LinearLayout>

+ 1 - 2
src/main/res/layout/file_details_share_public_link_add_new_item.xml

@@ -26,8 +26,7 @@
     android:id="@+id/add_public_share"
     android:layout_width="match_parent"
     android:layout_height="@dimen/standard_list_item_size"
-    android:orientation="horizontal"
-    android:visibility="gone">
+    android:orientation="horizontal">
 
     <ImageView
         android:layout_width="@dimen/share_icon_size"

+ 21 - 25
src/main/res/layout/file_details_share_share_item.xml

@@ -20,8 +20,8 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
     android:orientation="horizontal"
+    android:layout_height="@dimen/standard_list_item_size"
     android:weightSum="1"
     tools:ignore="UseCompoundDrawables">
 
@@ -39,29 +39,25 @@
             android:contentDescription="@string/user_icon"
             android:src="@drawable/ic_user" />
 
-        <TextView
-            android:id="@+id/name"
-            android:layout_width="0dp"
-            android:layout_height="match_parent"
-            android:layout_marginEnd="@dimen/standard_quarter_margin"
-            android:layout_weight="1"
-            android:ellipsize="end"
-            android:gravity="center_vertical"
-            android:singleLine="true"
-            android:text="@string/username"
-            android:textColor="@color/text_color"
-            android:textSize="@dimen/file_details_username_text_size" />
+    <TextView
+        android:id="@+id/name"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:textColor="@color/text_color"
+        android:ellipsize="end"
+        android:singleLine="true"
+        android:layout_weight="1"
+        android:gravity="center_vertical"
+        android:textSize="@dimen/file_details_username_text_size"
+        android:text="@string/username" />
 
-        <ImageView
-            android:id="@+id/overflow_menu"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-            android:layout_marginLeft="@dimen/standard_half_margin"
-            android:layout_marginStart="@dimen/standard_half_margin"
-            android:layout_marginEnd="@dimen/standard_half_margin"
-            android:layout_marginRight="@dimen/standard_half_margin"
-            android:contentDescription="@string/overflow_menu"
-            android:padding="@dimen/standard_half_padding"
-            android:src="@drawable/ic_dots_vertical" />
+    <ImageView
+        android:id="@+id/overflow_menu"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:contentDescription="@string/overflow_menu"
+        android:paddingStart="@dimen/standard_padding"
+        android:paddingEnd="@dimen/standard_padding"
+        android:src="@drawable/ic_dots_vertical" />
 </LinearLayout>

+ 63 - 119
src/main/res/layout/file_details_sharing_fragment.xml

@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
   Nextcloud Android client application
 
   Copyright (C) 2018 Andy Scherzinger
@@ -17,142 +16,87 @@
   You should have received a copy of the GNU Affero General Public
   License along with this program.  If not, see <http://www.gnu.org/licenses/>.
 -->
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
+<LinearLayout android:id="@+id/shareContainer"
+    android:layout_height="wrap_content"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_weight="1">
+    android:orientation="vertical"
+    android:paddingTop="@dimen/standard_eight_padding"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <androidx.appcompat.widget.SearchView
+        style="@style/ownCloud.SearchView"
+        android:hint="@string/share_search"
+        android:id="@+id/searchView"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/standard_margin"
+        android:layout_marginStart="@dimen/standard_quarter_margin"
+        android:layout_width="match_parent" />
 
     <LinearLayout
-        android:id="@+id/shareContainer"
-        android:layout_width="match_parent"
+        android:id="@+id/shared_with_you_container"
         android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:paddingTop="@dimen/standard_eigth_padding">
-
-        <androidx.appcompat.widget.SearchView
-            android:id="@+id/searchView"
-            style="@style/ownCloud.SearchView"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="@dimen/standard_quarter_margin"
-            android:layout_marginEnd="@dimen/standard_margin"
-            android:hint="@string/share_search" />
+        android:layout_marginBottom="@dimen/standard_half_margin"
+        android:layout_width="match_parent"
+        android:orientation="horizontal"
+        android:paddingLeft="@dimen/standard_padding"
+        android:paddingRight="@dimen/standard_padding"
+        android:paddingTop="@dimen/standard_padding">
+
+        <ImageView
+            android:contentDescription="@string/avatar"
+            android:id="@+id/shared_with_you_avatar"
+            android:layout_height="@dimen/user_icon_size"
+            android:layout_width="@dimen/user_icon_size"
+            android:src="@drawable/ic_user" />
 
         <LinearLayout
-            android:id="@+id/shared_with_you_container"
-            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginBottom="@dimen/standard_half_margin"
-            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:orientation="vertical"
             android:paddingLeft="@dimen/standard_padding"
-            android:paddingTop="@dimen/standard_padding"
-            android:paddingRight="@dimen/standard_padding">
+            android:paddingRight="@dimen/standard_padding"
+            android:paddingTop="@dimen/standard_half_padding">
 
-            <ImageView
-                android:id="@+id/shared_with_you_avatar"
-                android:layout_width="@dimen/user_icon_size"
-                android:layout_height="@dimen/user_icon_size"
-                android:contentDescription="@string/avatar"
-                android:src="@drawable/ic_user" />
-
-            <LinearLayout
-                android:layout_width="match_parent"
+            <TextView
+                android:id="@+id/shared_with_you_username"
                 android:layout_height="wrap_content"
-                android:orientation="vertical"
-                android:paddingLeft="@dimen/standard_padding"
-                android:paddingTop="@dimen/standard_half_padding"
-                android:paddingRight="@dimen/standard_padding">
-
-                <TextView
-                    android:id="@+id/shared_with_you_username"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:text="@string/shared_with_you_by"
-                    android:textSize="16sp" />
-
-                <LinearLayout
-                    android:id="@+id/shared_with_you_note_container"
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    android:orientation="horizontal"
-                    android:paddingTop="@dimen/standard_half_padding"
-                    tools:ignore="UseCompoundDrawables">
-
-                    <ImageView
-                        android:layout_width="16dp"
-                        android:layout_height="16dp"
-                        android:src="@drawable/file_text"
-                        android:contentDescription="@string/note_icon_hint" />
-
-                    <TextView
-                        android:id="@+id/shared_with_you_note"
-                        android:layout_width="0dp"
-                        android:layout_height="wrap_content"
-                        android:paddingStart="@dimen/standard_half_padding"
-                        android:paddingEnd="@dimen/standard_half_padding"
-                        android:textSize="16sp"
-                        android:layout_weight="1" />
-                </LinearLayout>
-
-            </LinearLayout>
-        </LinearLayout>
-
-        <include
-            android:id="@+id/file_details_share_public_link_add_new_item_include"
-            layout="@layout/file_details_share_public_link_add_new_item" />
-
-        <androidx.recyclerview.widget.RecyclerView
-            android:id="@+id/sharesList"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:divider="@drawable/divider"
-            android:dividerHeight="1dp" />
-
-        <LinearLayout
-            android:id="@+id/copy_internal_container"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:paddingStart="@dimen/zero"
-            android:paddingTop="@dimen/standard_half_padding"
-            android:paddingEnd="@dimen/standard_padding"
-            android:paddingBottom="@dimen/standard_padding">
-
-            <ImageView
-                android:id="@+id/copy_internal_link_icon"
-                android:layout_width="@dimen/share_icon_size"
-                android:layout_height="@dimen/share_icon_size"
-                android:layout_gravity="top"
-                android:layout_marginStart="@dimen/standard_margin"
-                android:layout_marginEnd="@dimen/standard_margin"
-                android:background="@drawable/round_bgnd"
-                android:contentDescription="@string/share"
-                android:padding="@dimen/standard_half_padding"
-                android:src="@drawable/ic_external" />
+                android:layout_width="match_parent"
+                android:text="@string/shared_with_you_by"
+                android:textSize="16sp" />
 
             <LinearLayout
+                android:id="@+id/shared_with_you_note_container"
+                android:layout_height="match_parent"
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/standard_half_margin"
-                android:orientation="vertical">
+                android:orientation="horizontal"
+                android:paddingTop="@dimen/standard_half_padding"
+                tools:ignore="UseCompoundDrawables">
 
-                <TextView
-                    android:id="@+id/shareInternalLink"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="@string/share_internal_link"
-                    android:textColor="@color/text_color" />
+                <ImageView
+                    android:contentDescription="@string/note_icon_hint"
+                    android:layout_height="16dp"
+                    android:layout_width="16dp"
+                    android:src="@drawable/file_text" />
 
                 <TextView
-                    android:id="@+id/shareInternalLinkText"
-                    android:layout_width="wrap_content"
+                    android:id="@+id/shared_with_you_note"
                     android:layout_height="wrap_content"
-                    tools:text="@string/share_internal_link_to_folder_text" />
+                    android:layout_weight="1"
+                    android:layout_width="0dp"
+                    android:paddingEnd="@dimen/standard_half_padding"
+                    android:paddingStart="@dimen/standard_half_padding"
+                    android:textSize="16sp" />
             </LinearLayout>
 
         </LinearLayout>
-
     </LinearLayout>
 
-</ScrollView>
+    <androidx.recyclerview.widget.RecyclerView
+        android:divider="@drawable/divider"
+        android:dividerHeight="1dp"
+        android:id="@+id/sharesList"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent" />
+
+</LinearLayout>

+ 68 - 0
src/main/res/menu/fragment_file_detail_sharing_email_link.xml

@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Nextcloud Android client application
+
+  Copyright (C) 2018 Andy Scherzinger
+
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+  License as published by the Free Software Foundation; either
+  version 3 of the License, or any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+
+  You should have received a copy of the GNU Affero General Public
+  License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:ignore="AppCompatResource">
+    <group
+        android:id="@+id/folder_permission"
+        android:checkableBehavior="single">
+        <item
+            android:id="@+id/link_share_read_only"
+            android:title="@string/link_share_read_only" />
+        <item
+            android:id="@+id/link_share_allow_upload_and_editing"
+            android:title="@string/link_share_allow_upload_and_editing" />
+        <item
+            android:id="@+id/link_share_file_drop"
+            android:title="@string/link_share_file_drop" />
+    </group>
+    <item
+        android:id="@+id/allow_editing"
+        android:checkable="true"
+        android:showAsAction="never"
+        android:title="@string/allow_editing"
+        app:showAsAction="never" />
+    <item
+        android:id="@+id/action_hide_file_download"
+        android:checkable="true"
+        android:showAsAction="never"
+        android:title="@string/share_via_link_hide_download"
+        app:showAsAction="never" />
+    <item
+        android:id="@+id/action_password"
+        android:showAsAction="never"
+        android:title="@string/share_via_link_menu_password_label"
+        app:showAsAction="never" />
+    <item
+        android:id="@+id/action_share_expiration_date"
+        android:showAsAction="never"
+        android:title="@string/share_expiration_date_label"
+        app:showAsAction="never" />
+    <item
+        android:id="@+id/action_share_send_note"
+        android:showAsAction="never"
+        android:title="@string/share_send_note"
+        app:showAsAction="never" />
+    <item
+        android:id="@+id/action_unshare"
+        android:showAsAction="never"
+        android:title="@string/unshare"
+        app:showAsAction="never" />
+</menu>

+ 10 - 1
src/main/res/menu/fragment_file_detail_sharing_link.xml → src/main/res/menu/fragment_file_detail_sharing_public_link.xml

@@ -20,7 +20,9 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     tools:ignore="AppCompatResource">
-    <group android:checkableBehavior="single">
+    <group
+        android:id="@+id/folder_permission"
+        android:checkableBehavior="single">
         <item
             android:id="@+id/link_share_read_only"
             android:title="@string/link_share_read_only" />
@@ -31,6 +33,12 @@
             android:id="@+id/link_share_file_drop"
             android:title="@string/link_share_file_drop" />
     </group>
+    <item
+        android:id="@+id/allow_editing"
+        android:checkable="true"
+        android:showAsAction="never"
+        android:title="@string/allow_editing"
+        app:showAsAction="never" />
     <item
         android:id="@+id/action_hide_file_download"
         android:checkable="true"
@@ -44,6 +52,7 @@
         app:showAsAction="never" />
     <item
         android:id="@+id/link_share_video_verification"
+        android:checkable="true"
         android:showAsAction="never"
         android:title="@string/link_share_video_verification"
         app:showAsAction="never" />

+ 1 - 1
src/main/res/values/dims.xml

@@ -31,7 +31,7 @@
     <dimen name="standard_double_padding">32dp</dimen>
     <dimen name="standard_half_padding">8dp</dimen>
     <dimen name="standard_quarter_padding">4dp</dimen>
-    <dimen name="standard_eigth_padding">2dp</dimen>
+    <dimen name="standard_eight_padding">2dp</dimen>
     <dimen name="standard_margin">16dp</dimen>
     <dimen name="standard_icon_list_horizontal_margin">24dp</dimen>
     <dimen name="standard_double_margin">32dp</dimen>