diff --git a/scripts/analysis/findbugs-results.txt b/scripts/analysis/findbugs-results.txt index 6efca19ea0b6..1448fd8565ef 100644 --- a/scripts/analysis/findbugs-results.txt +++ b/scripts/analysis/findbugs-results.txt @@ -1 +1 @@ -481 \ No newline at end of file +483 diff --git a/src/main/java/com/owncloud/android/authentication/AccountUtils.java b/src/main/java/com/owncloud/android/authentication/AccountUtils.java index 138492656f17..5ffb8ec759bf 100644 --- a/src/main/java/com/owncloud/android/authentication/AccountUtils.java +++ b/src/main/java/com/owncloud/android/authentication/AccountUtils.java @@ -25,9 +25,11 @@ import android.content.SharedPreferences; import android.net.Uri; import android.preference.PreferenceManager; +import android.text.TextUtils; import com.owncloud.android.MainApp; import com.owncloud.android.datamodel.ArbitraryDataProvider; +import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.lib.common.OwnCloudAccount; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; @@ -344,4 +346,14 @@ private static Account migrateAccount(Context context, Account currentAccount, A // will assume it succeeds, not a big deal otherwise return newAccount; } + + /** + * Checks if an account owns the file (file's ownerId is the same as account name) + * @param file File to check + * @param account account to compare + * @return false if ownerId is not set or owner is a different account + */ + public static boolean accountOwnsFile(OCFile file, Account account) { + return !TextUtils.isEmpty(file.getOwnerId()) && account.name.split("@")[0].equals(file.getOwnerId()); + } } diff --git a/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java index be03b333c882..0c4148b8468c 100644 --- a/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -205,6 +205,8 @@ public boolean saveFile(OCFile file) { cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading()); cv.put(ProviderTableMeta.FILE_ETAG_IN_CONFLICT, file.getEtagInConflict()); cv.put(ProviderTableMeta.FILE_UNREAD_COMMENTS_COUNT, file.getUnreadCommentsCount()); + cv.put(ProviderTableMeta.FILE_OWNER_ID, file.getOwnerId()); + cv.put(ProviderTableMeta.FILE_OWNER_DISPLAY_NAME, file.getOwnerDisplayName()); boolean sameRemotePath = fileExists(file.getRemotePath()); if (sameRemotePath || @@ -443,6 +445,8 @@ private ContentValues createContentValueForFile(OCFile folder) { cv.put(ProviderTableMeta.FILE_FAVORITE, folder.isFavorite()); cv.put(ProviderTableMeta.FILE_IS_ENCRYPTED, folder.isEncrypted()); cv.put(ProviderTableMeta.FILE_UNREAD_COMMENTS_COUNT, folder.getUnreadCommentsCount()); + cv.put(ProviderTableMeta.FILE_OWNER_ID, folder.getOwnerId()); + cv.put(ProviderTableMeta.FILE_OWNER_DISPLAY_NAME, folder.getOwnerDisplayName()); return cv; } @@ -479,6 +483,8 @@ private ContentValues createContentValueForFile(OCFile file, OCFile folder) { cv.put(ProviderTableMeta.FILE_MOUNT_TYPE, file.getMountType().ordinal()); cv.put(ProviderTableMeta.FILE_HAS_PREVIEW, file.isPreviewAvailable() ? 1 : 0); cv.put(ProviderTableMeta.FILE_UNREAD_COMMENTS_COUNT, file.getUnreadCommentsCount()); + cv.put(ProviderTableMeta.FILE_OWNER_ID, file.getOwnerId()); + cv.put(ProviderTableMeta.FILE_OWNER_DISPLAY_NAME, file.getOwnerDisplayName()); return cv; } @@ -975,6 +981,8 @@ private OCFile createFileInstance(Cursor c) { c.getColumnIndex(ProviderTableMeta.FILE_MOUNT_TYPE))]); file.setPreviewAvailable(c.getInt(c.getColumnIndex(ProviderTableMeta.FILE_HAS_PREVIEW)) == 1); file.setUnreadCommentsCount(c.getInt(c.getColumnIndex(ProviderTableMeta.FILE_UNREAD_COMMENTS_COUNT))); + file.setOwnerId(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_OWNER_ID))); + file.setOwnerDisplayName(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_OWNER_DISPLAY_NAME))); } return file; diff --git a/src/main/java/com/owncloud/android/datamodel/OCFile.java b/src/main/java/com/owncloud/android/datamodel/OCFile.java index 512fe5350e59..8edaa7c3058f 100644 --- a/src/main/java/com/owncloud/android/datamodel/OCFile.java +++ b/src/main/java/com/owncloud/android/datamodel/OCFile.java @@ -84,9 +84,9 @@ public class OCFile implements Parcelable, Comparable, ServerFileInterfa @Getter @Setter private boolean favorite; @Getter @Setter private boolean encrypted; @Getter @Setter private WebdavEntry.MountType mountType; - @Getter - @Setter - private int unreadCommentsCount; + @Getter @Setter private int unreadCommentsCount; + @Getter @Setter private String ownerId; + @Getter @Setter private String ownerDisplayName; /** * URI to the local path of the file contents, if stored in the device; cached after first call diff --git a/src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java b/src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java index f76b6208edde..d6fc8585c214 100644 --- a/src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java +++ b/src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java @@ -64,6 +64,7 @@ import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.GetMethod; +import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.FileNotFoundException; @@ -858,7 +859,7 @@ private int getAvatarDimension() { return Math.round(r.getDimension(R.dimen.file_avatar_size)); } - private @Nullable + private @NotNull Drawable doAvatarInBackground() { Bitmap avatar = null; @@ -923,7 +924,6 @@ Drawable doAvatarInBackground() { // everything else mClient.exhaustResponse(get.getResponseBodyAsStream()); break; - } } catch (Exception e) { try { @@ -936,15 +936,17 @@ Drawable doAvatarInBackground() { get.releaseConnection(); } } + } + if (avatar == null) { try { return TextDrawable.createAvatar(mAccount.name, mAvatarRadius); - } catch (Exception e) { - Log_OC.e(TAG, "Error generating fallback avatar"); + } catch (Exception e1) { + return mResources.getDrawable(R.drawable.ic_user); } + } else { + return BitmapUtils.bitmapToCircularBitmapDrawable(mResources, avatar); } - - return BitmapUtils.bitmapToCircularBitmapDrawable(mResources, avatar); } } diff --git a/src/main/java/com/owncloud/android/db/ProviderMeta.java b/src/main/java/com/owncloud/android/db/ProviderMeta.java index 0b7e4c8406dd..b19caa4b2df1 100644 --- a/src/main/java/com/owncloud/android/db/ProviderMeta.java +++ b/src/main/java/com/owncloud/android/db/ProviderMeta.java @@ -32,7 +32,7 @@ public class ProviderMeta { public static final String DB_NAME = "filelist"; - public static final int DB_VERSION = 42; + public static final int DB_VERSION = 43; private ProviderMeta() { } @@ -106,6 +106,8 @@ static public class ProviderTableMeta implements BaseColumns { public static final String FILE_MOUNT_TYPE = "mount_type"; public static final String FILE_HAS_PREVIEW = "has_preview"; public static final String FILE_UNREAD_COMMENTS_COUNT = "unread_comments_count"; + 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_ALL_COLUMNS = { _ID, FILE_PARENT, FILE_NAME, FILE_CREATION, FILE_MODIFIED, diff --git a/src/main/java/com/owncloud/android/providers/FileContentProvider.java b/src/main/java/com/owncloud/android/providers/FileContentProvider.java index 450edb203a01..9e40cdd84c56 100644 --- a/src/main/java/com/owncloud/android/providers/FileContentProvider.java +++ b/src/main/java/com/owncloud/android/providers/FileContentProvider.java @@ -698,7 +698,9 @@ private void createFilesTable(SQLiteDatabase db) { + ProviderTableMeta.FILE_SHARED_WITH_SHAREE + INTEGER + ProviderTableMeta.FILE_MOUNT_TYPE + INTEGER + ProviderTableMeta.FILE_HAS_PREVIEW + INTEGER - + ProviderTableMeta.FILE_UNREAD_COMMENTS_COUNT + " INTEGER);" + + ProviderTableMeta.FILE_UNREAD_COMMENTS_COUNT + INTEGER + + ProviderTableMeta.FILE_OWNER_ID + TEXT + + ProviderTableMeta.FILE_OWNER_DISPLAY_NAME + " TEXT);" ); } @@ -1860,6 +1862,26 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if (!upgraded) { Log_OC.i(SQL, String.format(Locale.ENGLISH, UPGRADE_VERSION_MSG, oldVersion, newVersion)); } + + if (oldVersion < 43 && newVersion >= 43) { + Log_OC.i(SQL, "Entering in the #43 add ownerId and owner display name to file table"); + db.beginTransaction(); + try { + db.execSQL(ALTER_TABLE + ProviderTableMeta.FILE_TABLE_NAME + + ADD_COLUMN + ProviderTableMeta.FILE_OWNER_ID + " TEXT "); + db.execSQL(ALTER_TABLE + ProviderTableMeta.FILE_TABLE_NAME + + ADD_COLUMN + ProviderTableMeta.FILE_OWNER_DISPLAY_NAME + " TEXT "); + + upgraded = true; + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + } + + if (!upgraded) { + Log_OC.i(SQL, String.format(Locale.ENGLISH, UPGRADE_VERSION_MSG, oldVersion, newVersion)); + } } @Override diff --git a/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java b/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java index a4bd5486010d..e84282a4f445 100644 --- a/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java +++ b/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java @@ -22,67 +22,76 @@ package com.owncloud.android.ui.adapter; -import android.accounts.Account; -import android.content.ContentValues; -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.Color; -import android.os.Handler; -import android.os.Looper; -import android.text.TextUtils; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Filter; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.owncloud.android.R; -import com.owncloud.android.authentication.AccountUtils; -import com.owncloud.android.datamodel.FileDataStorageManager; -import com.owncloud.android.datamodel.OCFile; -import com.owncloud.android.datamodel.ThumbnailsCacheManager; -import com.owncloud.android.datamodel.VirtualFolderType; -import com.owncloud.android.db.PreferenceManager; -import com.owncloud.android.db.ProviderMeta; -import com.owncloud.android.files.services.FileDownloader; -import com.owncloud.android.files.services.FileUploader; -import com.owncloud.android.lib.common.operations.RemoteOperation; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; -import com.owncloud.android.lib.resources.files.ReadFileRemoteOperation; -import com.owncloud.android.lib.resources.files.model.RemoteFile; -import com.owncloud.android.lib.resources.shares.OCShare; -import com.owncloud.android.lib.resources.shares.ShareType; -import com.owncloud.android.operations.RefreshFolderOperation; -import com.owncloud.android.operations.RemoteOperationFailedException; -import com.owncloud.android.services.OperationsService; -import com.owncloud.android.ui.activity.ComponentsGetter; -import com.owncloud.android.ui.fragment.ExtendedListFragment; -import com.owncloud.android.ui.interfaces.OCFileListFragmentInterface; -import com.owncloud.android.utils.DisplayUtils; -import com.owncloud.android.utils.FileSortOrder; -import com.owncloud.android.utils.FileStorageUtils; -import com.owncloud.android.utils.MimeTypeUtil; -import com.owncloud.android.utils.ThemeUtils; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; -import java.util.Vector; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -/** + import android.accounts.Account; + import android.content.ContentValues; + import android.content.Context; + import android.content.res.Resources; + import android.graphics.Bitmap; + import android.graphics.Color; + import android.graphics.drawable.Drawable; + import android.os.Handler; + import android.os.Looper; + import android.text.TextUtils; + import android.view.LayoutInflater; + import android.view.View; + import android.view.ViewGroup; + import android.widget.Filter; + import android.widget.ImageView; + import android.widget.LinearLayout; + import android.widget.TextView; + + import com.bumptech.glide.Glide; + import com.bumptech.glide.request.target.BitmapImageViewTarget; + import com.owncloud.android.R; + import com.owncloud.android.authentication.AccountUtils; + import com.owncloud.android.datamodel.FileDataStorageManager; + import com.owncloud.android.datamodel.OCFile; + import com.owncloud.android.datamodel.ThumbnailsCacheManager; + import com.owncloud.android.datamodel.VirtualFolderType; + import com.owncloud.android.db.PreferenceManager; + import com.owncloud.android.db.ProviderMeta; + import com.owncloud.android.files.services.FileDownloader; + import com.owncloud.android.files.services.FileUploader; + import com.owncloud.android.lib.common.operations.RemoteOperation; + import com.owncloud.android.lib.common.operations.RemoteOperationResult; + import com.owncloud.android.lib.common.utils.Log_OC; + import com.owncloud.android.lib.resources.files.ReadFileRemoteOperation; + import com.owncloud.android.lib.resources.files.model.RemoteFile; + import com.owncloud.android.lib.resources.shares.OCShare; + import com.owncloud.android.lib.resources.shares.ShareType; + import com.owncloud.android.operations.RefreshFolderOperation; + import com.owncloud.android.operations.RemoteOperationFailedException; + import com.owncloud.android.services.OperationsService; + import com.owncloud.android.ui.TextDrawable; + import com.owncloud.android.ui.activity.ComponentsGetter; + import com.owncloud.android.ui.fragment.ExtendedListFragment; + import com.owncloud.android.ui.interfaces.OCFileListFragmentInterface; + import com.owncloud.android.utils.DisplayUtils; + import com.owncloud.android.utils.FileSortOrder; + import com.owncloud.android.utils.FileStorageUtils; + import com.owncloud.android.utils.MimeTypeUtil; + import com.owncloud.android.utils.ThemeUtils; + + import java.io.File; + import java.util.ArrayList; + import java.util.HashSet; + import java.util.List; + import java.util.Locale; + import java.util.Set; + import java.util.Vector; + + import androidx.annotation.NonNull; + import androidx.core.graphics.drawable.RoundedBitmapDrawable; + import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + import androidx.recyclerview.widget.RecyclerView; + import butterknife.BindView; + import butterknife.ButterKnife; + + /** * This Adapter populates a RecyclerView with all files and folders in a Nextcloud instance. */ -public class OCFileListAdapter extends RecyclerView.Adapter { +public class OCFileListAdapter extends RecyclerView.Adapter + implements DisplayUtils.AvatarGenerationListener { private static final int showFilenameColumnThreshold = 4; private final FileDownloader.FileDownloaderBinder downloaderBinder; @@ -308,6 +317,27 @@ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int positi if (holder instanceof OCFileListItemViewHolder) { OCFileListItemViewHolder itemViewHolder = (OCFileListItemViewHolder) holder; + if (file.isSharedWithMe() && !multiSelect && !gridView && !mHideItemOptions) { + itemViewHolder.sharedAvatar.setVisibility(View.VISIBLE); + + Resources resources = mContext.getResources(); + + float avatarRadius = resources.getDimension(R.dimen.list_item_avatar_icon_radius); + + if (file.getOwnerId().contains("@")) { + showFederatedShareAvatar(file, avatarRadius, resources, itemViewHolder); + } else { + itemViewHolder.sharedAvatar.setTag(file.getOwnerId()); + DisplayUtils.setAvatar(mAccount, file.getOwnerId(), this, avatarRadius, resources, + itemViewHolder.sharedAvatar, mContext); + } + + itemViewHolder.sharedAvatar.setOnClickListener(view -> + ocFileListFragmentInterface.showShareDetailView(file)); + } else { + itemViewHolder.sharedAvatar.setVisibility(View.GONE); + } + if (onlyOnDevice) { File localFile = new File(file.getStoragePath()); @@ -393,6 +423,39 @@ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int positi } } + private void showFederatedShareAvatar(OCFile file, float avatarRadius, Resources resources, + OCFileListItemViewHolder itemViewHolder) { + // maybe federated share + String userId = file.getOwnerId().split("@")[0]; + String server = file.getOwnerId().split("@")[1]; + + String url = "https://" + server + "/avatar/" + userId + "/" + + DisplayUtils.convertDpToPixel(avatarRadius, mContext); + + Drawable placeholder; + try { + placeholder = TextDrawable.createAvatarByUserId(userId, avatarRadius); + } catch (Exception e) { + Log_OC.e(TAG, "Error calculating RGB value for active account icon.", e); + placeholder = resources.getDrawable(R.drawable.account_circle_white); + } + + itemViewHolder.sharedAvatar.setTag(null); + Glide.with(mContext).load(url) + .asBitmap() + .placeholder(placeholder) + .error(placeholder) + .into(new BitmapImageViewTarget(itemViewHolder.sharedAvatar) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory.create(mContext.getResources(), resource); + circularBitmapDrawable.setCircular(true); + itemViewHolder.sharedAvatar.setImageDrawable(circularBitmapDrawable); + } + }); + } + private void setThumbnail(OCFile file, ImageView thumbnailView) { if (file.isFolder()) { thumbnailView.setImageDrawable(MimeTypeUtil.getFolderTypeIcon(file.isSharedWithMe() || @@ -513,9 +576,11 @@ private void showShareIcon(OCFileListGridImageViewHolder gridViewHolder, OCFile if (gridViewHolder instanceof OCFileListItemViewHolder || file.getUnreadCommentsCount() == 0) { sharedIconView.setVisibility(View.VISIBLE); - if (file.isSharedWithSharee() || file.isSharedWithMe()) { + 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); } else if (file.isSharedViaLink()) { sharedIconView.setImageResource(R.drawable.shared_via_link); sharedIconView.setContentDescription(mContext.getString(R.string.shared_icon_shared_via_link)); @@ -523,7 +588,11 @@ private void showShareIcon(OCFileListGridImageViewHolder gridViewHolder, OCFile sharedIconView.setImageResource(R.drawable.ic_unshared); sharedIconView.setContentDescription(mContext.getString(R.string.shared_icon_share)); } - sharedIconView.setOnClickListener(view -> ocFileListFragmentInterface.onShareIconClick(file)); + if (AccountUtils.accountOwnsFile(file, mAccount)) { + sharedIconView.setOnClickListener(view -> ocFileListFragmentInterface.onShareIconClick(file)); + } else { + sharedIconView.setOnClickListener(view -> ocFileListFragmentInterface.showShareDetailView(file)); + } } else { sharedIconView.setVisibility(View.GONE); } @@ -732,6 +801,16 @@ public Filter getFilter() { return mFilesFilter; } + @Override + public void avatarGenerated(Drawable avatarDrawable, Object callContext) { + ((ImageView) callContext).setImageDrawable(avatarDrawable); + } + + @Override + public boolean shouldCallGeneratedCallback(String tag, Object callContext) { + return ((ImageView) callContext).getTag().equals(tag); + } + private class FilesFilter extends Filter { @Override @@ -825,59 +904,69 @@ public void setGridView(boolean bool) { gridView = bool; } - private static class OCFileListItemViewHolder extends OCFileListGridItemViewHolder { - private final TextView fileSize; - private final TextView lastModification; - private final ImageView overflowMenu; + static class OCFileListItemViewHolder extends OCFileListGridItemViewHolder { + @BindView(R.id.file_size) + public TextView fileSize; + + @BindView(R.id.last_mod) + public TextView lastModification; + + @BindView(R.id.overflow_menu) + public ImageView overflowMenu; + + @BindView(R.id.sharedAvatar) + public ImageView sharedAvatar; private OCFileListItemViewHolder(View itemView) { super(itemView); - - fileSize = itemView.findViewById(R.id.file_size); - lastModification = itemView.findViewById(R.id.last_mod); - overflowMenu = itemView.findViewById(R.id.overflow_menu); + ButterKnife.bind(this, itemView); } } - static class OCFileListGridItemViewHolder extends OCFileListGridImageViewHolder { - private final TextView fileName; + static class OCFileListGridItemViewHolder extends OCFileListGridImageViewHolder { + @BindView(R.id.Filename) public TextView fileName; private OCFileListGridItemViewHolder(View itemView) { super(itemView); - - fileName = itemView.findViewById(R.id.Filename); + ButterKnife.bind(this, itemView); } } - static class OCFileListGridImageViewHolder extends RecyclerView.ViewHolder { - private final ImageView thumbnail; - private final ImageView favorite; - private final ImageView localFileIndicator; - private final ImageView shared; - private final ImageView checkbox; - final ImageView unreadComments; - private final LinearLayout itemLayout; + static class OCFileListGridImageViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.thumbnail) + public ImageView thumbnail; + + @BindView(R.id.favorite_action) + public ImageView favorite; + + @BindView(R.id.localFileIndicator) + public ImageView localFileIndicator; + + @BindView(R.id.sharedIcon) + public ImageView shared; + + @BindView(R.id.custom_checkbox) + public ImageView checkbox; + + @BindView(R.id.ListItemLayout) + public LinearLayout itemLayout; + + @BindView(R.id.unreadComments) + public ImageView unreadComments; private OCFileListGridImageViewHolder(View itemView) { super(itemView); - - thumbnail = itemView.findViewById(R.id.thumbnail); - favorite = itemView.findViewById(R.id.favorite_action); - localFileIndicator = itemView.findViewById(R.id.localFileIndicator); - shared = itemView.findViewById(R.id.sharedIcon); - checkbox = itemView.findViewById(R.id.custom_checkbox); - unreadComments = itemView.findViewById(R.id.unreadComments); - itemLayout = itemView.findViewById(R.id.ListItemLayout); + ButterKnife.bind(this, itemView); } } - private static class OCFileListFooterViewHolder extends RecyclerView.ViewHolder { - private final TextView footerText; + static class OCFileListFooterViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.footerText) + public TextView footerText; private OCFileListFooterViewHolder(View itemView) { super(itemView); - - footerText = itemView.findViewById(R.id.footerText); + ButterKnife.bind(this, itemView); } } } diff --git a/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java b/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java index 3250c47ca6b9..bd505c89301d 100644 --- a/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java +++ b/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java @@ -24,6 +24,7 @@ import android.app.SearchManager; import android.content.Context; import android.content.res.Resources; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.text.TextUtils; import android.view.LayoutInflater; @@ -38,6 +39,7 @@ import com.google.android.material.snackbar.Snackbar; import com.owncloud.android.R; +import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.lib.common.operations.RemoteOperationResult; @@ -73,7 +75,8 @@ import butterknife.OnClick; import butterknife.Unbinder; -public class FileDetailSharingFragment extends Fragment implements UserListAdapter.ShareeListAdapterListener { +public class FileDetailSharingFragment extends Fragment implements UserListAdapter.ShareeListAdapterListener, + DisplayUtils.AvatarGenerationListener { private static final String ARG_FILE = "FILE"; private static final String ARG_ACCOUNT = "ACCOUNT"; @@ -86,6 +89,10 @@ public class FileDetailSharingFragment extends Fragment implements UserListAdapt private OCCapability capabilities; private OCShare publicShare; + private FileOperationsHelper fileOperationsHelper; + private FileDisplayActivity fileDisplayActivity; + private FileDataStorageManager fileDataStorageManager; + private Unbinder unbinder; @BindView(R.id.searchView) @@ -112,9 +119,14 @@ public class FileDetailSharingFragment extends Fragment implements UserListAdapt @BindView(R.id.share_by_link_container) LinearLayout shareByLinkContainer; - private FileOperationsHelper fileOperationsHelper; - private FileDisplayActivity fileDisplayActivity; - private FileDataStorageManager fileDataStorageManager; + @BindView(R.id.shared_with_you_container) + LinearLayout sharedWithYouContainer; + + @BindView(R.id.shared_with_you_avatar) + ImageView sharedWithYouAvatar; + + @BindView(R.id.shared_with_you_username) + TextView sharedWithYouUsername; public static FileDetailSharingFragment newInstance(OCFile file, Account account) { FileDetailSharingFragment fragment = new FileDetailSharingFragment(); @@ -198,6 +210,7 @@ public void onAttach(Context context) { private void setupView() { setShareByLinkInfo(file.isSharedViaLink()); setShareWithUserInfo(); + setShareWithYou(); FileDetailSharingFragmentHelper.setupSearchView( (SearchManager) fileDisplayActivity.getSystemService(Context.SEARCH_SERVICE), searchView, fileDisplayActivity.getComponentName()); @@ -246,6 +259,20 @@ public void setShareWithUserInfo() { updateListOfUserGroups(); } + private void setShareWithYou() { + if (AccountUtils.accountOwnsFile(file, account)) { + sharedWithYouContainer.setVisibility(View.GONE); + } else { + sharedWithYouUsername.setText( + String.format(getString(R.string.shared_with_you_by), file.getOwnerDisplayName())); + + DisplayUtils.setAvatar(account, file.getOwnerId(), this, getResources().getDimension( + R.dimen.file_list_item_avatar_icon_radius), getResources(), sharedWithYouAvatar, + getContext()); + sharedWithYouAvatar.setVisibility(View.VISIBLE); + } + } + private void updateListOfUserGroups() { // TODO Refactoring: create a new {@link ShareUserListAdapter} instance with every call should not be needed @@ -546,4 +573,14 @@ public void onSaveInstanceState(@NonNull Bundle outState) { outState.putParcelable(FileActivity.EXTRA_FILE, file); outState.putParcelable(FileActivity.EXTRA_ACCOUNT, account); } + + @Override + public void avatarGenerated(Drawable avatarDrawable, Object callContext) { + sharedWithYouAvatar.setImageDrawable(avatarDrawable); + } + + @Override + public boolean shouldCallGeneratedCallback(String tag, Object callContext) { + return false; + } } diff --git a/src/main/java/com/owncloud/android/utils/FileStorageUtils.java b/src/main/java/com/owncloud/android/utils/FileStorageUtils.java index 128d0675f90e..fff023035fd0 100644 --- a/src/main/java/com/owncloud/android/utils/FileStorageUtils.java +++ b/src/main/java/com/owncloud/android/utils/FileStorageUtils.java @@ -207,6 +207,8 @@ public static OCFile fillOCFile(RemoteFile remote) { file.setMountType(remote.getMountType()); file.setPreviewAvailable(remote.isHasPreview()); file.setUnreadCommentsCount(remote.getUnreadCommentsCount()); + file.setOwnerId(remote.getOwnerId()); + file.setOwnerDisplayName(remote.getOwnerDisplayName()); return file; } diff --git a/src/main/res/layout/file_details_sharing_fragment.xml b/src/main/res/layout/file_details_sharing_fragment.xml index a0038e6ff37d..cff9cc56f608 100644 --- a/src/main/res/layout/file_details_sharing_fragment.xml +++ b/src/main/res/layout/file_details_sharing_fragment.xml @@ -34,12 +34,46 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/searchView" - android:hint="@string/share_search" android:layout_marginStart="@dimen/standard_eighth_margin" android:layout_marginLeft="@dimen/standard_eighth_margin" android:layout_marginEnd="@dimen/standard_margin" android:layout_marginRight="@dimen/standard_margin" - style="@style/ownCloud.SearchView" /> + style="@style/ownCloud.SearchView" + android:hint="@string/share_search"/> + + + + + + + + + + + android:src="@drawable/ic_dots_vertical"/> + android:textSize="16sp"/> diff --git a/src/main/res/layout/list_item.xml b/src/main/res/layout/list_item.xml index 04fd0c82d524..551355e34730 100644 --- a/src/main/res/layout/list_item.xml +++ b/src/main/res/layout/list_item.xml @@ -171,13 +171,26 @@ android:paddingStart="@dimen/standard_half_padding" android:src="@drawable/ic_unshared" /> + + 20dp 20dp 12dp + 10dp 72dp 0dp 72dp diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 7aa662fff3af..d314196a0570 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -873,4 +873,6 @@ IO error Operation has been canceled Authentication Exception + Avatar from shared user + Shared with you by %1$s