Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/stefan-niedermann/nextcloud-deck.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstefan-niedermann <info@niedermann.it>2020-03-07 20:11:14 +0300
committerstefan-niedermann <info@niedermann.it>2020-03-07 20:11:14 +0300
commit656f1d4cc1596a7b6b5fc4b2aa28d8726956acc7 (patch)
tree38b67b93de73cee81b9641118649e6388a9bf89c
parent30363cbf4db19e344fbea401fe6f7cc4da2f6ea3 (diff)
Refactor attachment viewer to own activity with transition animation
-rw-r--r--app/src/main/AndroidManifest.xml3
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/AttachmentsActivity.java343
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentAdapter.java43
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentDialogFragment.java83
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAttachmentsFragment.java12
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/util/AttachmentUtil.java15
-rw-r--r--app/src/main/res/layout/activity_attachments.xml36
-rw-r--r--app/src/main/res/layout/dialog_attachment.xml18
-rw-r--r--app/src/main/res/layout/item_attachment_default.xml1
-rw-r--r--app/src/main/res/layout/item_attachment_image.xml2
-rw-r--r--app/src/main/res/values/setup.xml3
-rw-r--r--app/src/main/res/values/styles.xml23
12 files changed, 158 insertions, 424 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 727b1df58..1433653a4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -48,8 +48,7 @@
<activity
android:name=".ui.AttachmentsActivity"
- android:label="@string/attachments"
- android:theme="@style/AppTheme"
+ android:theme="@style/TransparentTheme"
android:parentActivityName="it.niedermann.nextcloud.deck.ui.EditActivity" />
<activity
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/AttachmentsActivity.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/AttachmentsActivity.java
index 5ec231351..411acdb90 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/AttachmentsActivity.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/AttachmentsActivity.java
@@ -1,90 +1,36 @@
package it.niedermann.nextcloud.deck.ui;
-import android.content.SharedPreferences;
import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.AdapterView;
-import android.widget.SpinnerAdapter;
+import android.view.MotionEvent;
-import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
-import com.google.android.material.tabs.TabLayout;
-import com.google.android.material.tabs.TabLayoutMediator;
-import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException;
-import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException;
-import com.nextcloud.android.sso.helper.SingleAccountHelper;
-import com.nextcloud.android.sso.model.SingleSignOnAccount;
+import com.bumptech.glide.Glide;
-import java.util.ArrayList;
-import java.util.Date;
import java.util.List;
-import it.niedermann.nextcloud.deck.Application;
import it.niedermann.nextcloud.deck.DeckLog;
-import it.niedermann.nextcloud.deck.R;
-import it.niedermann.nextcloud.deck.databinding.ActivityEditBinding;
-import it.niedermann.nextcloud.deck.model.Account;
-import it.niedermann.nextcloud.deck.model.Board;
-import it.niedermann.nextcloud.deck.model.Card;
-import it.niedermann.nextcloud.deck.model.Label;
-import it.niedermann.nextcloud.deck.model.User;
-import it.niedermann.nextcloud.deck.model.full.FullCard;
+import it.niedermann.nextcloud.deck.databinding.ActivityAttachmentsBinding;
+import it.niedermann.nextcloud.deck.model.Attachment;
import it.niedermann.nextcloud.deck.persistence.sync.SyncManager;
-import it.niedermann.nextcloud.deck.ui.board.BoardAdapter;
-import it.niedermann.nextcloud.deck.ui.card.CardDetailsFragment;
-import it.niedermann.nextcloud.deck.ui.card.CardTabAdapter;
-import it.niedermann.nextcloud.deck.ui.card.CommentDialogFragment;
import it.niedermann.nextcloud.deck.ui.exception.ExceptionHandler;
-import it.niedermann.nextcloud.deck.util.CardUtil;
+import it.niedermann.nextcloud.deck.util.AttachmentUtil;
-import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.LiveDataHelper.observeOnce;
import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.BUNDLE_KEY_ACCOUNT_ID;
-import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.BUNDLE_KEY_BOARD_ID;
import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.BUNDLE_KEY_LOCAL_ID;
-import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.BUNDLE_KEY_STACK_ID;
-import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.NO_LOCAL_ID;
-public class AttachmentsActivity extends AppCompatActivity implements
- CardDetailsFragment.CardDetailsListener,
- CommentDialogFragment.AddCommentListener,
- AdapterView.OnItemSelectedListener {
+public class AttachmentsActivity extends AppCompatActivity {
- private ActivityEditBinding binding;
- private SyncManager syncManager;
+ private ActivityAttachmentsBinding binding;
- private static final int[] tabTitles = new int[]{
- R.string.card_edit_details,
- R.string.card_edit_attachments,
- R.string.card_edit_activity
- };
-
- private FullCard originalCard;
- private FullCard fullCard;
-
- private long accountId;
- private long boardId;
- private long stackId;
- private long localId;
-
- private boolean pendingCreation = false;
- private boolean canEdit;
- private boolean createMode;
+ public static final String BUNDLE_KEY_CURRENT_ATTACHMENT_LOCAL_ID = "currentAttachmenLocaltId";
@Override
public void onCreate(Bundle savedInstanceState) {
- setTheme(Application.getAppTheme(this) ? R.style.DarkAppTheme : R.style.AppTheme);
super.onCreate(savedInstanceState);
Thread.currentThread().setUncaughtExceptionHandler(new ExceptionHandler(this));
- binding = ActivityEditBinding.inflate(getLayoutInflater());
+ binding = ActivityAttachmentsBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
@@ -93,253 +39,50 @@ public class AttachmentsActivity extends AppCompatActivity implements
if (extras == null) {
throw new IllegalArgumentException("Provide localId");
}
- accountId = extras.getLong(BUNDLE_KEY_ACCOUNT_ID);
- boardId = extras.getLong(BUNDLE_KEY_BOARD_ID);
- stackId = extras.getLong(BUNDLE_KEY_STACK_ID);
- localId = extras.getLong(BUNDLE_KEY_LOCAL_ID);
- syncManager = new SyncManager(this);
-
- createMode = NO_LOCAL_ID.equals(localId);
- if (boardId == 0L) {
- try {
- createMode = true;
- SingleSignOnAccount ssoa = SingleAccountHelper.getCurrentSingleSignOnAccount(this);
- syncManager.readAccount(ssoa.name).observe(this, (Account account) -> {
- accountId = account.getId();
- binding.selectBoardWrapper.setVisibility(View.VISIBLE);
- syncManager.getBoards(account.getId()).observe(this, (List<Board> boardsList) -> {
- for (Board board : boardsList) {
- if (!board.isPermissionEdit()) {
- boardsList.remove(board);
- }
- }
- Board[] boardsArray = new Board[boardsList.size()];
- boardsArray = boardsList.toArray(boardsArray);
- SpinnerAdapter adapter = new BoardAdapter(this, boardsArray);
- binding.boardSelector.setAdapter(adapter);
-
- SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
- long lastBoardId = sharedPreferences.getLong(getString(R.string.shared_preference_last_board_for_account_) + accountId, 0L);
- DeckLog.log("--- Read: shared_preference_last_board_for_account_" + account.getId() + " | " + lastBoardId);
- if (lastBoardId != 0L) {
- for (int i = 0; i < boardsArray.length; i++) {
- if (boardsArray[i].getLocalId() == lastBoardId) {
- binding.boardSelector.setSelection(i);
+ long accountId = extras.getLong(BUNDLE_KEY_ACCOUNT_ID);
+ long cardLocalId = extras.getLong(BUNDLE_KEY_LOCAL_ID);
+ long currentAttachment = extras.getLong(BUNDLE_KEY_CURRENT_ATTACHMENT_LOCAL_ID);
+
+ SyncManager syncManager = new SyncManager(this);
+
+ syncManager.readAccount(accountId).observe(this, account ->
+ syncManager.getCardByLocalId(accountId, cardLocalId).observe(this, fullCard -> {
+ binding.toolbar.setSubtitle(fullCard.getCard().getTitle());
+ List<Attachment> attachments = fullCard.getAttachments();
+ if (fullCard.getAttachments().size() == 0) {
+ DeckLog.logError(new IllegalStateException(AttachmentsActivity.class.getSimpleName() + " called, but card " + fullCard.getLocalId() + "has no attachments"));
+ finish();
+ } else {
+ if (currentAttachment != 0L) {
+ for (Attachment a : attachments) {
+ if (a.getLocalId() == currentAttachment) {
+ Glide.with(this)
+ .load(AttachmentUtil.getUrl(account.getUrl(), fullCard.getId(), a.getId()))
+ .into(binding.image);
+ binding.toolbar.setTitle(a.getBasename());
+ break;
}
}
+ } else {
+ DeckLog.logError(new IllegalStateException("No " + BUNDLE_KEY_CURRENT_ATTACHMENT_LOCAL_ID + " was provided. Falling back to displaying first image."));
+ Glide.with(this)
+ .load(AttachmentUtil.getUrl(account.getUrl(), fullCard.getId(), attachments.get(0).getId()))
+ .into(binding.image);
+ binding.toolbar.setTitle(attachments.get(0).getBasename());
}
- binding.boardSelector.setOnItemSelectedListener(this);
- });
- });
- } catch (NextcloudFilesAppAccountNotFoundException | NoCurrentAccountSelectedException e) {
- e.printStackTrace();
- }
- } else {
- if (accountId == 0L) {
- throw new IllegalArgumentException("No accountId given");
- }
- observeOnce(syncManager.getFullBoardById(accountId, boardId), AttachmentsActivity.this, (fullBoard -> {
- canEdit = fullBoard.getBoard().isPermissionEdit();
- invalidateOptionsMenu();
- if (createMode) {
- fullCard = new FullCard();
- originalCard = new FullCard();
- fullCard.setLabels(new ArrayList<>());
- fullCard.setAssignedUsers(new ArrayList<>());
- Card card = new Card();
- card.setStackId(stackId);
- fullCard.setCard(card);
- setupViewPager();
- setupTitle(createMode);
- } else {
- observeOnce(syncManager.getCardByLocalId(accountId, localId), AttachmentsActivity.this, (next) -> {
- fullCard = next;
- originalCard = new FullCard(fullCard);
- setupViewPager();
- setupTitle(createMode);
- });
- }
- }));
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- if (canEdit) {
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.card_edit_menu, menu);
- } else {
- menu.clear();
- }
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == R.id.action_card_save) {
- saveAndFinish();
- }
- return super.onOptionsItemSelected(item);
- }
-
- private void saveAndFinish() {
- if (!pendingCreation) {
- pendingCreation = true;
- if (fullCard.getCard().getTitle() == null || fullCard.getCard().getTitle().isEmpty()) {
- fullCard.getCard().setTitle(CardUtil.generateTitleFromDescription(fullCard.getCard().getDescription()));
- }
- if (fullCard.getCard().getTitle().isEmpty()) {
- new AlertDialog.Builder(this)
- .setTitle("Title is mandatory")
- .setMessage("Provide at least a title or description")
- .setPositiveButton(android.R.string.ok, null)
- .setOnDismissListener(dialog -> {
- pendingCreation = false;
- })
- .show();
- } else {
- if (createMode) {
- observeOnce(syncManager.createFullCard(accountId, boardId, stackId, fullCard), AttachmentsActivity.this, (card) -> super.finish());
- } else {
- observeOnce(syncManager.updateCard(fullCard), AttachmentsActivity.this, (card) -> super.finish());
- }
- }
- }
- }
-
- private void setupViewPager() {
- binding.tabLayout.removeAllTabs();
- binding.tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
- CardTabAdapter adapter = new CardTabAdapter(getSupportFragmentManager(), getLifecycle(), accountId, localId, boardId, canEdit);
- binding.pager.setOffscreenPageLimit(2);
- binding.pager.setAdapter(adapter);
- new TabLayoutMediator(binding.tabLayout, binding.pager, (tab, position) -> tab.setText(tabTitles[position])).attach();
- }
-
- private void setupTitle(boolean createMode) {
- binding.title.setText(fullCard.getCard().getTitle());
- if (canEdit) {
- if (createMode) {
- binding.title.requestFocus();
- getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
- if (fullCard.getCard().getTitle() != null) {
- binding.title.setSelection(fullCard.getCard().getTitle().length());
- }
- }
- binding.titleTextInputLayout.setHint(getString(createMode ? R.string.simple_add : R.string.edit));
- binding.title.addTextChangedListener(new TextWatcher() {
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- fullCard.getCard().setTitle(binding.title.getText().toString());
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- }
- });
- } else {
- binding.titleTextInputLayout.setHintEnabled(false);
- binding.title.setEnabled(false);
- }
- }
-
- @Override
- public void onDescriptionChanged(String description) {
- this.fullCard.getCard().setDescription(description);
- }
-
- @Override
- public void onUserAdded(User user) {
- this.fullCard.getAssignedUsers().add(user);
- }
-
- @Override
- public void onUserRemoved(User user) {
- this.fullCard.getAssignedUsers().remove(user);
- }
-
- @Override
- public void onLabelAdded(Label label) {
- this.fullCard.getLabels().add(label);
- }
-
- @Override
- public void onLabelRemoved(Label label) {
- this.fullCard.getLabels().remove(label);
- }
-
- @Override
- public void onDueDateChanged(Date dueDate) {
- this.fullCard.getCard().setDueDate(dueDate);
- }
-
- @Override
- public boolean onSupportNavigateUp() {
- finish(); // close this activity as oppose to navigating up
- return true;
- }
-
- @Override
- public void onBackPressed() {
- finish();
- }
-
- @Override
- public void finish() {
- if (!fullCard.equals(originalCard) && canEdit) {
- new AlertDialog.Builder(this)
- .setTitle(R.string.simple_save)
- .setMessage(R.string.do_you_want_to_save_your_changes)
- .setPositiveButton(R.string.simple_save, (dialog, whichButton) -> saveAndFinish())
- .setNegativeButton(R.string.simple_discard, (dialog, whichButton) -> super.finish()).show();
- } else {
- super.finish();
- }
- }
-
- @Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- boardId = ((Board) binding.boardSelector.getItemAtPosition(position)).getLocalId();
- observeOnce(syncManager.getFullBoardById(accountId, boardId), AttachmentsActivity.this, (fullBoard -> {
- canEdit = fullBoard.getBoard().isPermissionEdit();
-
- SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
- long savedStackId = sharedPreferences.getLong(getString(R.string.shared_preference_last_stack_for_account_and_board_) + accountId + "_" + boardId, 0L);
- DeckLog.log("--- Read: shared_preference_last_stack_for_account_and_board" + accountId + "_" + boardId + " | " + savedStackId);
- if (savedStackId == 0L) {
- observeOnce(syncManager.getStacksForBoard(accountId, boardId), AttachmentsActivity.this, (stacks -> {
- if (stacks != null && stacks.size() > 0) {
- stackId = stacks.get(0).getLocalId();
}
}));
- } else {
- stackId = savedStackId;
- }
- if (fullCard == null) {
- invalidateOptionsMenu();
- fullCard = new FullCard();
- fullCard.setLabels(new ArrayList<>());
- fullCard.setAssignedUsers(new ArrayList<>());
- Card card = new Card();
- card.setStackId(stackId);
- fullCard.setCard(card);
- setupViewPager();
- setupTitle(createMode);
- }
- }));
}
@Override
- public void onNothingSelected(AdapterView<?> parent) {
-
+ public boolean onTouchEvent(MotionEvent event) {
+ supportFinishAfterTransition();
+ return true;
}
@Override
- public void onCommentAdded(String comment) {
- syncManager.addCommentToCard(accountId, boardId, localId, comment);
+ public boolean onSupportNavigateUp() {
+ supportFinishAfterTransition();
+ return true;
}
}
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 1ea2c43e1..7cd953787 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
@@ -6,20 +6,22 @@ import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
+import android.os.Build;
import android.text.format.Formatter;
+import android.transition.Explode;
import android.util.Log;
import android.view.LayoutInflater;
+import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull;
-import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityOptionsCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
-import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import java.util.List;
@@ -29,31 +31,40 @@ import it.niedermann.nextcloud.deck.databinding.ItemAttachmentImageBinding;
import it.niedermann.nextcloud.deck.model.Account;
import it.niedermann.nextcloud.deck.model.Attachment;
import it.niedermann.nextcloud.deck.model.enums.DBStatus;
+import it.niedermann.nextcloud.deck.ui.AttachmentsActivity;
+import it.niedermann.nextcloud.deck.util.AttachmentUtil;
import it.niedermann.nextcloud.deck.util.DateUtil;
import it.niedermann.nextcloud.deck.util.DeleteDialogBuilder;
import static android.content.Context.CLIPBOARD_SERVICE;
import static androidx.constraintlayout.widget.Constraints.TAG;
+import static it.niedermann.nextcloud.deck.ui.AttachmentsActivity.BUNDLE_KEY_CURRENT_ATTACHMENT_LOCAL_ID;
+import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.BUNDLE_KEY_ACCOUNT_ID;
+import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.BUNDLE_KEY_LOCAL_ID;
public class AttachmentAdapter extends RecyclerView.Adapter<AttachmentAdapter.AttachmentViewHolder> {
public static final int VIEW_TYPE_DEFAULT = 2;
public static final int VIEW_TYPE_IMAGE = 1;
+ private final MenuInflater menuInflator;
private final Account account;
private final long cardRemoteId;
+ private final long cardLocalId;
@NonNull
private List<Attachment> attachments;
@NonNull
private AttachmentDeletedListener attachmentDeletedListener;
private Context context;
- AttachmentAdapter(@NonNull AttachmentDeletedListener attachmentDeletedListener, @NonNull Account account, long cardRemoteId, @NonNull List<Attachment> attachments) {
+ AttachmentAdapter(@NonNull MenuInflater menuInflator, @NonNull AttachmentDeletedListener attachmentDeletedListener, @NonNull Account account, long cardLocalId, long cardRemoteId, @NonNull List<Attachment> attachments) {
super();
+ this.menuInflator = menuInflator;
this.attachmentDeletedListener = attachmentDeletedListener;
this.attachments = attachments;
this.account = account;
this.cardRemoteId = cardRemoteId;
+ this.cardLocalId = cardLocalId;
}
@NonNull
@@ -75,10 +86,10 @@ public class AttachmentAdapter extends RecyclerView.Adapter<AttachmentAdapter.At
public void onBindViewHolder(@NonNull AttachmentViewHolder holder, int position) {
Attachment attachment = attachments.get(position);
int viewType = getItemViewType(position);
- String uri = account.getUrl() + "/index.php/apps/deck/cards/" + cardRemoteId + "/attachment/" + attachment.getId();
+ String uri = AttachmentUtil.getUrl(account.getUrl(), cardRemoteId, attachment.getId());
holder.setNotSyncedYetStatus(attachment.getStatusEnum() == DBStatus.UP_TO_DATE);
holder.getRootView().setOnCreateContextMenuListener((menu, v, menuInfo) -> {
- ((Activity) context).getMenuInflater().inflate(R.menu.attachment_menu, menu);
+ menuInflator.inflate(R.menu.attachment_menu, menu);
menu.findItem(R.id.delete).setOnMenuItemClickListener(item -> {
new DeleteDialogBuilder(context)
.setTitle(context.getString(R.string.delete_something, attachment.getFilename()))
@@ -89,7 +100,7 @@ public class AttachmentAdapter extends RecyclerView.Adapter<AttachmentAdapter.At
return false;
});
menu.findItem(android.R.id.copyUrl).setOnMenuItemClickListener(item -> {
- final android.content.ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(CLIPBOARD_SERVICE);
+ final ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(CLIPBOARD_SERVICE);
ClipData clipData = ClipData.newPlainText(attachment.getFilename(), uri);
if (clipboardManager != null) {
clipboardManager.setPrimaryClip(clipData);
@@ -103,14 +114,24 @@ public class AttachmentAdapter extends RecyclerView.Adapter<AttachmentAdapter.At
if (attachment.getMimetype() != null) {
if (attachment.getMimetype().startsWith("image")) {
- // TODO Glide is currently not yet able to use SSO and fails on authentication
Glide.with(context)
.load(uri)
- .transform(new CenterCrop())
.error(R.drawable.ic_image_grey600_24dp)
.into(holder.getPreview());
holder.getPreview().setImageResource(R.drawable.ic_image_grey600_24dp);
- holder.getPreview().getRootView().setOnClickListener((v) -> AttachmentDialogFragment.newInstance(uri, attachment.getBasename()).show(((AppCompatActivity) context).getSupportFragmentManager(), "preview"));
+ holder.getPreview().getRootView().setOnClickListener((v) -> {
+ Intent intent = new Intent(context, AttachmentsActivity.class);
+ intent.putExtra(BUNDLE_KEY_ACCOUNT_ID, account.getId());
+ intent.putExtra(BUNDLE_KEY_LOCAL_ID, cardLocalId);
+ intent.putExtra(BUNDLE_KEY_CURRENT_ATTACHMENT_LOCAL_ID, attachment.getLocalId());
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && context instanceof Activity) {
+ ((Activity) context).getWindow().setSharedElementEnterTransition(new Explode());
+ context.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation((Activity) context, holder.getPreview(), context.getString(R.string.transition_attachment_preview)).toBundle());
+ } else {
+ context.startActivity(intent);
+ }
+ });
} else if (attachment.getMimetype().startsWith("audio")) {
holder.getPreview().setImageResource(R.drawable.ic_music_note_grey600_24dp);
} else if (attachment.getMimetype().startsWith("video")) {
@@ -127,8 +148,8 @@ public class AttachmentAdapter extends RecyclerView.Adapter<AttachmentAdapter.At
default: {
DefaultAttachmentViewHolder defaultHolder = (DefaultAttachmentViewHolder) holder;
defaultHolder.binding.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()));
+ Intent openURL = new Intent(Intent.ACTION_VIEW);
+ openURL.setData(Uri.parse(AttachmentUtil.getUrl(account.getUrl(), cardRemoteId, attachment.getId())));
context.startActivity(openURL);
});
defaultHolder.binding.filename.setText(attachment.getBasename());
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentDialogFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentDialogFragment.java
deleted file mode 100644
index da2086d4c..000000000
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentDialogFragment.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package it.niedermann.nextcloud.deck.ui.card;
-
-import android.app.Dialog;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
-import androidx.fragment.app.DialogFragment;
-
-import com.bumptech.glide.Glide;
-
-import java.util.Objects;
-
-import it.niedermann.nextcloud.deck.Application;
-import it.niedermann.nextcloud.deck.R;
-import it.niedermann.nextcloud.deck.databinding.DialogAttachmentBinding;
-
-public class AttachmentDialogFragment extends DialogFragment {
-
- private static final String BUNDLE_KEY_URL = "url";
- private static final String BUNDLE_KEY_ALT = "alt";
-
- /**
- * Use newInstance()-Method
- */
- public AttachmentDialogFragment() {
- }
-
- @NonNull
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- DialogAttachmentBinding binding = DialogAttachmentBinding.inflate(requireActivity().getLayoutInflater());
-
- Glide.with(this)
-// .addDefaultRequestListener(new RequestListener<Object>() {
-// @Override
-// public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Object> target, boolean isFirstResource) {
-// image.setVisibility(View.VISIBLE);
-// progressBar.setVisibility(View.GONE);
-// return false;
-// }
-//
-// @Override
-// public boolean onResourceReady(Object resource, Object model, Target<Object> target, DataSource dataSource, boolean isFirstResource) {
-// progressBar.setVisibility(View.GONE);
-// image.setVisibility(View.VISIBLE);
-// return false;
-// }
-// })
- .load(requireArguments().getString(BUNDLE_KEY_URL))
- .into(binding.image);
- binding.image.setContentDescription(requireArguments().getString(BUNDLE_KEY_ALT));
- binding.image.getRootView().setOnClickListener((v) -> dismiss());
-
- return new AlertDialog.Builder(requireActivity(), Application.getAppTheme(getContext()) ? R.style.DialogDarkTheme : R.style.ThemeOverlay_AppCompat_Dialog_Alert)
- .setView(binding.getRoot())
- .create();
- }
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- Objects.requireNonNull(requireDialog().getWindow()).setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
- return super.onCreateView(inflater, container, savedInstanceState);
- }
-
- public static AttachmentDialogFragment newInstance(@NonNull String url, @NonNull String alt) {
- Bundle bundle = new Bundle();
- bundle.putString(BUNDLE_KEY_URL, url);
- bundle.putString(BUNDLE_KEY_ALT, alt);
-
- AttachmentDialogFragment fragment = new AttachmentDialogFragment();
- fragment.setArguments(bundle);
-
- return fragment;
- }
-}
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAttachmentsFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAttachmentsFragment.java
index a8a126b67..33e5a6306 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAttachmentsFragment.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAttachmentsFragment.java
@@ -66,7 +66,13 @@ public class CardAttachmentsFragment extends Fragment implements AttachmentAdapt
this.binding.emptyContentView.setVisibility(View.GONE);
this.binding.attachmentsList.setVisibility(View.VISIBLE);
syncManager.readAccount(accountId).observe(getViewLifecycleOwner(), (Account account) -> {
- RecyclerView.Adapter adapter = new AttachmentAdapter(this, account, fullCard.getCard().getId(), fullCard.getAttachments());
+ RecyclerView.Adapter adapter = new AttachmentAdapter(
+ requireActivity().getMenuInflater(),
+ this,
+ account,
+ fullCard.getCard().getLocalId(),
+ fullCard.getCard().getId(),
+ fullCard.getAttachments());
binding.attachmentsList.setAdapter(adapter);
GridLayoutManager glm = new GridLayoutManager(getActivity(), 3);
@@ -130,15 +136,13 @@ public class CardAttachmentsFragment extends Fragment implements AttachmentAdapt
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_ADD_ATTACHMENT && resultCode == Activity.RESULT_OK) {
- Uri uri = null;
if (data != null) {
- uri = data.getData();
+ Uri uri = data.getData();
Log.i(TAG, "Uri: " + uri.toString());
String path = FileUtils.getPath(getContext(), uri);
File uploadFile = new File(path);
syncManager.addAttachmentToCard(accountId, cardId, Attachment.getMimetypeForUri(getContext(), uri), uploadFile);
}
-
}
}
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
new file mode 100644
index 000000000..d123ee4c6
--- /dev/null
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/util/AttachmentUtil.java
@@ -0,0 +1,15 @@
+package it.niedermann.nextcloud.deck.util;
+
+/**
+ * Created by stefan on 07.03.20.
+ */
+
+public class AttachmentUtil {
+
+ private AttachmentUtil() {
+ }
+
+ public static String getUrl(String accountUrl, long cardRemoteId, long attachmentRemoteId) {
+ return accountUrl + "/index.php/apps/deck/cards/" + cardRemoteId + "/attachment/" + attachmentRemoteId;
+ }
+}
diff --git a/app/src/main/res/layout/activity_attachments.xml b/app/src/main/res/layout/activity_attachments.xml
new file mode 100644
index 000000000..4d1fabe17
--- /dev/null
+++ b/app/src/main/res/layout/activity_attachments.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ tools:theme="@style/TransparentTheme">
+
+ <com.google.android.material.appbar.AppBarLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <androidx.appcompat.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:navigationIcon="@drawable/ic_arrow_back_white_24dp"
+ app:titleTextColor="@android:color/white"
+ tools:title="@string/attachments" />
+ </com.google.android.material.appbar.AppBarLayout>
+
+ <androidx.viewpager2.widget.ViewPager2
+ android:id="@+id/view_pager"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <androidx.appcompat.widget.AppCompatImageView
+ android:id="@+id/image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:contentDescription="@null"
+ android:transitionName="@string/transition_attachment_preview"
+ tools:src="@drawable/ic_image_grey600_24dp"
+ tools:targetApi="lollipop" />
+</LinearLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_attachment.xml b/app/src/main/res/layout/dialog_attachment.xml
deleted file mode 100644
index 4b3f96008..000000000
--- a/app/src/main/res/layout/dialog_attachment.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
-
- <ImageView xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/image"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:contentDescription="@null"
- tools:src="@drawable/ic_image_grey600_24dp" />
-
- <!-- <ProgressBar-->
- <!-- android:id="@+id/progressBar"-->
- <!-- android:visibility="visible"-->
- <!-- android:layout_width="wrap_content"-->
- <!-- android:layout_height="wrap_content" />-->
-</FrameLayout> \ 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
index f58783559..11d147d92 100644
--- a/app/src/main/res/layout/item_attachment_default.xml
+++ b/app/src/main/res/layout/item_attachment_default.xml
@@ -20,6 +20,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="@dimen/standard_half_margin"
+ android:transitionName="@string/transition_attachment_preview"
app:srcCompat="@drawable/ic_attach_file_grey600_24dp" />
<androidx.appcompat.widget.AppCompatImageView
diff --git a/app/src/main/res/layout/item_attachment_image.xml b/app/src/main/res/layout/item_attachment_image.xml
index 9b9d64416..42ab7bc66 100644
--- a/app/src/main/res/layout/item_attachment_image.xml
+++ b/app/src/main/res/layout/item_attachment_image.xml
@@ -11,6 +11,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
+ android:scaleType="centerCrop"
+ android:transitionName="@string/transition_attachment_preview"
app:srcCompat="@drawable/ic_image_grey600_24dp" />
<androidx.appcompat.widget.AppCompatImageView
diff --git a/app/src/main/res/values/setup.xml b/app/src/main/res/values/setup.xml
index e9b860fba..db81c60a1 100644
--- a/app/src/main/res/values/setup.xml
+++ b/app/src/main/res/values/setup.xml
@@ -33,4 +33,7 @@
<integer name="minimum_server_app_major" translatable="false">0</integer>
<integer name="minimum_server_app_minor" translatable="false">6</integer>
<integer name="minimum_server_app_patch" translatable="false">4</integer>
+
+ <!-- Transitions -->
+ <string name="transition_attachment_preview" translatable="false">transition_attachment_preview</string>
</resources> \ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 300a9e22a..1e3be799f 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -1,4 +1,4 @@
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar.Bridge">
@@ -6,7 +6,7 @@
<item name="colorPrimaryDark">@color/primary</item>
<item name="colorAccent">@color/primary</item>
<item name="android:windowContentOverlay">@null</item>
- <item name="android:elevation">@null</item>
+ <item name="android:elevation" tools:targetApi="lollipop">@null</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
@@ -38,7 +38,7 @@
<style name="PrimaryCTAButton" parent="android:Widget.DeviceDefault.Button">
<item name="android:background">@color/primary</item>
<item name="android:textColor">@color/fg_accent</item>
- <item name="android:elevation">5dp</item>
+ <item name="android:elevation" tools:targetApi="lollipop">5dp</item>
</style>
<style name="NavigationView">
@@ -51,11 +51,15 @@
</style>
<style name="DeleteDialogDarkTheme" parent="DialogDarkTheme">
- <item name="android:buttonBarPositiveButtonStyle">@style/PositiveButtonStyle</item>
+ <item name="android:buttonBarPositiveButtonStyle" tools:targetApi="lollipop">
+ @style/PositiveButtonStyle
+ </item>
</style>
<style name="DeleteDialogTheme" parent="ThemeOverlay.AppCompat.Dialog.Alert">
- <item name="android:buttonBarPositiveButtonStyle">@style/PositiveButtonStyle</item>
+ <item name="android:buttonBarPositiveButtonStyle" tools:targetApi="lollipop">
+ @style/PositiveButtonStyle
+ </item>
</style>
<style name="PositiveButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
@@ -63,6 +67,13 @@
</style>
<style name="Spinner" parent="ThemeOverlay.AppCompat.Dark">
- <item name="android:textColor">@android:color/white</item>
+ <item name="android:textColor">@android:color/white</item>
+ </style>
+
+ <style name="TransparentTheme" parent="Theme.AppCompat.NoActionBar">
+ <item name="android:windowNoTitle">true</item>
+ <item name="android:windowBackground">@android:color/background_dark</item>
+ <item name="android:colorBackgroundCacheHint">@null</item>
+ <item name="android:windowIsTranslucent">true</item>
</style>
</resources>