Browse Source

show sharees

Signed-off-by: tobiasKaminsky <tobias@kaminsky.me>
tobiasKaminsky 6 years ago
parent
commit
dc7a2c0e7e

+ 5 - 0
drawable_resources/ic_people.svg

@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M0 0h24v24H0z" fill="none"/>
+    <path
+        d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"/>
+</svg>

+ 12 - 1
src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java

@@ -209,6 +209,7 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.FILE_OWNER_ID, file.getOwnerId());
         cv.put(ProviderTableMeta.FILE_OWNER_DISPLAY_NAME, file.getOwnerDisplayName());
         cv.put(ProviderTableMeta.FILE_NOTE, file.getNote());
+        cv.put(ProviderTableMeta.FILE_SHAREES, TextUtils.join(",", file.getSharees()));
 
         boolean sameRemotePath = fileExists(file.getRemotePath());
         if (sameRemotePath ||
@@ -452,6 +453,7 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.FILE_OWNER_ID, folder.getOwnerId());
         cv.put(ProviderTableMeta.FILE_OWNER_DISPLAY_NAME, folder.getOwnerDisplayName());
         cv.put(ProviderTableMeta.FILE_NOTE, folder.getNote());
+        cv.put(ProviderTableMeta.FILE_SHAREES, TextUtils.join(",", folder.getSharees()));
 
         return cv;
     }
@@ -491,6 +493,7 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.FILE_OWNER_ID, file.getOwnerId());
         cv.put(ProviderTableMeta.FILE_OWNER_DISPLAY_NAME, file.getOwnerDisplayName());
         cv.put(ProviderTableMeta.FILE_NOTE, file.getNote());
+        cv.put(ProviderTableMeta.FILE_SHAREES, TextUtils.join(",", file.getSharees()));
 
         return cv;
     }
@@ -989,6 +992,14 @@ public class FileDataStorageManager {
             file.setOwnerId(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_OWNER_ID)));
             file.setOwnerDisplayName(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_OWNER_DISPLAY_NAME)));
             file.setNote(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_NOTE)));
+
+            String sharees = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_SHAREES));
+
+            if (sharees == null || sharees.isEmpty()) {
+                file.setSharees(new ArrayList<>());
+            } else {
+                file.setSharees(new ArrayList<>(Arrays.asList(sharees.split(","))));
+            }
         }
 
         return file;
@@ -1217,7 +1228,7 @@ public class FileDataStorageManager {
             share.setSharedWithDisplayName(
                     c.getString(c.getColumnIndex(ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME)));
             share.setFolder(c.getInt(c.getColumnIndex(ProviderTableMeta.OCSHARES_IS_DIRECTORY)) == 1);
-            share.setUserId(c.getLong(c.getColumnIndex(ProviderTableMeta.OCSHARES_USER_ID)));
+            share.setUserId(c.getString(c.getColumnIndex(ProviderTableMeta.OCSHARES_USER_ID)));
             share.setRemoteId(c.getLong(c.getColumnIndex(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED)));
             share.setPasswordProtected(c.getInt(c.getColumnIndex(ProviderTableMeta.OCSHARES_IS_PASSWORD_PROTECTED)) == 1);
             share.setNote(c.getString(c.getColumnIndex(ProviderTableMeta.OCSHARES_NOTE)));

+ 7 - 6
src/main/java/com/owncloud/android/datamodel/OCFile.java

@@ -28,22 +28,22 @@ import android.content.Context;
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
-
+import androidx.annotation.NonNull;
+import androidx.core.content.FileProvider;
 import com.owncloud.android.R;
 import com.owncloud.android.lib.common.network.WebdavEntry;
 import com.owncloud.android.lib.common.network.WebdavUtils;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.resources.files.model.ServerFileInterface;
 import com.owncloud.android.utils.MimeType;
-
-import java.io.File;
-
-import androidx.annotation.NonNull;
-import androidx.core.content.FileProvider;
 import lombok.Getter;
 import lombok.Setter;
 import third_parties.daveKoeller.AlphanumComparator;
 
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
 public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterface {
     private final static String PERMISSION_SHARED_WITH_ME = "S";
     private final static String PERMISSION_CAN_RESHARE = "R";
@@ -88,6 +88,7 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
     @Getter @Setter private String ownerId;
     @Getter @Setter private String ownerDisplayName;
     @Getter @Setter String note;
+    @Getter @Setter private List<String> sharees = new ArrayList<>();
 
     /**
      * URI to the local path of the file contents, if stored in the device; cached after first call

+ 4 - 1
src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java

@@ -44,6 +44,7 @@ import android.view.Display;
 import android.view.MenuItem;
 import android.view.WindowManager;
 import android.widget.ImageView;
+
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.lib.common.OwnCloudAccount;
@@ -62,7 +63,7 @@ import com.owncloud.android.utils.ConnectivityUtils;
 import com.owncloud.android.utils.DisplayUtils.AvatarGenerationListener;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.MimeTypeUtil;
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
 import org.apache.commons.httpclient.HttpStatus;
 import org.apache.commons.httpclient.methods.GetMethod;
 import org.jetbrains.annotations.NotNull;
@@ -74,6 +75,8 @@ import java.lang.ref.WeakReference;
 import java.net.URLEncoder;
 import java.util.List;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
 /**
  * Manager for concurrent access to thumbnails cache.
  */

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

@@ -31,7 +31,7 @@ import com.owncloud.android.MainApp;
  */
 public class ProviderMeta {
     public static final String DB_NAME = "filelist";
-    public static final int DB_VERSION = 44;
+    public static final int DB_VERSION = 45;
 
     private ProviderMeta() {
         // No instance
@@ -109,6 +109,7 @@ public class ProviderMeta {
         public static final String FILE_OWNER_ID = "owner_id";
         public static final String FILE_OWNER_DISPLAY_NAME = "owner_display_name";
         public static final String FILE_NOTE = "note";
+        public static final String FILE_SHAREES = "sharees";
 
         public static final String[] FILE_ALL_COLUMNS = {
             _ID, FILE_PARENT, FILE_NAME, FILE_CREATION, FILE_MODIFIED,
@@ -116,7 +117,7 @@ public class ProviderMeta {
             FILE_PATH, FILE_ACCOUNT_OWNER, FILE_LAST_SYNC_DATE, FILE_LAST_SYNC_DATE_FOR_DATA, FILE_ETAG,
             FILE_ETAG_ON_SERVER, FILE_SHARED_VIA_LINK, FILE_SHARED_WITH_SHAREE, FILE_PUBLIC_LINK, FILE_PERMISSIONS,
             FILE_REMOTE_ID, FILE_UPDATE_THUMBNAIL, FILE_IS_DOWNLOADING, FILE_ETAG_IN_CONFLICT, FILE_FAVORITE,
-            FILE_IS_ENCRYPTED, FILE_MOUNT_TYPE, FILE_HAS_PREVIEW, FILE_UNREAD_COMMENTS_COUNT
+            FILE_IS_ENCRYPTED, FILE_MOUNT_TYPE, FILE_HAS_PREVIEW, FILE_UNREAD_COMMENTS_COUNT, FILE_SHAREES
         };
 
         public static final String FILE_DEFAULT_SORT_ORDER = FILE_NAME + " collate nocase asc";

+ 22 - 3
src/main/java/com/owncloud/android/providers/FileContentProvider.java

@@ -701,7 +701,8 @@ public class FileContentProvider extends ContentProvider {
                        + ProviderTableMeta.FILE_UNREAD_COMMENTS_COUNT + INTEGER
                        + ProviderTableMeta.FILE_OWNER_ID + TEXT
                        + ProviderTableMeta.FILE_OWNER_DISPLAY_NAME + TEXT
-                       + ProviderTableMeta.FILE_NOTE + " TEXT);"
+                       + ProviderTableMeta.FILE_NOTE + TEXT
+                       + ProviderTableMeta.FILE_SHAREES + " TEXT);"
         );
     }
 
@@ -1874,9 +1875,9 @@ public class FileContentProvider extends ContentProvider {
                 db.beginTransaction();
                 try {
                     db.execSQL(ALTER_TABLE + ProviderTableMeta.FILE_TABLE_NAME +
-                            ADD_COLUMN + ProviderTableMeta.FILE_OWNER_ID + " TEXT ");
+                                   ADD_COLUMN + ProviderTableMeta.FILE_OWNER_ID + " TEXT ");
                     db.execSQL(ALTER_TABLE + ProviderTableMeta.FILE_TABLE_NAME +
-                            ADD_COLUMN + ProviderTableMeta.FILE_OWNER_DISPLAY_NAME + " TEXT ");
+                                   ADD_COLUMN + ProviderTableMeta.FILE_OWNER_DISPLAY_NAME + " TEXT ");
 
                     upgraded = true;
                     db.setTransactionSuccessful();
@@ -1906,6 +1907,24 @@ public class FileContentProvider extends ContentProvider {
             if (!upgraded) {
                 Log_OC.i(SQL, String.format(Locale.ENGLISH, UPGRADE_VERSION_MSG, oldVersion, newVersion));
             }
+
+            if (oldVersion < 45 && newVersion >= 45) {
+                Log_OC.i(SQL, "Entering in the #45 add sharees to file table");
+                db.beginTransaction();
+                try {
+                    db.execSQL(ALTER_TABLE + ProviderTableMeta.FILE_TABLE_NAME +
+                                   ADD_COLUMN + ProviderTableMeta.FILE_SHAREES + " TEXT ");
+
+                    upgraded = true;
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                }
+            }
+
+            if (!upgraded) {
+                Log_OC.i(SQL, String.format(Locale.ENGLISH, UPGRADE_VERSION_MSG, oldVersion, newVersion));
+            }
         }
 
         @Override

+ 88 - 30
src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java

@@ -25,6 +25,7 @@
 package com.owncloud.android.ui.adapter;
 
 import android.accounts.Account;
+import android.accounts.AccountManager;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.res.Resources;
@@ -40,6 +41,7 @@ import android.view.ViewGroup;
 import android.widget.Filter;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
 import android.widget.TextView;
 
 import com.bumptech.glide.Glide;
@@ -77,6 +79,7 @@ import com.owncloud.android.utils.ThemeUtils;
 
 import java.io.File;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
@@ -100,6 +103,7 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
     private final FileDownloader.FileDownloaderBinder downloaderBinder;
     private final FileUploader.FileUploaderBinder uploaderBinder;
     private final OperationsService.OperationsServiceBinder operationsServiceBinder;
+    private final String userId;
     private Context mContext;
     private AppPreferences preferences;
     private List<OCFile> mFiles = new ArrayList<>();
@@ -123,6 +127,7 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
 
     private List<ThumbnailsCacheManager.ThumbnailGenerationTask> asyncTasks = new ArrayList<>();
     private boolean onlyOnDevice;
+    private boolean showShareAvatar;
 
     public OCFileListAdapter(
         Context context,
@@ -146,6 +151,17 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
         uploaderBinder = transferServiceGetter.getFileUploaderBinder();
         operationsServiceBinder = transferServiceGetter.getOperationsServiceBinder();
 
+        if (account != null) {
+            AccountManager accountManager = AccountManager.get(mContext);
+            userId = accountManager.getUserData(account,
+                                                com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
+        } else {
+            userId = "";
+        }
+
+        // TODO change when https://github.com/nextcloud/server/pull/14429 is merged
+        showShareAvatar = false;
+
         // initialise thumbnails cache on background thread
         new ThumbnailsCacheManager.InitDiskCacheTask().execute();
     }
@@ -328,26 +344,65 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
             if (holder instanceof OCFileListItemViewHolder) {
                 OCFileListItemViewHolder itemViewHolder = (OCFileListItemViewHolder) holder;
 
-                if (file.isSharedWithMe() && file.getOwnerId() != null && !multiSelect && !gridView &&
-                    !mHideItemOptions) {
-                    itemViewHolder.sharedAvatar.setVisibility(View.VISIBLE);
+                Resources resources = mContext.getResources();
+                float avatarRadius = resources.getDimension(R.dimen.list_item_avatar_icon_radius);
 
-                    Resources resources = mContext.getResources();
+                if ((file.isSharedWithMe() || file.isSharedWithSharee()) && !multiSelect && !gridView &&
+                    !mHideItemOptions) {
+                    itemViewHolder.sharedAvatars.setVisibility(View.VISIBLE);
+                    itemViewHolder.sharedAvatars.removeAllViews();
 
-                    float avatarRadius = resources.getDimension(R.dimen.list_item_avatar_icon_radius);
+                    String fileOwner = file.getOwnerId();
+                    ArrayList<String> sharees = (ArrayList<String>) file.getSharees();
 
-                    if (file.getOwnerId().contains("@")) {
-                        showFederatedShareAvatar(file, avatarRadius, resources, itemViewHolder);
-                    } else {
-                        itemViewHolder.sharedAvatar.setTag(file.getOwnerId());
-                        DisplayUtils.setAvatar(account, file.getOwnerId(), this, avatarRadius, resources,
-                                               itemViewHolder.sharedAvatar, mContext);
+                    // use fileOwner if not oneself, then add at first
+                    if (!fileOwner.equals(userId) && !sharees.contains(fileOwner)) {
+                        sharees.add(fileOwner);
                     }
 
-                    itemViewHolder.sharedAvatar.setOnClickListener(view ->
-                                                                       ocFileListFragmentInterface.showShareDetailView(file));
+                    Collections.reverse(sharees);
+
+                    Log_OC.d(this, "sharees of " + file.getFileName() + ": " + sharees);
+
+                    int shareeSize = Math.min(sharees.size(), 3);
+                    int w = DisplayUtils.convertDpToPixel(40, mContext);
+                    int margin = DisplayUtils.convertDpToPixel(24, mContext);
+                    int size = 60 * (shareeSize - 1) + w;
+
+                    for (int i = 0; i < shareeSize; i++) {
+                        String sharee = file.getSharees().get(i);
+
+                        ImageView avatar = new ImageView(mContext);
+
+                        if (i == 0 && sharees.size() > 3) {
+                            avatar.setImageResource(R.drawable.ic_people);
+                        } else {
+                            if (sharee.contains("@")) {
+                                showFederatedShareAvatar(sharee, avatarRadius, resources, avatar);
+                            } else {
+                                avatar.setTag(sharee);
+                                DisplayUtils.setAvatar(account, sharee, this, avatarRadius, resources,
+                                                       avatar, mContext);
+                                Log_OC.d(TAG, "avatar: " + sharee);
+                            }
+                        }
+
+                        avatar.setOnClickListener(view -> ocFileListFragmentInterface.showShareDetailView(file));
+
+                        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(w, w);
+                        layoutParams.setMargins(0, 0, i * margin, 0);
+                        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
+                        avatar.setLayoutParams(layoutParams);
+                        itemViewHolder.sharedAvatars.addView(avatar);
+
+                        ViewGroup.LayoutParams rememberParam = itemViewHolder.sharedAvatars.getLayoutParams();
+                        rememberParam.width = size;
+
+                        itemViewHolder.sharedAvatars.setLayoutParams(rememberParam);
+                    }
                 } else {
-                    itemViewHolder.sharedAvatar.setVisibility(View.GONE);
+                    itemViewHolder.sharedAvatars.setVisibility(View.GONE);
+                    itemViewHolder.sharedAvatars.removeAllViews();
                 }
 
                 if (onlyOnDevice) {
@@ -435,13 +490,13 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
         }
     }
 
-    private void showFederatedShareAvatar(OCFile file, float avatarRadius, Resources resources,
-                                          OCFileListItemViewHolder itemViewHolder) {
+    private void showFederatedShareAvatar(String user, float avatarRadius, Resources resources, ImageView avatar) {
         // maybe federated share
-        String userId = file.getOwnerId().split("@")[0];
-        String server = file.getOwnerId().split("@")[1];
+        String[] split = user.split("@");
+        String userId = split[0];
+        String server = split[1];
 
-        String url = "https://" + server + "/avatar/" + userId + "/" +
+        String url = "https://" + server + "/index.php/avatar/" + userId + "/" +
             DisplayUtils.convertDpToPixel(avatarRadius, mContext);
 
         Drawable placeholder;
@@ -452,21 +507,21 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
             placeholder = resources.getDrawable(R.drawable.account_circle_white);
         }
 
-        itemViewHolder.sharedAvatar.setTag(null);
+        avatar.setTag(null);
         Glide.with(mContext).load(url)
             .asBitmap()
             .placeholder(placeholder)
             .error(placeholder)
-            .into(new BitmapImageViewTarget(itemViewHolder.sharedAvatar) {
+            .into(new BitmapImageViewTarget(avatar) {
                 @Override
                 protected void setResource(Bitmap resource) {
                     RoundedBitmapDrawable circularBitmapDrawable =
                         RoundedBitmapDrawableFactory.create(mContext.getResources(), resource);
                     circularBitmapDrawable.setCircular(true);
-                    itemViewHolder.sharedAvatar.setImageDrawable(circularBitmapDrawable);
+                    avatar.setImageDrawable(circularBitmapDrawable);
                 }
             });
-    }
+        }
 
     private void setThumbnail(OCFile file, ImageView thumbnailView) {
         if (file.isFolder()) {
@@ -586,11 +641,14 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
         if (gridViewHolder instanceof OCFileListItemViewHolder || file.getUnreadCommentsCount() == 0) {
             sharedIconView.setVisibility(View.VISIBLE);
 
-            if (file.isSharedWithSharee()) {
-                sharedIconView.setImageResource(R.drawable.shared_via_users);
-                sharedIconView.setContentDescription(mContext.getString(R.string.shared_icon_shared));
-            } else if (file.isSharedWithMe()) {
-                sharedIconView.setVisibility(View.GONE);
+            if (file.isSharedWithSharee() || file.isSharedWithMe()) {
+                if (showShareAvatar) {
+                    sharedIconView.setVisibility(View.GONE);
+                } else {
+                    sharedIconView.setVisibility(View.VISIBLE);
+                    sharedIconView.setImageResource(R.drawable.shared_via_users);
+                    sharedIconView.setContentDescription(mContext.getString(R.string.shared_icon_shared));
+                }
             } else if (file.isSharedViaLink()) {
                 sharedIconView.setImageResource(R.drawable.shared_via_link);
                 sharedIconView.setContentDescription(mContext.getString(R.string.shared_icon_shared_via_link));
@@ -925,8 +983,8 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
         @BindView(R.id.overflow_menu)
         public ImageView overflowMenu;
 
-        @BindView(R.id.sharedAvatar)
-        public ImageView sharedAvatar;
+        @BindView(R.id.sharedAvatars)
+        public RelativeLayout sharedAvatars;
 
         private OCFileListItemViewHolder(View itemView) {
             super(itemView);

+ 23 - 15
src/main/java/com/owncloud/android/ui/adapter/UserListAdapter.java

@@ -32,7 +32,13 @@ import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.PopupMenu;
 import android.widget.TextView;
-
+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;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
@@ -50,14 +56,6 @@ import com.owncloud.android.utils.ThemeUtils;
 import java.security.NoSuchAlgorithmException;
 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.
  */
@@ -72,14 +70,16 @@ public class UserListAdapter extends RecyclerView.Adapter<UserListAdapter.UserVi
     private List<OCShare> shares;
     private float avatarRadiusDimension;
     private OCFile file;
+    private String userId;
 
     public UserListAdapter(FragmentManager fragmentManager, Context context, List<OCShare> shares, Account account,
-                           OCFile file, ShareeListAdapterListener listener) {
+                           OCFile file, 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);
@@ -120,12 +120,20 @@ public class UserListAdapter extends RecyclerView.Adapter<UserListAdapter.UserVi
 
             holder.name.setText(name);
 
-            ThemeUtils.tintCheckbox(holder.allowEditing, accentColor);
-            holder.allowEditing.setChecked(canEdit(share));
-            holder.allowEditing.setOnClickListener(v -> allowEditClick(holder.allowEditing, share));
+            if (share.getShareWith().equalsIgnoreCase(userId) || share.getUserId().equalsIgnoreCase(userId)) {
+                holder.allowEditing.setVisibility(View.VISIBLE);
+                holder.editShareButton.setVisibility(View.VISIBLE);
+
+                ThemeUtils.tintCheckbox(holder.allowEditing, accentColor);
+                holder.allowEditing.setChecked(canEdit(share));
+                holder.allowEditing.setOnClickListener(v -> allowEditClick(holder.allowEditing, share));
 
-            // bind listener to edit privileges
-            holder.editShareButton.setOnClickListener(v -> onOverflowIconClicked(v, holder.allowEditing, share));
+                // bind listener to edit privileges
+                holder.editShareButton.setOnClickListener(v -> onOverflowIconClicked(v, holder.allowEditing, share));
+            } else {
+                holder.allowEditing.setVisibility(View.GONE);
+                holder.editShareButton.setVisibility(View.GONE);
+            }
         }
     }
 

+ 10 - 7
src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java

@@ -39,12 +39,7 @@ import android.widget.LinearLayout;
 import android.widget.PopupMenu;
 import android.widget.ProgressBar;
 import android.widget.TextView;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.viewpager.widget.ViewPager;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.Unbinder;
+
 import com.google.android.material.tabs.TabLayout;
 import com.nextcloud.client.di.Injectable;
 import com.nextcloud.client.preferences.AppPreferences;
@@ -68,9 +63,17 @@ import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.MimeTypeUtil;
 import com.owncloud.android.utils.ThemeUtils;
 
-import javax.inject.Inject;
 import java.lang.ref.WeakReference;
 
+import javax.inject.Inject;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.viewpager.widget.ViewPager;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.Unbinder;
+
 /**
  * This Fragment is used to display the details about a file.
  */

+ 19 - 15
src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java

@@ -21,6 +21,7 @@
 package com.owncloud.android.ui.fragment;
 
 import android.accounts.Account;
+import android.accounts.AccountManager;
 import android.app.SearchManager;
 import android.content.Context;
 import android.content.res.Resources;
@@ -36,7 +37,17 @@ import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.PopupMenu;
 import android.widget.TextView;
-
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.AppCompatCheckBox;
+import androidx.appcompat.widget.SearchView;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+import butterknife.Unbinder;
 import com.google.android.material.snackbar.Snackbar;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
@@ -63,18 +74,6 @@ import com.owncloud.android.utils.ThemeUtils;
 
 import java.util.List;
 
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.widget.AppCompatCheckBox;
-import androidx.appcompat.widget.SearchView;
-import androidx.fragment.app.Fragment;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnClick;
-import butterknife.Unbinder;
-
 public class FileDetailSharingFragment extends Fragment implements UserListAdapter.ShareeListAdapterListener,
     DisplayUtils.AvatarGenerationListener {
 
@@ -222,6 +221,7 @@ public class FileDetailSharingFragment extends Fragment implements UserListAdapt
             ThemeUtils.themeSearchView(getContext(), searchView, false);
         } else {
             searchView.setVisibility(View.GONE);
+            shareByLinkContainer.setVisibility(View.GONE);
             noList.setText(R.string.reshare_not_allowed);
         }
     }
@@ -296,9 +296,13 @@ public class FileDetailSharingFragment extends Fragment implements UserListAdapt
         // TODO Refactoring: create a new {@link ShareUserListAdapter} instance with every call should not be needed
 
         if (shares.size() > 0) {
+            AccountManager accountManager = AccountManager.get(getContext());
+            String userId = accountManager.getUserData(account,
+                com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
+
             usersList.setVisibility(View.VISIBLE);
-            usersList.setAdapter(new UserListAdapter(fileDisplayActivity.getSupportFragmentManager(), fileDisplayActivity, shares,
-                account, file, this));
+            usersList.setAdapter(new UserListAdapter(fileDisplayActivity.getSupportFragmentManager(),
+                fileDisplayActivity, shares, account, file, this, userId));
             usersList.setLayoutManager(new LinearLayoutManager(getContext()));
             usersList.addItemDecoration(new SimpleListItemDividerDecoration(getContext()));
             noList.setVisibility(View.GONE);

+ 1 - 0
src/main/java/com/owncloud/android/utils/FileStorageUtils.java

@@ -210,6 +210,7 @@ public final class FileStorageUtils {
         file.setOwnerId(remote.getOwnerId());
         file.setOwnerDisplayName(remote.getOwnerDisplayName());
         file.setNote(remote.getNote());
+        file.setSharees(remote.getSharees());
 
         return file;
     }

+ 9 - 0
src/main/res/drawable/ic_people.xml

@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M16,11c1.66,0 2.99,-1.34 2.99,-3S17.66,5 16,5c-1.66,0 -3,1.34 -3,3s1.34,3 3,3zM8,11c1.66,0 2.99,-1.34 2.99,-3S9.66,5 8,5C6.34,5 5,6.34 5,8s1.34,3 3,3zM8,13c-2.33,0 -7,1.17 -7,3.5L1,19h14v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5zM16,13c-0.29,0 -0.62,0.02 -0.97,0.05 1.16,0.84 1.97,1.97 1.97,3.45L17,19h6v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5z"/>
+</vector>

+ 37 - 38
src/main/res/layout/list_item.xml

@@ -17,14 +17,14 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/ListItemLayout"
-    android:layout_width="match_parent"
-    android:layout_height="@dimen/standard_list_item_size"
-    android:background="@drawable/list_selector"
-    android:descendantFocusability="blocksDescendants"
-    android:foreground="?android:attr/selectableItemBackground"
-    android:baselineAligned="false"
-    android:orientation="horizontal">
+              android:id="@+id/ListItemLayout"
+              android:layout_width="match_parent"
+              android:layout_height="@dimen/standard_list_item_size"
+              android:background="@drawable/list_selector"
+              android:descendantFocusability="blocksDescendants"
+              android:foreground="?android:attr/selectableItemBackground"
+              android:baselineAligned="false"
+              android:orientation="horizontal">
 
     <RelativeLayout
         android:layout_width="@dimen/standard_list_item_size"
@@ -44,7 +44,7 @@
             android:layout_marginLeft="@dimen/standard_half_margin"
             android:layout_marginStart="@dimen/standard_half_margin"
             android:contentDescription="@null"
-            android:src="@drawable/folder" />
+            android:src="@drawable/folder"/>
 
         <ImageView
             android:id="@+id/favorite_action"
@@ -58,18 +58,18 @@
             android:contentDescription="@string/favorite"
             android:src="@drawable/favorite"/>
 
-            <ImageView
-                android:id="@+id/localFileIndicator"
-                android:layout_width="@dimen/list_item_local_file_indicator_layout_width"
-                android:layout_height="@dimen/list_item_local_file_indicator_layout_height"
-                android:layout_alignParentBottom="true"
-                android:layout_alignParentEnd="true"
-                android:layout_alignParentRight="true"
-                android:layout_marginEnd="@dimen/standard_quarter_margin"
-                android:layout_marginRight="@dimen/standard_quarter_margin"
-                android:contentDescription="@string/downloader_download_succeeded_ticker"
-                android:scaleType="fitCenter"
-                android:src="@drawable/ic_synced" />
+        <ImageView
+            android:id="@+id/localFileIndicator"
+            android:layout_width="@dimen/list_item_local_file_indicator_layout_width"
+            android:layout_height="@dimen/list_item_local_file_indicator_layout_height"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentEnd="true"
+            android:layout_alignParentRight="true"
+            android:layout_marginEnd="@dimen/standard_quarter_margin"
+            android:layout_marginRight="@dimen/standard_quarter_margin"
+            android:contentDescription="@string/downloader_download_succeeded_ticker"
+            android:scaleType="fitCenter"
+            android:src="@drawable/ic_synced"/>
 
     </RelativeLayout>
 
@@ -90,7 +90,7 @@
             android:singleLine="true"
             android:text="@string/placeholder_filename"
             android:textColor="@color/textColor"
-            android:textSize="@dimen/two_line_primary_text_size" />
+            android:textSize="@dimen/two_line_primary_text_size"/>
 
         <LinearLayout
             android:layout_width="match_parent"
@@ -103,7 +103,7 @@
                 android:layout_height="wrap_content"
                 android:text="@string/placeholder_fileSize"
                 android:textColor="@color/list_item_lastmod_and_filesize_text"
-                android:textSize="@dimen/two_line_secondary_text_size" />
+                android:textSize="@dimen/two_line_secondary_text_size"/>
 
             <TextView
                 android:id="@+id/file_separator"
@@ -116,7 +116,7 @@
                 android:paddingStart="@dimen/zero"
                 android:text="@string/info_separator"
                 android:textColor="@color/list_item_lastmod_and_filesize_text"
-                android:textSize="@dimen/two_line_secondary_text_size" />
+                android:textSize="@dimen/two_line_secondary_text_size"/>
 
             <TextView
                 android:id="@+id/last_mod"
@@ -125,7 +125,7 @@
                 android:gravity="end"
                 android:text="@string/placeholder_media_time"
                 android:textColor="@color/list_item_lastmod_and_filesize_text"
-                android:textSize="@dimen/two_line_secondary_text_size" />
+                android:textSize="@dimen/two_line_secondary_text_size"/>
 
         </LinearLayout>
 
@@ -133,7 +133,7 @@
 
     <RelativeLayout
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
+        android:layout_height="match_parent"
         android:layout_gravity="center_vertical"
         android:paddingEnd="@dimen/zero"
         android:paddingLeft="@dimen/standard_half_padding"
@@ -169,28 +169,27 @@
             android:paddingLeft="@dimen/standard_half_padding"
             android:paddingRight="@dimen/list_item_share_right_margin"
             android:paddingStart="@dimen/standard_half_padding"
-            android:src="@drawable/ic_unshared" />
+            android:src="@drawable/ic_unshared"/>
 
-        <ImageView
-            android:id="@+id/sharedAvatar"
-            android:layout_width="@dimen/file_icon_size"
+        <RelativeLayout
+            android:id="@+id/sharedAvatars"
+            android:layout_width="100dp"
             android:layout_height="@dimen/file_icon_size"
             android:layout_centerVertical="true"
+            android:layout_alignRight="@id/sharedIcon"
+            android:layout_alignEnd="@id/sharedIcon"
             android:layout_toEndOf="@id/sharedIcon"
             android:layout_toRightOf="@id/sharedIcon"
             android:contentDescription="@string/shared_avatar_desc"
-            android:clickable="true"
-            android:focusable="true"
-            android:src="@drawable/ic_user"
-            android:visibility="gone" />
+            android:visibility="visible"/>
 
         <ImageView
             android:id="@+id/custom_checkbox"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
             android:layout_centerVertical="true"
-            android:layout_toEndOf="@id/sharedAvatar"
-            android:layout_toRightOf="@id/sharedAvatar"
+            android:layout_toEndOf="@id/sharedAvatars"
+            android:layout_toRightOf="@id/sharedAvatars"
             android:clickable="false"
             android:contentDescription="@string/checkbox"
             android:focusable="false"
@@ -198,7 +197,7 @@
             android:paddingLeft="@dimen/standard_half_padding"
             android:paddingRight="@dimen/alternate_padding"
             android:paddingStart="@dimen/standard_half_padding"
-            android:src="@drawable/ic_checkbox_blank_outline" />
+            android:src="@drawable/ic_checkbox_blank_outline"/>
 
         <ImageView
             android:id="@+id/overflow_menu"
@@ -214,7 +213,7 @@
             android:paddingLeft="@dimen/standard_half_padding"
             android:paddingRight="@dimen/alternate_padding"
             android:paddingStart="@dimen/standard_half_padding"
-            android:src="@drawable/ic_dots_vertical" />
+            android:src="@drawable/ic_dots_vertical"/>
 
     </RelativeLayout>