diff options
author | Stefan Niedermann <info@niedermann.it> | 2020-12-09 14:12:18 +0300 |
---|---|---|
committer | Stefan Niedermann <info@niedermann.it> | 2020-12-09 14:12:18 +0300 |
commit | 61506f9d29daf0559fa12c70a25a45a4c6d83fa1 (patch) | |
tree | 26c3ad677b9c2a086d947fd9ff86166f27af30f2 /app/src/main/java | |
parent | 48dd2fe1a86e86f44040b41f22c9b0f1b5d9f487 (diff) |
Prepare support of thumbnail generation
Signed-off-by: Stefan Niedermann <info@niedermann.it>
Diffstat (limited to 'app/src/main/java')
6 files changed, 130 insertions, 61 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/model/Attachment.java b/app/src/main/java/it/niedermann/nextcloud/deck/model/Attachment.java index 5e3b988ef..7eabcbe70 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/model/Attachment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/model/Attachment.java @@ -2,6 +2,7 @@ package it.niedermann.nextcloud.deck.model; import androidx.room.Entity; import androidx.room.ForeignKey; +import androidx.room.Ignore; import androidx.room.Index; import java.io.Serializable; @@ -35,6 +36,9 @@ public class Attachment extends AbstractRemoteEntity implements Comparable<Attac private String extension; private String filename; private String localPath; + // TODO should probably be a Long... depends on https://github.com/nextcloud/deck/pull/2638 + @Ignore + private String fileId; public long getCardId() { return cardId; @@ -140,6 +144,22 @@ public class Attachment extends AbstractRemoteEntity implements Comparable<Attac this.localPath = localPath; } + /** + * TODO depends on https://github.com/nextcloud/deck/pull/2638 + */ + @Ignore + public String getFileId() { + return this.fileId; + } + + /** + * TODO depends on https://github.com/nextcloud/deck/pull/2638 + */ + @Ignore + public void setFileId(String fileId) { + this.fileId = fileId; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/model/ocs/Version.java b/app/src/main/java/it/niedermann/nextcloud/deck/model/ocs/Version.java index c04512ad2..cfd973831 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/model/ocs/Version.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/model/ocs/Version.java @@ -10,12 +10,14 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import it.niedermann.nextcloud.deck.R; +import it.niedermann.nextcloud.deck.model.Attachment; import it.niedermann.nextcloud.deck.model.ocs.comment.DeckComment; public class Version implements Comparable<Version> { private static final Pattern NUMBER_EXTRACTION_PATTERN = Pattern.compile("[0-9]+"); private static final Version VERSION_1_0_0 = new Version("1.0.0", 1, 0, 0); private static final Version VERSION_1_0_3 = new Version("1.0.3", 1, 0, 3); + private static final Version VERSION_1_3_0 = new Version("1.3.0", 1, 3, 0); @Nullable private static Version VERSION_MINIMUM_SUPPORTED; @@ -155,6 +157,22 @@ public class Version implements Comparable<Version> { } /** + * Before {@link #VERSION_1_3_0} all {@link Attachment}s have been stored in a special folder at the server. + * Starting with {@link #VERSION_1_3_0} {@link Attachment}s can be stored as regular files, allowing for example to make use of server side thumbnail generation. + * <p> + * Since the migration takes a long time, it does not happen on upgrading the server app but step by step via a cronjob. + * Therefore this method is just an indicator, that it is possible that {@link Attachment}s are stored as files, but it is no guarantee that all {@link Attachment}s already have been migrated to files. + * + * @return whether or not the server supports file attachments + * @see <a href="https://github.com/nextcloud/deck/pull/2638">documentation in PR</a> + */ + public boolean supportsFileAttachments() { + return false; +// TODO depends on https://github.com/nextcloud/deck/pull/2638 +// return isGreaterOrEqualTo(VERSION_1_3_0); + } + + /** * Title max length has been increased from 100 to 255 characters beginning with server {@link Version} 1.0.0 * * @return the number of characters that the title fields of cards allow @@ -165,6 +183,7 @@ public class Version implements Comparable<Version> { ? 255 : 100; } + /** * URL to view a card in the web interface has been changed in {@link Version} 1.0.0 * diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/attachments/AttachmentAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/attachments/AttachmentAdapter.java index b17b34137..c7d32bd37 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/attachments/AttachmentAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/attachments/AttachmentAdapter.java @@ -1,43 +1,31 @@ package it.niedermann.nextcloud.deck.ui.attachments; import android.content.Context; -import android.graphics.drawable.Drawable; -import android.os.Build; import android.view.LayoutInflater; import android.view.ViewGroup; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.FragmentActivity; import androidx.recyclerview.widget.RecyclerView; -import com.bumptech.glide.Glide; -import com.bumptech.glide.load.DataSource; -import com.bumptech.glide.load.engine.GlideException; -import com.bumptech.glide.request.RequestListener; -import com.bumptech.glide.request.target.Target; - +import java.util.ArrayList; import java.util.List; -import it.niedermann.nextcloud.deck.R; import it.niedermann.nextcloud.deck.databinding.ItemAttachmentBinding; import it.niedermann.nextcloud.deck.model.Account; import it.niedermann.nextcloud.deck.model.Attachment; -import it.niedermann.nextcloud.deck.util.AttachmentUtil; -import it.niedermann.nextcloud.deck.util.MimeTypeUtil; public class AttachmentAdapter extends RecyclerView.Adapter<AttachmentViewHolder> { private final Account account; private final long cardRemoteId; @NonNull - private List<Attachment> attachments; - private Context context; + private final List<Attachment> attachments = new ArrayList<>(); @SuppressWarnings("WeakerAccess") public AttachmentAdapter(@NonNull Account account, long cardRemoteId, @NonNull List<Attachment> attachments) { super(); - this.attachments = attachments; + this.attachments.clear(); + this.attachments.addAll(attachments); this.account = account; this.cardRemoteId = cardRemoteId; } @@ -45,43 +33,13 @@ public class AttachmentAdapter extends RecyclerView.Adapter<AttachmentViewHolder @NonNull @Override public AttachmentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - this.context = parent.getContext(); - return new AttachmentViewHolder(ItemAttachmentBinding.inflate(LayoutInflater.from(context), parent, false)); + final Context context = parent.getContext(); + return new AttachmentViewHolder(context, ItemAttachmentBinding.inflate(LayoutInflater.from(context), parent, false)); } @Override public void onBindViewHolder(@NonNull AttachmentViewHolder holder, int position) { - final Attachment attachment = attachments.get(position); - final String uri = AttachmentUtil.getRemoteOrLocalUrl(account.getUrl(), cardRemoteId, attachment); - if (MimeTypeUtil.isImage(attachment.getMimetype())) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - holder.binding.preview.setTransitionName(context.getString(R.string.transition_attachment_preview, String.valueOf(attachment.getLocalId()))); - } - holder.binding.preview.setImageResource(R.drawable.ic_image_grey600_24dp); - Glide.with(context) - .load(uri) - .listener(new RequestListener<Drawable>() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, - Target<Drawable> target, boolean isFirstResource) { - if (context instanceof FragmentActivity) { - ((FragmentActivity) context).supportStartPostponedEnterTransition(); - } - return false; - } - - @Override - public boolean onResourceReady(Drawable resource, Object model, - Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { - if (context instanceof FragmentActivity) { - ((FragmentActivity) context).supportStartPostponedEnterTransition(); - } - return false; - } - }) - .error(R.drawable.ic_image_grey600_24dp) - .into(holder.binding.preview); - } + holder.bind(account, attachments.get(position), cardRemoteId); } @Override diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/attachments/AttachmentViewHolder.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/attachments/AttachmentViewHolder.java index 584a57d1d..6f4fe3c74 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/attachments/AttachmentViewHolder.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/attachments/AttachmentViewHolder.java @@ -1,15 +1,72 @@ package it.niedermann.nextcloud.deck.ui.attachments; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.os.Build; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; import androidx.recyclerview.widget.RecyclerView; +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.target.Target; + +import it.niedermann.nextcloud.deck.R; import it.niedermann.nextcloud.deck.databinding.ItemAttachmentBinding; +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.Attachment; +import it.niedermann.nextcloud.deck.util.AttachmentUtil; +import it.niedermann.nextcloud.deck.util.MimeTypeUtil; public class AttachmentViewHolder extends RecyclerView.ViewHolder { - public ItemAttachmentBinding binding; + @NonNull + private final Context parentContext; + @NonNull + private final ItemAttachmentBinding binding; @SuppressWarnings("WeakerAccess") - public AttachmentViewHolder(ItemAttachmentBinding binding) { + public AttachmentViewHolder(@NonNull Context parentContext, @NonNull ItemAttachmentBinding binding) { super(binding.getRoot()); + this.parentContext = parentContext; this.binding = binding; } + + public void bind(@NonNull Account account, @NonNull Attachment attachment, long cardRemoteId) { + if (MimeTypeUtil.isImage(attachment.getMimetype())) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + binding.preview.setTransitionName(parentContext.getString(R.string.transition_attachment_preview, String.valueOf(attachment.getLocalId()))); + } + binding.preview.setImageResource(R.drawable.ic_image_grey600_24dp); + binding.preview.post(() -> { + final String uri = AttachmentUtil.getThumbnailUrl(account.getServerDeckVersionAsObject(), account.getUrl(), cardRemoteId, attachment, binding.preview.getWidth()); + Glide.with(parentContext) + .load(uri) + .listener(new RequestListener<Drawable>() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, + Target<Drawable> target, boolean isFirstResource) { + if (parentContext instanceof FragmentActivity) { + ((FragmentActivity) parentContext).supportStartPostponedEnterTransition(); + } + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, + Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { + if (parentContext instanceof FragmentActivity) { + ((FragmentActivity) parentContext).supportStartPostponedEnterTransition(); + } + return false; + } + }) + .error(R.drawable.ic_image_grey600_24dp) + .into(binding.preview); + }); + } + } }
\ No newline at end of file diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/ImageAttachmentViewHolder.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/ImageAttachmentViewHolder.java index e3139295f..3c95da1b7 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/ImageAttachmentViewHolder.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/ImageAttachmentViewHolder.java @@ -18,7 +18,7 @@ import it.niedermann.nextcloud.deck.model.Attachment; import it.niedermann.nextcloud.deck.util.AttachmentUtil; public class ImageAttachmentViewHolder extends AttachmentViewHolder { - private ItemAttachmentImageBinding binding; + private final ItemAttachmentImageBinding binding; @SuppressWarnings("WeakerAccess") public ImageAttachmentViewHolder(ItemAttachmentImageBinding binding) { @@ -37,16 +37,17 @@ public class ImageAttachmentViewHolder extends AttachmentViewHolder { } public void bind(@NonNull Account account, @NonNull MenuInflater menuInflater, @NonNull FragmentManager fragmentManager, Long cardRemoteId, Attachment attachment, @Nullable View.OnClickListener onClickListener, @ColorInt int mainColor) { - @Nullable final String uri = AttachmentUtil.getRemoteOrLocalUrl(account.getUrl(), cardRemoteId, attachment); + super.bind(menuInflater, fragmentManager, cardRemoteId, attachment, onClickListener, mainColor, AttachmentUtil.getRemoteOrLocalUrl(account.getUrl(), cardRemoteId, attachment)); - super.bind(menuInflater, fragmentManager, cardRemoteId, attachment, onClickListener, mainColor, uri); + getPreview().post(() -> { + @Nullable final String uri = AttachmentUtil.getThumbnailUrl(account.getServerDeckVersionAsObject(), account.getUrl(), cardRemoteId, attachment, getPreview().getWidth()); + Glide.with(getPreview().getContext()) + .load(uri) + .placeholder(R.drawable.ic_image_grey600_24dp) + .error(R.drawable.ic_image_grey600_24dp) + .into(getPreview()); + }); - getPreview().setImageResource(R.drawable.ic_image_grey600_24dp); - Glide.with(getPreview().getContext()) - .load(uri) - .placeholder(R.drawable.ic_image_grey600_24dp) - .error(R.drawable.ic_image_grey600_24dp) - .into(getPreview()); itemView.setOnClickListener(onClickListener); } }
\ No newline at end of file diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/util/AttachmentUtil.java b/app/src/main/java/it/niedermann/nextcloud/deck/util/AttachmentUtil.java index 2baec8e92..ef3e14b37 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/util/AttachmentUtil.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/util/AttachmentUtil.java @@ -10,6 +10,7 @@ import android.widget.Toast; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.Px; import java.io.File; import java.io.FileNotFoundException; @@ -20,6 +21,7 @@ import java.io.InputStream; import it.niedermann.nextcloud.deck.DeckLog; import it.niedermann.nextcloud.deck.R; import it.niedermann.nextcloud.deck.model.Attachment; +import it.niedermann.nextcloud.deck.model.ocs.Version; /** * Created by stefan on 07.03.20. @@ -31,7 +33,19 @@ public class AttachmentUtil { } /** - * @return {@link AttachmentUtil#getRemoteUrl} or {@link Attachment#getLocalPath()} as fallback in case this {@param attachment} has not yet been synced. + * @return a link to the thumbnail of the given {@link Attachment}. + * If a thumbnail is not available (see {@link Version#supportsFileAttachments()}), a link to + * the {@link Attachment} itself will be returned instead. + */ + public static String getThumbnailUrl(@NonNull Version version, @NonNull String accountUrl, @NonNull Long cardRemoteId, @NonNull Attachment attachment, @Px int previewSize) { + return version.supportsFileAttachments() && !TextUtils.isEmpty(String.valueOf(attachment.getFileId())) + ? accountUrl + "/index.php/core/preview?fileId=" + attachment.getFileId() + "&x=" + previewSize + "&y=" + previewSize + : getRemoteOrLocalUrl(accountUrl, cardRemoteId, attachment); + } + + /** + * @return {@link AttachmentUtil#getRemoteUrl} or {@link Attachment#getLocalPath()} as fallback + * in case this {@param attachment} has not yet been synced. */ @Nullable public static String getRemoteOrLocalUrl(@NonNull String accountUrl, @Nullable Long cardRemoteId, @NonNull Attachment attachment) { |