From 19fbf6f00df82ef075daf7c575d3bba002ba8ff7 Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Sun, 21 Jan 2024 13:21:53 +0100 Subject: feat(attachment): Open file attachments in Nextcloud Files app Refs: #1561 Signed-off-by: Stefan Niedermann --- FAQ.md | 11 +++++++ .../ui/card/attachments/CardAttachmentAdapter.java | 4 +-- .../attachments/DefaultAttachmentViewHolder.java | 4 +-- .../nextcloud/deck/util/AttachmentUtil.java | 35 ++++++++++++++++++++-- .../metadata/android/en-US/changelogs/1024000.txt | 1 + 5 files changed, 48 insertions(+), 7 deletions(-) diff --git a/FAQ.md b/FAQ.md index 3e144bec4..7fb1aa631 100644 --- a/FAQ.md +++ b/FAQ.md @@ -3,6 +3,7 @@ - [I have experienced an error](#i-have-experienced-an-error) - [Why has my bug report been closed?](#why-has-my-bug-report-been-closed) - [Why is my card not visible in the upcoming cards view?](#why-is-my-card-not-visible-in-the-upcoming-cards-view) +- [Why does the browser open when clicking on an attachment?](#why-does-the-browser-open-when-clicking-on-an-attachment) - [Known issues](#known-issues) - [Why don't you make an option for…?](#why-dont-you-make-an-option-for) - [Why don't you make an iOS app?](#why-dont-you-make-an-ios-app) @@ -66,6 +67,16 @@ This is necessary for two reasons: Checkout the [Upcoming Analyzer](https://upcoming-analyzer.niedermann.it/) to check out the criterias your card needs to match to be shown in the upcoming cards view. +## Why does the browser open when clicking on an attachment? + +The Deck server app supports two different type of attachments: +- Attachments added prior to Deck server 1.3 have been added as `deck_file` attachments +- Attachments added with Deck server 1.3 or later are added as `file` attachments + +The latter are stored as usual files in your Nextcloud, usually in the `/Deck` folder of your account. +Only `file` attachments are able show preview images and to get opened directly, while `deck_file` attachments are effectively only available via the Web UI. +We opened a [feature request](https://github.com/nextcloud/deck/issues/3101) to implement an `occ` migration command, but the current state of implementation is unclear. + ## Known issues Here is a collection of issues which are caused by the (not by us developed) Deck server app and can not be fixed within Deck Android. Please [contact the Nextcloud GmbH](https://nextcloud.com/contact/) if you want them to be fixed. diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentAdapter.java index 57fe8d1e3..3a1ebff15 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentAdapter.java @@ -2,7 +2,7 @@ package it.niedermann.nextcloud.deck.ui.card.attachments; import static androidx.lifecycle.Transformations.distinctUntilChanged; import static androidx.recyclerview.widget.RecyclerView.NO_ID; -import static it.niedermann.nextcloud.deck.util.AttachmentUtil.openAttachmentInBrowser; +import static it.niedermann.nextcloud.deck.util.AttachmentUtil.openAttachment; import android.app.Activity; import android.view.LayoutInflater; @@ -112,7 +112,7 @@ public class CardAttachmentAdapter extends RecyclerView.Adapter openAttachmentInBrowser(account, context, cardRemoteId, attachment); + onClickListener = (event) -> openAttachment(account, context, cardRemoteId, attachment); break; } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/DefaultAttachmentViewHolder.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/DefaultAttachmentViewHolder.java index 21f858218..505fdf335 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/DefaultAttachmentViewHolder.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/DefaultAttachmentViewHolder.java @@ -1,7 +1,7 @@ package it.niedermann.nextcloud.deck.ui.card.attachments; import static it.niedermann.nextcloud.deck.util.AttachmentUtil.getIconForMimeType; -import static it.niedermann.nextcloud.deck.util.AttachmentUtil.openAttachmentInBrowser; +import static it.niedermann.nextcloud.deck.util.AttachmentUtil.openAttachment; import android.text.format.Formatter; import android.view.MenuInflater; @@ -40,7 +40,7 @@ public class DefaultAttachmentViewHolder extends AttachmentViewHolder { public void bind(@NonNull Account account, @NonNull MenuInflater menuInflater, @NonNull FragmentManager fragmentManager, Long cardRemoteId, Attachment attachment, @Nullable View.OnClickListener onClickListener, @ColorInt int color) { super.bind(account, menuInflater, fragmentManager, cardRemoteId, attachment, onClickListener, color); getPreview().setImageResource(getIconForMimeType(attachment.getMimetype())); - itemView.setOnClickListener((event) -> openAttachmentInBrowser(account, itemView.getContext(), cardRemoteId, attachment)); + itemView.setOnClickListener((event) -> openAttachment(account, itemView.getContext(), cardRemoteId, attachment)); binding.filename.setText(attachment.getBasename()); binding.filesize.setText(Formatter.formatFileSize(binding.filesize.getContext(), attachment.getFilesize())); if (attachment.getLastModifiedLocal() != null) { 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 aba73a11e..a9c25dcf7 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 @@ -2,6 +2,7 @@ package it.niedermann.nextcloud.deck.util; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.net.Uri; import android.text.TextUtils; import android.widget.Toast; @@ -11,6 +12,10 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.Px; +import com.nextcloud.android.sso.model.FilesAppType; + +import java.util.Optional; + import it.niedermann.nextcloud.deck.DeckLog; import it.niedermann.nextcloud.deck.R; import it.niedermann.nextcloud.deck.model.Account; @@ -57,23 +62,47 @@ public class AttachmentUtil { } /** - * Tries to open the given {@link Attachment} in web browser. Displays a toast on failure. + * Tries to open the given {@link Attachment} in the Nextcloud Android app with a fallback to the web browser. + * Displays a toast on failure. */ - public static void openAttachmentInBrowser(@NonNull Account account, @NonNull Context context, Long cardRemoteId, Attachment attachment) { + public static void openAttachment(@NonNull Account account, @NonNull Context context, @Nullable Long cardRemoteId, Attachment attachment) { if (cardRemoteId == null) { Toast.makeText(context, R.string.card_does_not_yet_exist, Toast.LENGTH_LONG).show(); DeckLog.logError(new IllegalArgumentException("cardRemoteId must not be null.")); return; } + final var intent = generateNextcloudFilesIntent(context.getPackageManager(), account, attachment) + .orElse(generateBrowserIntent(account, cardRemoteId, attachment)); + try { - context.startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(getCopyDownloadUrl(account, cardRemoteId, attachment)))); + context.startActivity(intent); } catch (IllegalArgumentException e) { Toast.makeText(context, R.string.attachment_does_not_yet_exist, Toast.LENGTH_LONG).show(); DeckLog.logError(new IllegalArgumentException("attachmentRemoteId must not be null.")); } } + private static Optional generateNextcloudFilesIntent(@NonNull PackageManager packageManager, @NonNull Account account, Attachment attachment) { + for (final var type : FilesAppType.values()) { + final var intent = new Intent(Intent.ACTION_VIEW) + .setClassName(type.packageId, "com.owncloud.android.ui.activity.FileDisplayActivity") + .putExtra("KEY_FILE_ID", String.valueOf(attachment.getFileId())) + .putExtra("KEY_ACCOUNT", account.getName()); + + if (packageManager.resolveActivity(intent, 0) != null) { + return Optional.of(intent); + } + } + + return Optional.empty(); + } + + private static Intent generateBrowserIntent(@NonNull Account account, long cardRemoteId, @NonNull Attachment attachment) { + return new Intent(Intent.ACTION_VIEW) + .setData(Uri.parse(getCopyDownloadUrl(account, cardRemoteId, attachment))); + } + public static String getCopyDownloadUrl(@NonNull Account account, @NonNull Long cardRemoteId, @NonNull Attachment attachment) { if (attachment.getId() == null) { throw new IllegalArgumentException("attachment id must not be null"); diff --git a/fastlane/metadata/android/en-US/changelogs/1024000.txt b/fastlane/metadata/android/en-US/changelogs/1024000.txt index cd581c869..b0d209ea3 100644 --- a/fastlane/metadata/android/en-US/changelogs/1024000.txt +++ b/fastlane/metadata/android/en-US/changelogs/1024000.txt @@ -1,3 +1,4 @@ - ☑️ Support Completed / Uncompleted state (#1556) - Requires deck server ≥ 1.12.2 +- 📎 Open file attachments in Nextcloud Files app (#1561) - Requires deck server ≥ 1.12.2 - ☑️ Share text as task to card description (#1558) - ☀️ Force keeping screen on while importing first account \ No newline at end of file -- cgit v1.2.3