浏览代码

wip

Signed-off-by: tobiasKaminsky <tobias@kaminsky.me>
tobiasKaminsky 4 年之前
父节点
当前提交
20d24d8a6d

+ 4 - 2
src/main/java/com/owncloud/android/ui/adapter/PublicShareViewHolder.java

@@ -26,6 +26,7 @@ import android.content.Context;
 import android.text.TextUtils;
 import android.view.View;
 
+import com.owncloud.android.R;
 import com.owncloud.android.databinding.FileDetailsSharePublicLinkItemBinding;
 import com.owncloud.android.lib.resources.shares.OCShare;
 import com.owncloud.android.utils.ThemeUtils;
@@ -47,9 +48,10 @@ class PublicShareViewHolder extends RecyclerView.ViewHolder {
         this.context = context;
     }
 
-    public void bind(OCShare publicShare, ShareeListAdapter.ShareeListAdapterListener listener) {
+    public void bind(OCShare publicShare, ShareeListAdapterListener listener) {
         if (!TextUtils.isEmpty(publicShare.getLabel())) {
-            binding.publicShareLabel.setText(publicShare.getLabel());
+            String text = String.format(context.getString(R.string.share_link), publicShare.getLabel());
+            binding.publicShareLabel.setText(text);
         }
 
         ThemeUtils.colorIconImageViewWithBackground(binding.copyInternalLinkIcon, context);

+ 30 - 338
src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapter.java

@@ -25,43 +25,24 @@
 
 package com.owncloud.android.ui.adapter;
 
-import android.accounts.Account;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ImageView;
-import android.widget.PopupMenu;
-import android.widget.TextView;
 
 import com.owncloud.android.R;
 import com.owncloud.android.databinding.FileDetailsSharePublicLinkItemBinding;
-import com.owncloud.android.datamodel.FileDataStorageManager;
-import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.databinding.FileDetailsShareUserItemBinding;
 import com.owncloud.android.lib.resources.shares.OCShare;
 import com.owncloud.android.lib.resources.shares.ShareType;
-import com.owncloud.android.lib.resources.status.OCCapability;
-import com.owncloud.android.lib.resources.status.OwnCloudVersion;
-import com.owncloud.android.ui.TextDrawable;
-import com.owncloud.android.ui.dialog.ExpirationDatePickerDialogFragment;
-import com.owncloud.android.ui.dialog.NoteDialogFragment;
-import com.owncloud.android.ui.fragment.util.SharingMenuHelper;
 import com.owncloud.android.utils.DisplayUtils;
-import com.owncloud.android.utils.ThemeUtils;
 
-import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
 import java.util.List;
 
-import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
-import androidx.appcompat.widget.AppCompatCheckBox;
-import androidx.fragment.app.FragmentManager;
 import androidx.recyclerview.widget.RecyclerView;
-import butterknife.BindView;
-import butterknife.ButterKnife;
 
 /**
  * Adapter to show a user/group/email/remote in Sharing list in file details view.
@@ -70,27 +51,23 @@ public class ShareeListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
     implements DisplayUtils.AvatarGenerationListener {
 
     private ShareeListAdapterListener listener;
-    private OCCapability capabilities;
-    private FragmentManager fragmentManager;
     private Context context;
-    private int accentColor;
     private List<OCShare> shares;
     private float avatarRadiusDimension;
-    private OCFile file;
     private String userId;
 
-    public ShareeListAdapter(FragmentManager fragmentManager, Context context, List<OCShare> shares, Account account,
-                             OCFile file, ShareeListAdapterListener listener, String userId) {
+    public ShareeListAdapter(Context context,
+                             List<OCShare> shares,
+                             ShareeListAdapterListener listener,
+                             String userId) {
         this.context = context;
-        this.fragmentManager = fragmentManager;
         this.shares = shares;
         this.listener = listener;
-        this.file = file;
         this.userId = userId;
 
-        accentColor = ThemeUtils.primaryAccentColor(context);
-        capabilities = new FileDataStorageManager(account, context.getContentResolver()).getCapability(account.name);
         avatarRadiusDimension = context.getResources().getDimension(R.dimen.user_icon_radius);
+
+        sort(this.shares);
     }
 
     @Override
@@ -103,18 +80,16 @@ public class ShareeListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
     public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
         switch (ShareType.fromValue(viewType)) {
             case PUBLIC_LINK:
-                FileDetailsSharePublicLinkItemBinding binding =
-                    FileDetailsSharePublicLinkItemBinding.inflate(LayoutInflater.from(context), parent, false);
-
-                return new PublicShareViewHolder(binding, context);
-
-//            case USER:
-//                 nothing for now
-//                break;
-
+            case EMAIL:
+                return new PublicShareViewHolder(FileDetailsSharePublicLinkItemBinding.inflate(LayoutInflater.from(context),
+                                                                                               parent,
+                                                                                               false),
+                                                 context);
             default:
-                View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.file_details_share_user_item, parent, false);
-                return new UserViewHolder(v);
+                return new UserViewHolder(FileDetailsShareUserItemBinding.inflate(LayoutInflater.from(context),
+                                                                                  parent,
+                                                                                  false),
+                                          context);
         }
     }
 
@@ -131,53 +106,7 @@ public class ShareeListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
             publicShareViewHolder.bind(share, listener);
         } else {
             UserViewHolder userViewHolder = (UserViewHolder) holder;
-            String name = share.getSharedWithDisplayName();
-
-            switch (share.getShareType()) {
-                case GROUP:
-                    name = context.getString(R.string.share_group_clarification, name);
-                    setImage(userViewHolder, name, R.drawable.ic_group);
-                    break;
-                case EMAIL:
-                    name = context.getString(R.string.share_email_clarification, name);
-                    setImage(userViewHolder, name, R.drawable.ic_email);
-                    break;
-                case ROOM:
-                    name = context.getString(R.string.share_room_clarification, name);
-                    setImage(userViewHolder, name, R.drawable.ic_chat_bubble);
-                    break;
-                case CIRCLE:
-                    userViewHolder.avatar.setImageResource(R.drawable.ic_circles);
-                    break;
-                default:
-                    setImage(userViewHolder, name, R.drawable.ic_user);
-                    break;
-            }
-
-            userViewHolder.name.setText(name);
-
-            if (share.getShareWith().equalsIgnoreCase(userId) || share.getUserId().equalsIgnoreCase(userId)) {
-                userViewHolder.allowEditing.setVisibility(View.VISIBLE);
-                userViewHolder.editShareButton.setVisibility(View.VISIBLE);
-
-                ThemeUtils.tintCheckbox(userViewHolder.allowEditing, accentColor);
-                userViewHolder.allowEditing.setChecked(canEdit(share));
-                userViewHolder.allowEditing.setOnClickListener(v -> allowEditClick(userViewHolder.allowEditing, share));
-
-                // bind listener to edit privileges
-                userViewHolder.editShareButton.setOnClickListener(v -> onOverflowIconClicked(v, userViewHolder.allowEditing, share));
-            } else {
-                userViewHolder.allowEditing.setVisibility(View.GONE);
-                userViewHolder.editShareButton.setVisibility(View.GONE);
-            }
-        }
-    }
-
-    private void setImage(UserViewHolder holder, String name, @DrawableRes int fallback) {
-        try {
-            holder.avatar.setImageDrawable(TextDrawable.createNamedAvatar(name, avatarRadiusDimension));
-        } catch (NoSuchAlgorithmException e) {
-            holder.avatar.setImageResource(fallback);
+            userViewHolder.bind(share, listener, userId, avatarRadiusDimension);
         }
     }
 
@@ -191,208 +120,10 @@ public class ShareeListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
         return shares.size();
     }
 
-    private void allowEditClick(AppCompatCheckBox checkBox, @NonNull OCShare share) {
-        if (!share.isFolder()) {
-            share.setPermissions(listener.updatePermissionsToShare(
-                    share,
-                    canReshare(share),
-                    checkBox.isChecked(),
-                    false,
-                    false,
-                    false
-            ));
-        } else {
-            share.setPermissions(listener.updatePermissionsToShare(
-                    share,
-                    canReshare(share),
-                    checkBox.isChecked(),
-                    checkBox.isChecked(),
-                    checkBox.isChecked(),
-                    checkBox.isChecked()
-            ));
-        }
-    }
-
-    private void onOverflowIconClicked(View view, AppCompatCheckBox allowEditsCheckBox, OCShare share) {
-        // use grey as fallback for elements where custom theming is not available
-        if (ThemeUtils.themingEnabled(context)) {
-            context.getTheme().applyStyle(R.style.FallbackThemingTheme, true);
-        }
-        PopupMenu popup = new PopupMenu(context, view);
-        popup.inflate(R.menu.item_user_sharing_settings);
-
-        prepareOptionsMenu(popup.getMenu(), share);
-
-        popup.setOnMenuItemClickListener(item -> optionsItemSelected(popup.getMenu(), item, allowEditsCheckBox, share));
-        popup.show();
-    }
-
-    /**
-     * Updates the sharee's menu with the current permissions of the {@link OCShare}
-     *
-     * @param menu  the menu of the sharee/shared file
-     * @param share the shared file
-     */
-    private void prepareOptionsMenu(Menu menu, OCShare share) {
-
-        MenuItem editCreateItem = menu.findItem(R.id.action_can_edit_create);
-        MenuItem editChangeItem = menu.findItem(R.id.action_can_edit_change);
-        MenuItem editDeleteItem = menu.findItem(R.id.action_can_edit_delete);
-
-        MenuItem hideFileListingItem = menu.findItem(R.id.action_hide_file_listing);
-        MenuItem passwordItem = menu.findItem(R.id.action_password);
-        MenuItem expirationDateItem = menu.findItem(R.id.action_expiration_date);
-
-        MenuItem reshareItem = menu.findItem(R.id.action_can_reshare);
-
-        MenuItem sendNoteItem = menu.findItem(R.id.action_share_send_note);
-
-        if (isReshareForbidden(share)) {
-            reshareItem.setVisible(false);
-        }
-        reshareItem.setChecked(canReshare(share));
-
-        if (share.getShareType() == ShareType.EMAIL) {
-            SharingMenuHelper.setupHideFileListingMenuItem(
-                    hideFileListingItem,
-                    file.isFolder(),
-                    canEdit(share),
-                    share.getPermissions()
-            );
-            SharingMenuHelper.setupPasswordMenuItem(passwordItem, share.isPasswordProtected());
-
-            reshareItem.setVisible(false);
-            editCreateItem.setVisible(false);
-            editChangeItem.setVisible(false);
-            editDeleteItem.setVisible(false);
-        } else {
-            if (file.isFolder() && isEditOptionsAvailable(share)) {
-                /// TODO change areEditOptionsAvailable in order to delete !isFederated
-                editCreateItem.setChecked(canCreate(share));
-                editChangeItem.setChecked(canUpdate(share));
-                editDeleteItem.setChecked(canDelete(share));
-            } else {
-                editCreateItem.setVisible(false);
-                editChangeItem.setVisible(false);
-                editDeleteItem.setVisible(false);
-            }
-
-            hideFileListingItem.setVisible(false);
-            passwordItem.setVisible(false);
-
-            if (!capabilities.getVersion().isNewerOrEqual(OwnCloudVersion.nextcloud_18)) {
-                expirationDateItem.setVisible(false);
-            }
-        }
-
-        SharingMenuHelper.setupExpirationDateMenuItem(
-                menu.findItem(R.id.action_expiration_date), share.getExpirationDate(), context.getResources());
-
-        sendNoteItem.setVisible(capabilities.getVersion().isNoteOnShareSupported());
-    }
-
-    private boolean isEditOptionsAvailable(OCShare share) {
-        return !ShareType.FEDERATED.equals(share.getShareType());
-    }
-
-    private boolean isReshareForbidden(OCShare share) {
-        return ShareType.FEDERATED.equals(share.getShareType()) ||
-                (capabilities != null && capabilities.getFilesSharingResharing().isFalse());
-    }
-
-    private boolean canEdit(OCShare share) {
-        return (share.getPermissions() &
-                (OCShare.CREATE_PERMISSION_FLAG | OCShare.UPDATE_PERMISSION_FLAG | OCShare.DELETE_PERMISSION_FLAG)) > 0;
-    }
-
-    private boolean canCreate(OCShare share) {
-        return (share.getPermissions() & OCShare.CREATE_PERMISSION_FLAG) > 0;
-    }
-
-    private boolean canUpdate(OCShare share) {
-        return (share.getPermissions() & OCShare.UPDATE_PERMISSION_FLAG) > 0;
-    }
-
-    private boolean canDelete(OCShare share) {
-        return (share.getPermissions() & OCShare.DELETE_PERMISSION_FLAG) > 0;
-    }
-
-    private boolean canReshare(OCShare share) {
-        return (share.getPermissions() & OCShare.SHARE_PERMISSION_FLAG) > 0;
-    }
-
-    private boolean optionsItemSelected(Menu menu, MenuItem item, AppCompatCheckBox allowEditsCheckBox, OCShare share) {
-        switch (item.getItemId()) {
-            case R.id.action_can_edit_create:
-            case R.id.action_can_edit_change:
-            case R.id.action_can_edit_delete: {
-                item.setChecked(!item.isChecked());
-                if (item.isChecked() && !allowEditsCheckBox.isChecked()) {
-                    allowEditsCheckBox.setChecked(true);
-                }
-                share.setPermissions(
-                        updatePermissionsToShare(
-                                share,
-                                menu.findItem(R.id.action_can_reshare).isChecked(),
-                                allowEditsCheckBox.isChecked(),
-                                menu.findItem(R.id.action_can_edit_create).isChecked(),
-                                menu.findItem(R.id.action_can_edit_change).isChecked(),
-                                menu.findItem(R.id.action_can_edit_delete).isChecked())
-                );
-                return true;
-            }
-            case R.id.action_can_reshare: {
-                item.setChecked(!item.isChecked());
-                share.setPermissions(
-                        updatePermissionsToShare(
-                                share,
-                                menu.findItem(R.id.action_can_reshare).isChecked(),
-                                allowEditsCheckBox.isChecked(),
-                                menu.findItem(R.id.action_can_edit_create).isChecked(),
-                                menu.findItem(R.id.action_can_edit_change).isChecked(),
-                                menu.findItem(R.id.action_can_edit_delete).isChecked())
-                );
-                return true;
-            }
-            case R.id.action_unshare: {
-                listener.unshareWith(share);
-                shares.remove(share);
-                notifyDataSetChanged();
-                return true;
-            }
-            case R.id.action_password: {
-                listener.requestPasswordForShare(share, false);
-                return true;
-            }
-            case R.id.action_expiration_date: {
-                ExpirationDatePickerDialogFragment dialog = ExpirationDatePickerDialogFragment
-                    .newInstance(share, share.getExpirationDate());
-                dialog.show(fragmentManager, ExpirationDatePickerDialogFragment.DATE_PICKER_DIALOG);
-                return true;
-            }
-            case R.id.action_share_send_note:
-                NoteDialogFragment dialog = NoteDialogFragment.newInstance(share);
-                dialog.show(fragmentManager, NoteDialogFragment.NOTE_FRAGMENT);
-                return true;
-            default:
-                return true;
-        }
-    }
-
-    private int updatePermissionsToShare(OCShare share, boolean canReshare, boolean canEdit, boolean canEditCreate,
-                                         boolean canEditChange, boolean canEditDelete) {
-        return listener.updatePermissionsToShare(
-            share,
-            canReshare,
-            canEdit,
-            canEditCreate,
-            canEditChange,
-            canEditDelete
-                                                );
-    }
-
     public void addShares(List<OCShare> sharesToAdd) {
         shares.addAll(sharesToAdd);
+        sort(shares);
+        notifyDataSetChanged();
     }
 
     @Override
@@ -412,57 +143,18 @@ public class ShareeListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
         return false;
     }
 
-    class UserViewHolder extends RecyclerView.ViewHolder {
-        @BindView(R.id.avatar)
-        ImageView avatar;
-        @BindView(R.id.name)
-        TextView name;
-        @BindView(R.id.allowEditing)
-        AppCompatCheckBox allowEditing;
-        @BindView(R.id.editShareButton)
-        ImageView editShareButton;
-
-        UserViewHolder(View itemView) {
-            super(itemView);
-            ButterKnife.bind(this, itemView);
-        }
+    public void remove(OCShare share) {
+        shares.remove(share);
+        notifyDataSetChanged();
     }
 
-    public interface ShareeListAdapterListener {
-        /**
-         * unshare with given sharee {@link OCShare}.
-         *
-         * @param share the share
-         */
-        void unshareWith(OCShare share);
-
-        /**
-         * Updates the permissions of the {@link OCShare}.
-         *
-         * @param share         the share to be updated
-         * @param canReshare    reshare permission
-         * @param canEdit       edit permission
-         * @param canEditCreate create permission (folders only)
-         * @param canEditChange change permission (folders only)
-         * @param canEditDelete delete permission (folders only)
-         * @return permissions value set
-         */
-        int updatePermissionsToShare(OCShare share,
-                                     boolean canReshare,
-                                     boolean canEdit,
-                                     boolean canEditCreate,
-                                     boolean canEditChange,
-                                     boolean canEditDelete);
-
-        /**
-         * Starts a dialog that requests a password to the user to protect a share.
-         *
-         * @param share the share for which a password shall be configured/removed
-         */
-        void requestPasswordForShare(OCShare share, boolean askForPassword);
-
-        void copyLink(OCShare share);
+    private void sort(List<OCShare> shares) {
+        Collections.sort(shares, (o1, o2) -> {
+            if (o1.getShareType() != o2.getShareType()) {
+                return o1.getShareType().compareTo(o2.getShareType());
+            }
 
-        void showLinkOverflowMenu(OCShare publicShare, ImageView overflowMenuShareLink);
+            return o1.getSharedWithDisplayName().compareTo(o2.getSharedWithDisplayName());
+        });
     }
 }

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

@@ -0,0 +1,35 @@
+/*
+ *
+ * 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.widget.ImageView;
+
+import com.owncloud.android.lib.resources.shares.OCShare;
+
+public interface ShareeListAdapterListener {
+    void copyLink(OCShare share);
+
+    void showLinkOverflowMenu(OCShare publicShare, ImageView overflowMenuShareLink);
+
+    void showUserOverflowMenu(OCShare share, ImageView overflowMenu);
+}

+ 103 - 0
src/main/java/com/owncloud/android/ui/adapter/UserViewHolder.java

@@ -0,0 +1,103 @@
+/*
+ *
+ * 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.view.View;
+import android.widget.ImageView;
+
+import com.owncloud.android.R;
+import com.owncloud.android.databinding.FileDetailsShareUserItemBinding;
+import com.owncloud.android.lib.resources.shares.OCShare;
+import com.owncloud.android.ui.TextDrawable;
+
+import java.security.NoSuchAlgorithmException;
+
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+class UserViewHolder extends RecyclerView.ViewHolder {
+    private FileDetailsShareUserItemBinding binding;
+    private float avatarRadiusDimension;
+    private Context context;
+
+    public UserViewHolder(@NonNull View itemView) {
+        super(itemView);
+    }
+
+    public UserViewHolder(FileDetailsShareUserItemBinding binding, Context context) {
+        this(binding.getRoot());
+        this.binding = binding;
+        this.context = context;
+    }
+
+    public void bind(OCShare share,
+                     ShareeListAdapterListener listener,
+                     String userId,
+                     float avatarRadiusDimension) {
+        this.avatarRadiusDimension = avatarRadiusDimension;
+        String name = share.getSharedWithDisplayName();
+
+        switch (share.getShareType()) {
+            case GROUP:
+                name = context.getString(R.string.share_group_clarification, name);
+                setImage(binding.avatar, name, R.drawable.ic_group);
+                break;
+            case EMAIL:
+                name = context.getString(R.string.share_email_clarification, name);
+                setImage(binding.avatar, name, R.drawable.ic_email);
+                break;
+            case ROOM:
+                name = context.getString(R.string.share_room_clarification, name);
+                setImage(binding.avatar, name, R.drawable.ic_chat_bubble);
+                break;
+            case CIRCLE:
+                binding.avatar.setImageResource(R.drawable.ic_circles);
+                break;
+            default:
+                setImage(binding.avatar, name, R.drawable.ic_user);
+                break;
+        }
+
+        binding.name.setText(name);
+
+        if (share.getShareWith().equalsIgnoreCase(userId) || share.getUserId().equalsIgnoreCase(userId)) {
+            binding.editShareButton.setVisibility(View.VISIBLE);
+
+            // bind listener to edit privileges
+            binding.editShareButton.setOnClickListener(v -> listener.showUserOverflowMenu(share,
+                                                                                          binding.editShareButton));
+        } else {
+            binding.editShareButton.setVisibility(View.GONE);
+        }
+    }
+
+    private void setImage(ImageView avatar, String name, @DrawableRes int fallback) {
+        try {
+            avatar.setImageDrawable(TextDrawable.createNamedAvatar(name, avatarRadiusDimension));
+        } catch (NoSuchAlgorithmException e) {
+            avatar.setImageResource(fallback);
+        }
+    }
+}

+ 185 - 35
src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java

@@ -53,9 +53,11 @@ import com.owncloud.android.lib.resources.shares.OCShare;
 import com.owncloud.android.lib.resources.shares.SharePermissionsBuilder;
 import com.owncloud.android.lib.resources.shares.ShareType;
 import com.owncloud.android.lib.resources.status.OCCapability;
+import com.owncloud.android.lib.resources.status.OwnCloudVersion;
 import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.ui.activity.FileDisplayActivity;
 import com.owncloud.android.ui.adapter.ShareeListAdapter;
+import com.owncloud.android.ui.adapter.ShareeListAdapterListener;
 import com.owncloud.android.ui.decoration.SimpleListItemDividerDecoration;
 import com.owncloud.android.ui.dialog.ExpirationDatePickerDialogFragment;
 import com.owncloud.android.ui.dialog.NoteDialogFragment;
@@ -84,7 +86,7 @@ import butterknife.ButterKnife;
 import butterknife.OnClick;
 import butterknife.Unbinder;
 
-public class FileDetailSharingFragment extends Fragment implements ShareeListAdapter.ShareeListAdapterListener,
+public class FileDetailSharingFragment extends Fragment implements ShareeListAdapterListener,
     DisplayUtils.AvatarGenerationListener,
     Injectable {
 
@@ -283,11 +285,8 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
                                                        com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
 
             sharesList.setVisibility(View.VISIBLE);
-            sharesList.setAdapter(new ShareeListAdapter(fileActivity.getSupportFragmentManager(),
-                                                        fileActivity,
+            sharesList.setAdapter(new ShareeListAdapter(fileActivity,
                                                         shares,
-                                                        user.toPlatformAccount(),
-                                                        file,
                                                         this,
                                                         userId));
             sharesList.setLayoutManager(new LinearLayoutManager(getContext()));
@@ -346,6 +345,73 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
         }
     }
 
+    @Override
+    public void showUserOverflowMenu(OCShare share, ImageView overflowMenu) {
+        // use grey as fallback for elements where custom theming is not available
+        if (ThemeUtils.themingEnabled(requireContext())) {
+            requireContext().getTheme().applyStyle(R.style.FallbackThemingTheme, true);
+        }
+        PopupMenu popup = new PopupMenu(requireContext(), overflowMenu);
+        popup.inflate(R.menu.item_user_sharing_settings);
+        prepareUserOptionsMenu(popup.getMenu(), share);
+        popup.setOnMenuItemClickListener(item -> userOptionsItemSelected(popup.getMenu(), item, share));
+        popup.show();
+    }
+
+    /**
+     * Updates the sharee's menu with the current permissions of the {@link OCShare}
+     *
+     * @param menu  the menu of the sharee/shared file
+     * @param share the shared file
+     */
+    private void prepareUserOptionsMenu(Menu menu, OCShare share) {
+        MenuItem allowCreatingItem = menu.findItem(R.id.allow_creating);
+        MenuItem allowDeletingItem = menu.findItem(R.id.allow_deleting);
+        MenuItem hideFileListingItem = menu.findItem(R.id.action_hide_file_listing);
+        MenuItem passwordItem = menu.findItem(R.id.action_password);
+        MenuItem expirationDateItem = menu.findItem(R.id.action_expiration_date);
+        MenuItem reshareItem = menu.findItem(R.id.allow_resharing);
+        MenuItem sendNoteItem = menu.findItem(R.id.action_share_send_note);
+
+        if (isReshareForbidden(share)) {
+            reshareItem.setVisible(false);
+        }
+        reshareItem.setChecked(canReshare(share));
+
+        if (share.getShareType() == ShareType.EMAIL) {
+            SharingMenuHelper.setupHideFileListingMenuItem(hideFileListingItem,
+                                                           file.isFolder(),
+                                                           canEdit(share),
+                                                           share.getPermissions());
+            SharingMenuHelper.setupPasswordMenuItem(passwordItem, share.isPasswordProtected());
+
+            reshareItem.setVisible(false);
+            allowCreatingItem.setVisible(false);
+            allowDeletingItem.setVisible(false);
+        } else {
+            if (file.isFolder() && isEditOptionsAvailable(share)) {
+                allowCreatingItem.setChecked(canCreate(share));
+                allowDeletingItem.setChecked(canDelete(share));
+            } else {
+                allowCreatingItem.setVisible(false);
+                allowDeletingItem.setVisible(false);
+            }
+
+            hideFileListingItem.setVisible(false);
+            passwordItem.setVisible(false);
+
+            if (!capabilities.getVersion().isNewerOrEqual(OwnCloudVersion.nextcloud_18)) {
+                expirationDateItem.setVisible(false);
+            }
+        }
+
+        SharingMenuHelper.setupExpirationDateMenuItem(menu.findItem(R.id.action_expiration_date),
+                                                      share.getExpirationDate(),
+                                                      getResources());
+
+        sendNoteItem.setVisible(capabilities.getVersion().isNoteOnShareSupported());
+    }
+
     public void showLinkOverflowMenu(OCShare publicShare, ImageView overflowMenuShareLink) {
         if (ThemeUtils.themingEnabled(requireContext())) {
             // use grey as fallback for elements where custom theming is not available
@@ -354,17 +420,17 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
 
         PopupMenu popup = new PopupMenu(requireContext(), overflowMenuShareLink);
         popup.inflate(R.menu.fragment_file_detail_sharing_link);
-        prepareOptionsMenu(popup.getMenu(), publicShare);
-        popup.setOnMenuItemClickListener(menuItem -> optionsItemSelected(menuItem, publicShare));
+        prepareLinkOptionsMenu(popup.getMenu(), publicShare);
+        popup.setOnMenuItemClickListener(menuItem -> linkOptionsItemSelected(menuItem, publicShare));
         popup.show();
     }
 
-    private void prepareOptionsMenu(Menu menu, OCShare publicShare) {
+    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());
+//        SharingMenuHelper.setupHideFileListingMenuItem(menu.findItem(R.id.action_hide_file_listing),
+//                                                       file.isFolder(),
+//                                                       menu.findItem(R.id.action_allow_editing).isChecked(),
+//                                                       publicShare.getPermissions());
 
         SharingMenuHelper.setupHideFileDownload(menu.findItem(R.id.action_hide_file_download),
                                                 publicShare.isHideFileDownload(),
@@ -379,21 +445,61 @@ 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);
-        }
+//        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);
+//        }
     }
 
-    public boolean optionsItemSelected(MenuItem item, OCShare publicShare) {
+    private boolean userOptionsItemSelected(Menu menu,
+                                            MenuItem item,
+                                            OCShare share) {
         switch (item.getItemId()) {
-            case R.id.action_allow_editing:
-                if (file.isSharedViaLink()) {
-                    item.setChecked(!item.isChecked());
-                    fileOperationsHelper.setUploadPermissionsToPublicShare(publicShare, item.isChecked());
-                }
+            case R.id.allow_creating:
+            case R.id.allow_deleting:
+            case R.id.allow_resharing: {
+                item.setChecked(!item.isChecked());
+                share.setPermissions(updatePermissionsToShare(share,
+                                                              menu.findItem(R.id.allow_resharing).isChecked(),
+                                                              menu.findItem(R.id.allow_editing).isChecked(),
+                                                              menu.findItem(R.id.allow_creating).isChecked(),
+                                                              menu.findItem(R.id.allow_deleting).isChecked()));
+                return true;
+            }
+            case R.id.action_unshare: {
+                unshareWith(share);
+                ((ShareeListAdapter) sharesList.getAdapter()).remove(share);
+                return true;
+            }
+            case R.id.action_password: {
+                requestPasswordForShare(share);
+                return true;
+            }
+            case R.id.action_expiration_date: {
+                ExpirationDatePickerDialogFragment dialog = ExpirationDatePickerDialogFragment
+                    .newInstance(share, share.getExpirationDate());
+                dialog.show(fileActivity.getSupportFragmentManager(),
+                            ExpirationDatePickerDialogFragment.DATE_PICKER_DIALOG);
+                return true;
+            }
+            case R.id.action_share_send_note:
+                NoteDialogFragment dialog = NoteDialogFragment.newInstance(share);
+                dialog.show(fileActivity.getSupportFragmentManager(), NoteDialogFragment.NOTE_FRAGMENT);
+                return true;
+            default:
                 return true;
+        }
+    }
+
+    public boolean linkOptionsItemSelected(MenuItem item, OCShare publicShare) {
+        switch (item.getItemId()) {
+//            case R.id.action_allow_editing:
+//                if (file.isSharedViaLink()) {
+//                    item.setChecked(!item.isChecked());
+//                    fileOperationsHelper.setUploadPermissionsToPublicShare(publicShare, item.isChecked());
+//                }
+//                return true;
             case R.id.action_hide_file_listing: {
                 item.setChecked(!item.isChecked());
                 fileOperationsHelper.setHideFileListingPermissionsToPublicShare(publicShare, item.isChecked());
@@ -468,24 +574,20 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
         setupView();
     }
 
-    @Override
-    public void unshareWith(OCShare share) {
+    private void unshareWith(OCShare share) {
         fileOperationsHelper.unshareShare(file, share);
     }
 
-    @Override
-    public int updatePermissionsToShare(OCShare share,
-                                        boolean canReshare,
-                                        boolean canEdit,
-                                        boolean canEditCreate,
-                                        boolean canEditChange,
-                                        boolean canEditDelete) {
+    private int updatePermissionsToShare(OCShare share,
+                                         boolean canReshare,
+                                         boolean canEdit,
+                                         boolean canEditCreate,
+                                         boolean canEditDelete) {
         SharePermissionsBuilder spb = new SharePermissionsBuilder();
         spb.setSharePermission(canReshare);
 
         if (file.isFolder()) {
-            spb.setUpdatePermission(canEditChange)
-                .setCreatePermission(canEditCreate)
+            spb.setCreatePermission(canEditCreate)
                 .setDeletePermission(canEditDelete);
         } else {
             spb.setUpdatePermission(canEdit);
@@ -552,7 +654,6 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
         } else {
             addPublicShare.setVisibility(View.GONE);
             ((ShareeListAdapter) sharesList.getAdapter()).addShares(shares);
-
         }
     }
 
@@ -573,4 +674,53 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
     public boolean shouldCallGeneratedCallback(String tag, Object callContext) {
         return false;
     }
+
+    private boolean isReshareForbidden(OCShare share) {
+        return ShareType.FEDERATED.equals(share.getShareType()) ||
+            (capabilities != null && capabilities.getFilesSharingResharing().isFalse());
+    }
+
+    private boolean isEditOptionsAvailable(OCShare share) {
+        return !ShareType.FEDERATED.equals(share.getShareType());
+    }
+
+
+    private boolean canEdit(OCShare share) {
+        return (share.getPermissions() &
+            (OCShare.CREATE_PERMISSION_FLAG | OCShare.UPDATE_PERMISSION_FLAG | OCShare.DELETE_PERMISSION_FLAG)) > 0;
+    }
+
+    private boolean canCreate(OCShare share) {
+        return (share.getPermissions() & OCShare.CREATE_PERMISSION_FLAG) > 0;
+    }
+
+    private boolean canUpdate(OCShare share) {
+        return (share.getPermissions() & OCShare.UPDATE_PERMISSION_FLAG) > 0;
+    }
+
+    private boolean canDelete(OCShare share) {
+        return (share.getPermissions() & OCShare.DELETE_PERMISSION_FLAG) > 0;
+    }
+
+//    private void allowEditClick(AppCompatCheckBox checkBox, @NonNull OCShare share) {
+//        if (!share.isFolder()) {
+//            share.setPermissions(updatePermissionsToShare(share,
+//                                                          canReshare(share),
+//                                                          checkBox.isChecked(),
+//                                                          false,
+//                                                          false,
+//                                                          false));
+//        } else {
+//            share.setPermissions(updatePermissionsToShare(share,
+//                                                          canReshare(share),
+//                                                          checkBox.isChecked(),
+//                                                          checkBox.isChecked(),
+//                                                          checkBox.isChecked(),
+//                                                          checkBox.isChecked()));
+//        }
+//    }
+
+    private boolean canReshare(OCShare share) {
+        return (share.getPermissions() & OCShare.SHARE_PERMISSION_FLAG) > 0;
+    }
 }

+ 5 - 0
src/main/res/layout/file_details_share_public_link_item.xml

@@ -45,6 +45,11 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
+        android:textColor="@color/text_color"
+        android:ellipsize="end"
+        android:singleLine="true"
+        android:gravity="center_vertical"
+        android:textSize="@dimen/file_details_username_text_size"
         android:text="@string/share_via_link_section_title" />
 
     <ImageView

+ 0 - 8
src/main/res/layout/file_details_share_user_item.xml

@@ -52,14 +52,6 @@
             android:textColor="@color/text_color"
             android:textSize="@dimen/file_details_username_text_size" />
 
-    <androidx.appcompat.widget.AppCompatCheckBox
-            android:id="@+id/allowEditing"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-            android:textSize="16sp"
-            android:text="@string/edit_permission_label" />
-
         <ImageView
             android:id="@+id/editShareButton"
             android:layout_width="wrap_content"

+ 23 - 23
src/main/res/menu/fragment_file_detail_sharing_link.xml

@@ -1,6 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Nesxtcloud Android client application
+<?xml version="1.0" encoding="utf-8"?><!--
+  Nextcloud Android client application
 
   Copyright (C) 2018 Andy Scherzinger
 
@@ -21,36 +20,32 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     tools:ignore="AppCompatResource">
-
-    <item
-        android:id="@+id/action_allow_editing"
-        android:showAsAction="never"
-        android:title="@string/allow_editing"
-        android:checkable="true"
-        android:textSize="16sp"
-        app:showAsAction="never" />
-
-    <item
-        android:id="@+id/action_hide_file_listing"
-        android:showAsAction="never"
-        android:title="@string/share_via_link_hide_file_listing_permission_label"
-        android:checkable="true"
-        app:showAsAction="never" />
+    <group 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/action_hide_file_download"
+        android:checkable="true"
         android:showAsAction="never"
         android:title="@string/share_via_link_hide_download"
-        android:checkable="true"
         app:showAsAction="never" />
     <item
-        android:id="@+id/action_edit_label"
+        android:id="@+id/action_password"
         android:showAsAction="never"
-        android:title="@string/edit_label"
+        android:title="@string/share_via_link_menu_password_label"
         app:showAsAction="never" />
     <item
-        android:id="@+id/action_password"
+        android:id="@+id/link_share_video_verification"
         android:showAsAction="never"
-        android:title="@string/share_via_link_menu_password_label"
+        android:title="@string/link_share_video_verification"
         app:showAsAction="never" />
     <item
         android:id="@+id/action_share_expiration_date"
@@ -67,6 +62,11 @@
         android:showAsAction="never"
         android:title="@string/share_send_note"
         app:showAsAction="never" />
+    <item
+        android:id="@+id/action_edit_label"
+        android:showAsAction="never"
+        android:title="@string/edit_label"
+        app:showAsAction="never" />
     <item
         android:id="@+id/action_unshare"
         android:showAsAction="never"

+ 9 - 9
src/main/res/menu/item_user_sharing_settings.xml

@@ -21,30 +21,30 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     tools:ignore="AppCompatResource">
-
     <item
-        android:id="@+id/action_can_edit_create"
+        android:id="@+id/allow_editing"
         android:checkable="true"
         android:showAsAction="never"
-        android:title="@string/share_privilege_can_edit_create"
+        android:title="@string/allow_editing"
         app:showAsAction="never" />
+
     <item
-        android:id="@+id/action_can_edit_change"
+        android:id="@+id/allow_creating"
         android:checkable="true"
         android:showAsAction="never"
-        android:title="@string/share_privilege_can_edit_change"
+        android:title="@string/allow_creating"
         app:showAsAction="never" />
     <item
-        android:id="@+id/action_can_edit_delete"
+        android:id="@+id/allow_deleting"
         android:checkable="true"
         android:showAsAction="never"
-        android:title="@string/share_privilege_can_edit_delete"
+        android:title="@string/allow_deleting"
         app:showAsAction="never" />
     <item
-        android:id="@+id/action_can_reshare"
+        android:id="@+id/allow_resharing"
         android:checkable="true"
         android:showAsAction="never"
-        android:title="@string/share_privilege_can_share"
+        android:title="@string/allow_resharing"
         app:showAsAction="never" />
     <item
         android:id="@+id/action_hide_file_listing"

+ 9 - 0
src/main/res/values/strings.xml

@@ -483,6 +483,7 @@
     <string name="share_known_remote_clarification">%1$s ( at %2$s )</string>
 
     <string name="share_privilege_unshare">Unshare</string>
+    <string name="share_privilege_can_edit">can edit</string>
     <string name="share_privilege_can_share">can share</string>
     <string name="share_privilege_can_edit_create">can create</string>
     <string name="share_privilege_can_edit_change">can change</string>
@@ -933,4 +934,12 @@
     <string name="add_new_public_share">Add new public share link</string>
     <string name="edit_label">Change name</string>
     <string name="public_share_name">New name</string>
+    <string name="share_link">Share link (%1$s)</string>
+    <string name="allow_creating">Allow creating</string>
+    <string name="allow_deleting">Allow deleting</string>
+    <string name="allow_resharing">Allow resharing</string>
+    <string name="link_share_read_only">Read only</string>
+    <string name="link_share_allow_upload_and_editing">Allow upload and editing</string>
+    <string name="link_share_file_drop">File drop (upload only)</string>
+    <string name="link_share_video_verification">Video verification</string>
 </resources>