Skip to content

Commit

Permalink
feat(attachment): Open file attachments in Nextcloud Files app
Browse files Browse the repository at this point in the history
Refs: #1561

Signed-off-by: Stefan Niedermann <info@niedermann.it>
  • Loading branch information
stefan-niedermann committed Jan 21, 2024
1 parent 397be5e commit 19fbf6f
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 7 deletions.
11 changes: 11 additions & 0 deletions FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

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;
Expand Down Expand Up @@ -112,7 +112,7 @@ public void onBindViewHolder(@NonNull AttachmentViewHolder holder, int position)
}
case VIEW_TYPE_DEFAULT:
default: {
onClickListener = (event) -> openAttachmentInBrowser(account, context, cardRemoteId, attachment);
onClickListener = (event) -> openAttachment(account, context, cardRemoteId, attachment);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -40,7 +40,7 @@ protected ImageView getNotSyncedYetStatusIcon() {
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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

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;
Expand All @@ -11,6 +12,10 @@
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;
Expand Down Expand Up @@ -57,23 +62,47 @@ private static String getRemoteOrLocalUrl(@NonNull String accountUrl, @Nullable
}

/**
* 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<Intent> 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");
Expand Down
1 change: 1 addition & 0 deletions fastlane/metadata/android/en-US/changelogs/1024000.txt
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 19fbf6f

Please sign in to comment.