From 457e9948c23f2468293675303ad6e15f1da15a23 Mon Sep 17 00:00:00 2001 From: stefan-niedermann Date: Mon, 24 Feb 2020 21:05:45 +0100 Subject: Display image attachments directly --- .../nextcloud/deck/ui/card/AttachmentAdapter.java | 113 ++++++++++++++------- .../deck/ui/card/CardAttachmentsFragment.java | 17 ++++ .../deck/ui/widget/SquareRelativeLayout.java | 34 +++++++ .../layout/fragment_card_edit_tab_attachments.xml | 3 +- app/src/main/res/layout/item_attachment.xml | 79 -------------- .../main/res/layout/item_attachment_default.xml | 79 ++++++++++++++ app/src/main/res/layout/item_attachment_image.xml | 25 +++++ 7 files changed, 235 insertions(+), 115 deletions(-) create mode 100644 app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/SquareRelativeLayout.java delete mode 100644 app/src/main/res/layout/item_attachment.xml create mode 100644 app/src/main/res/layout/item_attachment_default.xml create mode 100644 app/src/main/res/layout/item_attachment_image.xml diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentAdapter.java index 74a00677e..dad498a62 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentAdapter.java @@ -16,6 +16,7 @@ import androidx.appcompat.widget.AppCompatImageView; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.CenterCrop; import java.util.List; @@ -30,6 +31,9 @@ import it.niedermann.nextcloud.deck.util.DeleteDialogBuilder; public class AttachmentAdapter extends RecyclerView.Adapter { + public static final int VIEW_TYPE_DEFAULT = 2; + public static final int VIEW_TYPE_IMAGE = 1; + private final Account account; private final long cardRemoteId; @NonNull @@ -50,56 +54,82 @@ public class AttachmentAdapter extends RecyclerView.Adapter { - Intent openURL = new Intent(android.content.Intent.ACTION_VIEW); - openURL.setData(Uri.parse(account.getUrl() + "/index.php/apps/deck/cards/" + cardRemoteId + "/attachment/" + attachment.getId())); - context.startActivity(openURL); - }); - if (attachment.getMimetype() != null) { if (attachment.getMimetype().startsWith("image")) { // TODO Glide is currently not yet able to use SSO and fails on authentication String uri = account.getUrl() + "/index.php/apps/deck/cards/" + cardRemoteId + "/attachment/" + attachment.getId(); Glide.with(context) .load(uri) + .transform(new CenterCrop()) .error(R.drawable.ic_image_grey600_24dp) - .into(holder.filetype); - holder.filetype.setImageResource(R.drawable.ic_image_grey600_24dp); - holder.filename.getRootView().setOnClickListener((v) -> AttachmentDialogFragment.newInstance(uri, attachment.getBasename()).show(((AppCompatActivity) context).getSupportFragmentManager(), "asdf")); + .into(holder.preview); + holder.preview.setImageResource(R.drawable.ic_image_grey600_24dp); + holder.preview.getRootView().setOnClickListener((v) -> AttachmentDialogFragment.newInstance(uri, attachment.getBasename()).show(((AppCompatActivity) context).getSupportFragmentManager(), "preview")); } else if (attachment.getMimetype().startsWith("audio")) { - holder.filetype.setImageResource(R.drawable.ic_music_note_grey600_24dp); + holder.preview.setImageResource(R.drawable.ic_music_note_grey600_24dp); } else if (attachment.getMimetype().startsWith("video")) { - holder.filetype.setImageResource(R.drawable.ic_local_movies_grey600_24dp); + holder.preview.setImageResource(R.drawable.ic_local_movies_grey600_24dp); } } - holder.filename.setText(attachment.getBasename()); - holder.filesize.setText(Formatter.formatFileSize(context, attachment.getFilesize())); - if (attachment.getLastModifiedLocal() != null) { - holder.modified.setText(DateUtil.getRelativeDateTimeString(context, attachment.getLastModifiedLocal().getTime())); - holder.modified.setVisibility(View.VISIBLE); - } else if (attachment.getLastModified() != null) { - holder.modified.setText(DateUtil.getRelativeDateTimeString(context, attachment.getLastModified().getTime())); - holder.modified.setVisibility(View.VISIBLE); - } else { - holder.modified.setVisibility(View.GONE); + + //noinspection SwitchStatementWithTooFewBranches + switch (viewType) { + case VIEW_TYPE_IMAGE: { + ImageAttachmentViewHolder imageHolder = (ImageAttachmentViewHolder) holder; + break; + } + default: { + DefaultAttachmentViewHolder defaultHolder = (DefaultAttachmentViewHolder) holder; + defaultHolder.filename.getRootView().setOnClickListener((event) -> { + Intent openURL = new Intent(android.content.Intent.ACTION_VIEW); + openURL.setData(Uri.parse(account.getUrl() + "/index.php/apps/deck/cards/" + cardRemoteId + "/attachment/" + attachment.getId())); + context.startActivity(openURL); + }); + defaultHolder.filename.setText(attachment.getBasename()); + defaultHolder.filesize.setText(Formatter.formatFileSize(context, attachment.getFilesize())); + if (attachment.getLastModifiedLocal() != null) { + defaultHolder.modified.setText(DateUtil.getRelativeDateTimeString(context, attachment.getLastModifiedLocal().getTime())); + defaultHolder.modified.setVisibility(View.VISIBLE); + } else if (attachment.getLastModified() != null) { + defaultHolder.modified.setText(DateUtil.getRelativeDateTimeString(context, attachment.getLastModified().getTime())); + defaultHolder.modified.setVisibility(View.VISIBLE); + } else { + defaultHolder.modified.setVisibility(View.GONE); + } + defaultHolder.deleteButton.setOnClickListener((v) -> { + new DeleteDialogBuilder(context) + .setTitle(context.getString(R.string.delete_something, attachment.getFilename())) + .setMessage(R.string.attachment_delete_message) + .setNegativeButton(android.R.string.cancel, null) + .setPositiveButton(R.string.simple_delete, (dialog, which) -> attachmentDeletedListener.onAttachmentDeleted(attachment)) + .show(); + }); + break; + } } - holder.deleteButton.setOnClickListener((v) -> { - new DeleteDialogBuilder(context) - .setTitle(context.getString(R.string.delete_something, attachment.getFilename())) - .setMessage(R.string.attachment_delete_message) - .setNegativeButton(android.R.string.cancel, null) - .setPositiveButton(R.string.simple_delete, (dialog, which) -> attachmentDeletedListener.onAttachmentDeleted(attachment)) - .show(); - }); + } + + @Override + public int getItemViewType(int position) { + String mimeType = attachments.get(position).getMimetype(); + return (mimeType != null && mimeType.startsWith("image")) ? VIEW_TYPE_IMAGE : VIEW_TYPE_DEFAULT; } @Override @@ -108,10 +138,17 @@ public class AttachmentAdapter extends RecyclerView.Adapter { RecyclerView.Adapter adapter = new AttachmentAdapter(this, account, fullCard.getCard().getId(), fullCard.getAttachments()); attachmentsList.setAdapter(adapter); + GridLayoutManager glm = new GridLayoutManager(getActivity(), 3); + + glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { + @Override + public int getSpanSize(int position) { + switch (adapter.getItemViewType(position)) { + case AttachmentAdapter.VIEW_TYPE_IMAGE: + return 1; + case AttachmentAdapter.VIEW_TYPE_DEFAULT: + return 3; + default: + return 1; + } + } + }); + attachmentsList.setLayoutManager(glm); }); } }); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/SquareRelativeLayout.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/SquareRelativeLayout.java new file mode 100644 index 000000000..86a48d6d2 --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/SquareRelativeLayout.java @@ -0,0 +1,34 @@ +package it.niedermann.nextcloud.deck.ui.widget; + +import android.annotation.TargetApi; +import android.content.Context; +import android.os.Build; +import android.util.AttributeSet; +import android.widget.RelativeLayout; + +public class SquareRelativeLayout extends RelativeLayout { + + public SquareRelativeLayout(Context context) { + super(context); + } + + public SquareRelativeLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public SquareRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public SquareRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + // Set a square layout. + super.onMeasure(widthMeasureSpec, widthMeasureSpec); + } + +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_card_edit_tab_attachments.xml b/app/src/main/res/layout/fragment_card_edit_tab_attachments.xml index 42b21612a..93d76fb53 100644 --- a/app/src/main/res/layout/fragment_card_edit_tab_attachments.xml +++ b/app/src/main/res/layout/fragment_card_edit_tab_attachments.xml @@ -13,8 +13,7 @@ android:layout_height="match_parent" android:scrollbars="vertical" android:visibility="gone" - app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" - tools:listitem="@layout/item_attachment" + tools:listitem="@layout/item_attachment_default" tools:visibility="visible" /> - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/item_attachment_default.xml b/app/src/main/res/layout/item_attachment_default.xml new file mode 100644 index 000000000..26798c547 --- /dev/null +++ b/app/src/main/res/layout/item_attachment_default.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_attachment_image.xml b/app/src/main/res/layout/item_attachment_image.xml new file mode 100644 index 000000000..c7f63d998 --- /dev/null +++ b/app/src/main/res/layout/item_attachment_image.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file -- cgit v1.2.3