Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 612e4005 authored by alperozturk's avatar alperozturk
Browse files

add viewholders

parent 9f825a8d
Loading
Loading
Loading
Loading
+29 −17
Original line number Diff line number Diff line
@@ -29,6 +29,9 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.google.android.material.snackbar.Snackbar;
import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.lib.resources.shares.OCShare;
import com.owncloud.android.lib.resources.shares.ShareType;

import java.util.ArrayList;
import java.util.List;
@@ -39,13 +42,13 @@ import it.niedermann.owncloud.notes.branding.BrandedSnackbar;
import it.niedermann.owncloud.notes.databinding.FragmentNoteShareBinding;
import it.niedermann.owncloud.notes.persistence.entity.Account;
import it.niedermann.owncloud.notes.persistence.entity.Note;
import it.niedermann.owncloud.notes.share.adapter.ShareeListAdapter;
import it.niedermann.owncloud.notes.share.listener.ShareeListAdapterListener;
import it.niedermann.owncloud.notes.shared.user.User;
import it.niedermann.owncloud.notes.shared.util.ClipboardUtil;
import it.niedermann.owncloud.notes.shared.util.extensions.BundleExtensionsKt;

public class NoteShareFragment extends Fragment implements ShareeListAdapterListener,
        DisplayUtils.AvatarGenerationListener,
        Injectable, FileDetailsSharingMenuBottomSheetActions, QuickSharingPermissionsBottomSheetDialog.QuickPermissionSharingBottomSheetActions {
public class NoteShareFragment extends Fragment implements ShareeListAdapterListener {

    private static final String TAG = "NoteShareFragment";
    private static final String ARG_NOTE = "NOTE";
@@ -107,11 +110,11 @@ public class NoteShareFragment extends Fragment implements ShareeListAdapterList
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        binding = FragmentNoteShareBinding.inflate(inflater, container, false);

        binding.sharesList.setAdapter(new ShareeListAdapter(fileActivity,
        binding.sharesList.setAdapter(new ShareeListAdapter(requireActivity(),
                new ArrayList<>(),
                this,
                user,
                note));
                account));

        binding.sharesList.setLayoutManager(new LinearLayoutManager(requireContext()));

@@ -223,7 +226,7 @@ public class NoteShareFragment extends Fragment implements ShareeListAdapterList
        }
    }

    private void copyInternalLink() {
    public void copyInternalLink() {
        if (account == null) {
            BrandedSnackbar.make(requireView(), getString(R.string.note_share_fragment_could_not_retrieve_url), Snackbar.LENGTH_LONG)
                    .setAnchorView(binding.sharesList)
@@ -438,7 +441,8 @@ public class NoteShareFragment extends Fragment implements ShareeListAdapterList
        ShareeListAdapter adapter = (ShareeListAdapter) binding.sharesList.getAdapter();

        if (adapter == null) {
            DisplayUtils.showSnackMessage(getView(), getString(R.string.could_not_retrieve_shares));
            BrandedSnackbar.make(requireView(), getString(R.string.could_not_retrieve_shares), Snackbar.LENGTH_LONG)
                    .show();
            return;
        }
        adapter.getShares().clear();
@@ -484,7 +488,8 @@ public class NoteShareFragment extends Fragment implements ShareeListAdapterList
        if (intent.resolveActivity(requireContext().getPackageManager()) != null) {
            onContactSelectionResultLauncher.launch(intent);
        } else {
            DisplayUtils.showSnackMessage(requireActivity(), getString(R.string.file_detail_sharing_fragment_no_contact_app_message));
            BrandedSnackbar.make(requireView(), getString(R.string.file_detail_sharing_fragment_no_contact_app_message), Snackbar.LENGTH_LONG)
                    .show();
        }
    }

@@ -507,16 +512,19 @@ public class NoteShareFragment extends Fragment implements ShareeListAdapterList
                        binding.searchView.requestFocus();
                    });
                } else {
                    DisplayUtils.showSnackMessage(binding.getRoot(), R.string.email_pick_failed);
                    BrandedSnackbar.make(requireView(), getString(R.string.email_pick_failed), Snackbar.LENGTH_LONG)
                            .show();
                    Log_OC.e(NoteShareFragment.class.getSimpleName(), "Failed to pick email address.");
                }
            } else {
                DisplayUtils.showSnackMessage(binding.getRoot(), R.string.email_pick_failed);
                BrandedSnackbar.make(requireView(), getString(R.string.email_pick_failed), Snackbar.LENGTH_LONG)
                        .show();
                Log_OC.e(NoteShareFragment.class.getSimpleName(), "Failed to pick email address as no Email found.");
            }
            cursor.close();
        } else {
            DisplayUtils.showSnackMessage(binding.getRoot(), R.string.email_pick_failed);
            BrandedSnackbar.make(requireView(), getString(R.string.email_pick_failed), Snackbar.LENGTH_LONG)
                    .show();
            Log_OC.e(NoteShareFragment.class.getSimpleName(), "Failed to pick email address as Cursor is null.");
        }
    }
@@ -534,8 +542,8 @@ public class NoteShareFragment extends Fragment implements ShareeListAdapterList
    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        FileExtensionsKt.logFileSize(file, TAG);
        outState.putParcelable(ARG_NOTE, file);
        outState.putSerializable(ARG_NOTE, note);
        outState.putSerializable(ARG_ACCOUNT, account);
        outState.putParcelable(ARG_USER, user);
    }

@@ -576,7 +584,8 @@ public class NoteShareFragment extends Fragment implements ShareeListAdapterList
        unshareWith(share);
        ShareeListAdapter adapter = (ShareeListAdapter) binding.sharesList.getAdapter();
        if (adapter == null) {
            DisplayUtils.showSnackMessage(getView(), getString(R.string.failed_update_ui));
            BrandedSnackbar.make(requireView(), getString(R.string.email_pick_failed), Snackbar.LENGTH_LONG)
                    .show();
            return;
        }
        adapter.remove(share);
@@ -612,7 +621,8 @@ public class NoteShareFragment extends Fragment implements ShareeListAdapterList
                if (isGranted) {
                    pickContactEmail();
                } else {
                    DisplayUtils.showSnackMessage(binding.getRoot(), R.string.contact_no_permission);
                    BrandedSnackbar.make(binding.getRoot(), getString(R.string.contact_no_permission), Snackbar.LENGTH_LONG)
                            .show();
                }
            });

@@ -623,13 +633,15 @@ public class NoteShareFragment extends Fragment implements ShareeListAdapterList
                        if (result.getResultCode() == Activity.RESULT_OK) {
                            Intent intent = result.getData();
                            if (intent == null) {
                                DisplayUtils.showSnackMessage(binding.getRoot(), R.string.email_pick_failed);
                                BrandedSnackbar.make(binding.getRoot(), getString(R.string.email_pick_failed), Snackbar.LENGTH_LONG)
                                        .show();
                                return;
                            }

                            Uri contactUri = intent.getData();
                            if (contactUri == null) {
                                DisplayUtils.showSnackMessage(binding.getRoot(), R.string.email_pick_failed);
                                BrandedSnackbar.make(binding.getRoot(), getString(R.string.email_pick_failed), Snackbar.LENGTH_LONG)
                                        .show();
                                return;
                            }

+193 −0
Original line number Diff line number Diff line
package it.niedermann.owncloud.notes.share.adapter;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.owncloud.android.lib.resources.shares.OCShare;
import com.owncloud.android.lib.resources.shares.ShareType;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.databinding.ItemAddPublicShareBinding;
import it.niedermann.owncloud.notes.databinding.ItemInternalShareLinkBinding;
import it.niedermann.owncloud.notes.databinding.ItemShareLinkShareBinding;
import it.niedermann.owncloud.notes.databinding.ItemShareShareBinding;
import it.niedermann.owncloud.notes.persistence.entity.Account;
import it.niedermann.owncloud.notes.share.adapter.holder.InternalShareViewHolder;
import it.niedermann.owncloud.notes.share.adapter.holder.LinkShareViewHolder;
import it.niedermann.owncloud.notes.share.adapter.holder.NewLinkShareViewHolder;
import it.niedermann.owncloud.notes.share.adapter.holder.ShareViewHolder;
import it.niedermann.owncloud.notes.share.listener.ShareeListAdapterListener;
import it.niedermann.owncloud.notes.shared.user.User;

/**
 * Adapter to show a user/group/email/remote in Sharing list in file details view.
 */
public class ShareeListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private Account account;
    private final ShareeListAdapterListener listener;
    private final Activity activity;
    private List<OCShare> shares;
    private final float avatarRadiusDimension;
    private final User user;

    public ShareeListAdapter(Activity activity,
                             List<OCShare> shares,
                             ShareeListAdapterListener listener,
                             User user,
                             Account account) {
        this.activity = activity;
        this.shares = shares;
        this.listener = listener;
        this.user = user;
        this.account = account;
        avatarRadiusDimension = activity.getResources().getDimension(R.dimen.default_icon_size);

        sortShares();
    }

    @Override
    public int getItemViewType(int position) {
        return shares.get(position).getShareType().getValue();
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        switch (ShareType.fromValue(viewType)) {
            case PUBLIC_LINK, EMAIL -> {
                return new LinkShareViewHolder(
                        ItemShareLinkShareBinding.inflate(LayoutInflater.from(activity),
                                parent,
                                false),
                        activity);
            }
            case NEW_PUBLIC_LINK -> {
                return new NewLinkShareViewHolder(
                        ItemAddPublicShareBinding.inflate(LayoutInflater.from(activity),
                                parent,
                                false)
                );
            }
            case INTERNAL -> {
                return new InternalShareViewHolder(
                        ItemInternalShareLinkBinding.inflate(LayoutInflater.from(activity), parent, false),
                        activity);
            }
            default -> {
                return new ShareViewHolder(ItemShareShareBinding.inflate(LayoutInflater.from(activity),
                        parent,
                        false),
                        account,
                        user,
                        activity);
            }
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if (shares == null || shares.size() <= position) {
            return;
        }

        final OCShare share = shares.get(position);

        if (holder instanceof LinkShareViewHolder publicShareViewHolder) {
            publicShareViewHolder.bind(share, listener);
        } else if (holder instanceof InternalShareViewHolder internalShareViewHolder) {
            internalShareViewHolder.bind(share, listener);
        } else if (holder instanceof NewLinkShareViewHolder newLinkShareViewHolder) {
            newLinkShareViewHolder.bind(listener);
        } else {
            ShareViewHolder userViewHolder = (ShareViewHolder) holder;
            userViewHolder.bind(share, listener);
        }
    }

    @Override
    public long getItemId(int position) {
        return shares.get(position).getId();
    }

    @Override
    public int getItemCount() {
        return shares.size();
    }

    @SuppressLint("NotifyDataSetChanged")
    public void addShares(List<OCShare> sharesToAdd) {
        shares.addAll(sharesToAdd);
        sortShares();
        notifyDataSetChanged();
    }

    public void avatarGenerated(Drawable avatarDrawable, Object callContext) {
        if (callContext instanceof ImageView iv) {
            iv.setImageDrawable(avatarDrawable);
        }
    }

    public boolean shouldCallGeneratedCallback(String tag, Object callContext) {
        if (callContext instanceof ImageView iv) {
            // needs to be changed once federated users have avatars
            return String.valueOf(iv.getTag()).equals(tag.split("@")[0]);
        }
        return false;
    }

    @SuppressLint("NotifyDataSetChanged")
    public void remove(OCShare share) {
        shares.remove(share);
        notifyDataSetChanged();
    }

    /**
     * sort all by creation time, then email/link shares on top
     */
    protected final void sortShares() {
        List<OCShare> links = new ArrayList<>();
        List<OCShare> users = new ArrayList<>();

        for (OCShare share : shares) {
            if (ShareType.PUBLIC_LINK == share.getShareType() || ShareType.EMAIL == share.getShareType()) {
                links.add(share);
            } else if (share.getShareType() != ShareType.INTERNAL) {
                users.add(share);
            }
        }

        links.sort((o1, o2) -> Long.compare(o2.getSharedDate(), o1.getSharedDate()));
        users.sort((o1, o2) -> Long.compare(o2.getSharedDate(), o1.getSharedDate()));

        shares = links;
        shares.addAll(users);

        final OCShare ocShare = new OCShare();
        ocShare.setShareType(ShareType.INTERNAL);
        shares.add(ocShare);
    }

    public List<OCShare> getShares() {
        return shares;
    }

    public void removeNewPublicShare() {
        for (OCShare share : shares) {
            if (share.getShareType() == ShareType.NEW_PUBLIC_LINK) {
                shares.remove(share);
                break;
            }
        }
    }
}
+55 −0
Original line number Diff line number Diff line
package it.niedermann.owncloud.notes.share.adapter.holder;


import android.content.Context;
import android.graphics.PorterDuff;
import android.view.View;

import com.owncloud.android.lib.resources.shares.OCShare;

import androidx.annotation.NonNull;
import androidx.core.content.res.ResourcesCompat;
import androidx.recyclerview.widget.RecyclerView;

import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.databinding.ItemInternalShareLinkBinding;
import it.niedermann.owncloud.notes.share.listener.ShareeListAdapterListener;

public class InternalShareViewHolder extends RecyclerView.ViewHolder {
    private ItemInternalShareLinkBinding binding;
    private Context context;

    public InternalShareViewHolder(@NonNull View itemView) {
        super(itemView);
    }

    public InternalShareViewHolder(ItemInternalShareLinkBinding binding, Context context) {
        this(binding.getRoot());
        this.binding = binding;
        this.context = context;
    }

    public void bind(OCShare share, ShareeListAdapterListener listener) {
        binding.copyInternalLinkIcon
                .getBackground()
                .setColorFilter(ResourcesCompat.getColor(context.getResources(),
                                R.color.widget_foreground,
                                null),
                        PorterDuff.Mode.SRC_IN);
        binding.copyInternalLinkIcon
                .getDrawable()
                .mutate()
                .setColorFilter(ResourcesCompat.getColor(context.getResources(),
                                R.color.fg_contrast,
                                null),
                        PorterDuff.Mode.SRC_IN);

        if (share.isFolder()) {
            binding.shareInternalLinkText.setText(context.getString(R.string.share_internal_link_to_folder_text));
        } else {
            binding.shareInternalLinkText.setText(context.getString(R.string.share_internal_link_to_file_text));
        }

        binding.copyInternalContainer.setOnClickListener(l -> listener.copyInternalLink());
    }
}
+93 −0
Original line number Diff line number Diff line
package it.niedermann.owncloud.notes.share.adapter.holder;

import android.content.Context;
import android.graphics.PorterDuff;
import android.text.TextUtils;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.core.content.res.ResourcesCompat;
import androidx.recyclerview.widget.RecyclerView;

import com.nextcloud.android.lib.resources.files.FileDownloadLimit;
import com.owncloud.android.lib.resources.shares.OCShare;
import com.owncloud.android.lib.resources.shares.ShareType;

import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.databinding.ItemShareLinkShareBinding;
import it.niedermann.owncloud.notes.share.helper.SharingMenuHelper;
import it.niedermann.owncloud.notes.share.listener.ShareeListAdapterListener;

public class LinkShareViewHolder extends RecyclerView.ViewHolder {
    private ItemShareLinkShareBinding binding;
    private Context context;

    public LinkShareViewHolder(@NonNull View itemView) {
        super(itemView);
    }

    public LinkShareViewHolder(ItemShareLinkShareBinding binding, Context context) {
        this(binding.getRoot());
        this.binding = binding;
        this.context = context;
    }

    public void bind(OCShare publicShare, ShareeListAdapterListener listener) {
        if (ShareType.EMAIL == publicShare.getShareType()) {
            binding.name.setText(publicShare.getSharedWithDisplayName());
            binding.icon.setImageDrawable(ResourcesCompat.getDrawable(context.getResources(),
                    R.drawable.ic_email,
                    null));
            binding.copyLink.setVisibility(View.GONE);

            binding.icon.getBackground().setColorFilter(context.getResources().getColor(R.color.nc_grey),
                    PorterDuff.Mode.SRC_IN);
            binding.icon.getDrawable().mutate().setColorFilter(context.getResources().getColor(R.color.icon_on_nc_grey),
                    PorterDuff.Mode.SRC_IN);
        } else {
            if (!TextUtils.isEmpty(publicShare.getLabel())) {
                String text = String.format(context.getString(R.string.share_link_with_label), publicShare.getLabel());
                binding.name.setText(text);
            } else {
                if (SharingMenuHelper.isSecureFileDrop(publicShare)) {
                    binding.name.setText(context.getResources().getString(R.string.share_permission_secure_file_drop));
                } else {
                    binding.name.setText(R.string.share_link);
                }
            }

            // viewThemeUtils.platform.colorImageViewBackgroundAndIcon(binding.icon);
        }

        FileDownloadLimit downloadLimit = publicShare.getFileDownloadLimit();
        if (downloadLimit != null && downloadLimit.getLimit() > 0) {
            int remaining = downloadLimit.getLimit() - downloadLimit.getCount();
            String text = context.getResources().getQuantityString(R.plurals.share_download_limit_description, remaining, remaining);

            binding.subline.setText(text);
            binding.subline.setVisibility(View.VISIBLE);
        } else {
            binding.subline.setVisibility(View.GONE);
        }

        String permissionName = SharingMenuHelper.getPermissionName(context, publicShare);
        setPermissionName(publicShare, permissionName);

        binding.overflowMenu.setOnClickListener(v -> listener.showSharingMenuActionSheet(publicShare));
        if (!SharingMenuHelper.isSecureFileDrop(publicShare)) {
            binding.shareByLinkContainer.setOnClickListener(v -> listener.showPermissionsDialog(publicShare));
        }

        binding.copyLink.setOnClickListener(v -> listener.copyLink(publicShare));
    }

    private void setPermissionName(OCShare publicShare, String permissionName) {
        if (!TextUtils.isEmpty(permissionName) && !SharingMenuHelper.isSecureFileDrop(publicShare)) {
            binding.permissionName.setText(permissionName);
            binding.permissionName.setVisibility(View.VISIBLE);
            // viewThemeUtils.androidx.colorPrimaryTextViewElement(binding.permissionName);
        } else {
            binding.permissionName.setVisibility(View.GONE);
        }
    }
}
+26 −0
Original line number Diff line number Diff line
package it.niedermann.owncloud.notes.share.adapter.holder;

import android.view.View;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import it.niedermann.owncloud.notes.databinding.ItemAddPublicShareBinding;
import it.niedermann.owncloud.notes.share.listener.ShareeListAdapterListener;

public class NewLinkShareViewHolder extends RecyclerView.ViewHolder {
    private ItemAddPublicShareBinding binding;

    public NewLinkShareViewHolder(@NonNull View itemView) {
        super(itemView);
    }

    public NewLinkShareViewHolder(ItemAddPublicShareBinding binding) {
        this(binding.getRoot());
        this.binding = binding;
    }

    public void bind(ShareeListAdapterListener listener) {
        binding.addNewPublicShareLink.setOnClickListener(v -> listener.createPublicShareLink());
    }
}
Loading