diff options
Diffstat (limited to 'app/src/main/java/it/niedermann/nextcloud')
4 files changed, 221 insertions, 5 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsActivity.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsActivity.java index 30575af29..3e1e7c9be 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsActivity.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsActivity.java @@ -10,10 +10,23 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.lifecycle.ViewModelProvider; +import it.niedermann.nextcloud.deck.DeckLog; +import it.niedermann.nextcloud.deck.api.ResponseCallback; import it.niedermann.nextcloud.deck.databinding.ActivityUpcomingCardsBinding; +import it.niedermann.nextcloud.deck.model.Card; +import it.niedermann.nextcloud.deck.model.Stack; +import it.niedermann.nextcloud.deck.model.full.FullCard; +import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.WrappedLiveData; +import it.niedermann.nextcloud.deck.ui.exception.ExceptionDialogFragment; import it.niedermann.nextcloud.deck.ui.exception.ExceptionHandler; +import it.niedermann.nextcloud.deck.ui.movecard.MoveCardListener; -public class UpcomingCardsActivity extends AppCompatActivity { +import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.LiveDataHelper.observeOnce; + +public class UpcomingCardsActivity extends AppCompatActivity implements MoveCardListener { + + private UpcomingCardsViewModel viewModel; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -22,12 +35,41 @@ public class UpcomingCardsActivity extends AppCompatActivity { Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this)); final ActivityUpcomingCardsBinding binding = ActivityUpcomingCardsBinding.inflate(getLayoutInflater()); - final UpcomingCardsViewModel viewModel = new ViewModelProvider(this).get(UpcomingCardsViewModel.class); + viewModel = new ViewModelProvider(this).get(UpcomingCardsViewModel.class); setContentView(binding.getRoot()); setSupportActionBar(binding.toolbar); - final UpcomingCardsAdapter adapter = new UpcomingCardsAdapter(this, getSupportFragmentManager()); + final UpcomingCardsAdapter adapter = new UpcomingCardsAdapter(this, getSupportFragmentManager(), + viewModel::assignUser, + viewModel::unassignUser, + (fullCard) -> viewModel.archiveCard(fullCard, new ResponseCallback<FullCard>() { + @Override + public void onResponse(FullCard response) { + DeckLog.info("Successfully archived", Card.class.getSimpleName(), fullCard.getCard().getTitle()); + } + + @Override + public void onError(Throwable throwable) { + ResponseCallback.super.onError(throwable); + runOnUiThread(() -> ExceptionDialogFragment.newInstance(throwable, null).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName())); + } + }), + (card) -> viewModel.deleteCard(card, new ResponseCallback<Void>() { + @Override + public void onResponse(Void response) { + DeckLog.info("Successfully deleted card", card.getTitle()); + } + + @Override + public void onError(Throwable throwable) { + if (!SyncManager.ignoreExceptionOnVoidError(throwable)) { + ResponseCallback.super.onError(throwable); + runOnUiThread(() -> ExceptionDialogFragment.newInstance(throwable, null).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName())); + } + } + }) + ); binding.recyclerView.setAdapter(adapter); viewModel.getUpcomingCards().observe(this, items -> { if (items.size() > 0) { @@ -46,4 +88,16 @@ public class UpcomingCardsActivity extends AppCompatActivity { return new Intent(context, UpcomingCardsActivity.class) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } + + @Override + public void move(long originAccountId, long originCardLocalId, long targetAccountId, long targetBoardLocalId, long targetStackLocalId) { + final WrappedLiveData<Void> liveData = viewModel.moveCard(originAccountId, originCardLocalId, targetAccountId, targetBoardLocalId, targetStackLocalId); + observeOnce(liveData, this, (next) -> { + if (liveData.hasError() && !SyncManager.ignoreExceptionOnVoidError(liveData.getError())) { + ExceptionDialogFragment.newInstance(liveData.getError(), null).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); + } else { + DeckLog.log("Moved", Card.class.getSimpleName(), originCardLocalId, "to", Stack.class.getSimpleName(), targetStackLocalId); + } + }); + } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsAdapter.java index f97c10cbe..80d3339b2 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsAdapter.java @@ -12,6 +12,8 @@ import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.Consumer; import java.util.stream.Collectors; import it.niedermann.nextcloud.deck.R; @@ -19,6 +21,8 @@ import it.niedermann.nextcloud.deck.databinding.ItemCardCompactBinding; import it.niedermann.nextcloud.deck.databinding.ItemCardDefaultBinding; import it.niedermann.nextcloud.deck.databinding.ItemCardDefaultOnlyTitleBinding; import it.niedermann.nextcloud.deck.databinding.ItemSectionBinding; +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.Card; import it.niedermann.nextcloud.deck.model.full.FullCard; import it.niedermann.nextcloud.deck.ui.card.AbstractCardViewHolder; import it.niedermann.nextcloud.deck.ui.card.CompactCardViewHolder; @@ -41,13 +45,29 @@ public class UpcomingCardsAdapter extends RecyclerView.Adapter<RecyclerView.View protected String counterMaxValue; @ColorInt protected int mainColor; + @NonNull + private final BiConsumer<Account, Card> assignCard; + @NonNull + private final BiConsumer<Account, Card> unassignCard; + @NonNull + private final Consumer<FullCard> archiveCard; + @NonNull + private final Consumer<Card> deleteCard; - public UpcomingCardsAdapter(@NonNull Activity activity, @NonNull FragmentManager fragmentManager) { + public UpcomingCardsAdapter(@NonNull Activity activity, @NonNull FragmentManager fragmentManager, + @NonNull BiConsumer<Account, Card> assignCard, + @NonNull BiConsumer<Account, Card> unassignCard, + @NonNull Consumer<FullCard> archiveCard, + @NonNull Consumer<Card> deleteCard) { this.activity = activity; this.counterMaxValue = this.activity.getString(R.string.counter_max_value); this.fragmentManager = fragmentManager; this.mainColor = ContextCompat.getColor(this.activity, R.color.defaultBrand); this.compactMode = getDefaultSharedPreferences(this.activity).getBoolean(this.activity.getString(R.string.pref_key_compact), false); + this.assignCard = assignCard; + this.unassignCard = unassignCard; + this.archiveCard = archiveCard; + this.deleteCard = deleteCard; setHasStableIds(true); } @@ -118,7 +138,18 @@ public class UpcomingCardsAdapter extends RecyclerView.Adapter<RecyclerView.View if (viewHolder.getClass() == AbstractCardViewHolder.class || viewHolder instanceof AbstractCardViewHolder) { final UpcomingCardsAdapterItem cardItem = (UpcomingCardsAdapterItem) item; AbstractCardViewHolder cardViewHolder = ((AbstractCardViewHolder) viewHolder); - cardViewHolder.bind(cardItem.getFullCard(), cardItem.getAccount(), cardItem.getCurrentBoardRemoteId(), false, R.menu.card_menu, (a, b) -> true, counterMaxValue, mainColor); + cardViewHolder.bind(cardItem.getFullCard(), cardItem.getAccount(), cardItem.getCurrentBoardRemoteId(), cardItem.currentBoardHasEditPermission(), R.menu.card_menu, + new UpcomingCardsOptionsItemSelectedListener( + cardItem.getAccount(), + activity, + fragmentManager, + cardItem.getCurrentBoardRemoteId(), + cardItem.getCurrentBoardLocalId(), + assignCard, + unassignCard, + archiveCard, + deleteCard + ), counterMaxValue, mainColor); cardViewHolder.bindCardClickListener((v) -> activity.startActivity(EditActivity.createEditCardIntent(activity, cardItem.getAccount(), cardItem.getCurrentBoardLocalId(), cardItem.getFullCard().getLocalId()))); } else { throw new IllegalStateException("Item at position " + position + " is a " + item.getClass().getSimpleName() + " but viewHolder is no " + AbstractCardViewHolder.class.getSimpleName()); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsOptionsItemSelectedListener.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsOptionsItemSelectedListener.java new file mode 100644 index 000000000..403292840 --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsOptionsItemSelectedListener.java @@ -0,0 +1,106 @@ +package it.niedermann.nextcloud.deck.ui.upcomingcards; + +import android.app.Activity; +import android.content.Intent; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; + +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +import it.niedermann.nextcloud.deck.DeckLog; +import it.niedermann.nextcloud.deck.R; +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.Card; +import it.niedermann.nextcloud.deck.model.full.FullCard; +import it.niedermann.nextcloud.deck.ui.card.CardOptionsItemSelectedListener; +import it.niedermann.nextcloud.deck.ui.movecard.MoveCardDialogFragment; +import it.niedermann.nextcloud.deck.util.CardUtil; + +import static it.niedermann.nextcloud.deck.util.MimeTypeUtil.TEXT_PLAIN; + +public class UpcomingCardsOptionsItemSelectedListener implements CardOptionsItemSelectedListener { + @NonNull + private final Account account; + @NonNull + private final Activity activity; + @NonNull + private final FragmentManager fragmentManager; + @Nullable + private final Long boardRemoteId; + private final long boardLocalId; + @NonNull + private final BiConsumer<Account, Card> assignCard; + @NonNull + private final BiConsumer<Account, Card> unassignCard; + @NonNull + private final Consumer<FullCard> archiveCard; + @NonNull + private final Consumer<Card> deleteCard; + + public UpcomingCardsOptionsItemSelectedListener(@NonNull Account account, + @NonNull Activity activity, + @NonNull FragmentManager fragmentManager, + @Nullable Long boardRemoteId, + long boardLocalId, + @NonNull BiConsumer<Account, Card> assignCard, + @NonNull BiConsumer<Account, Card> unassignCard, + @NonNull Consumer<FullCard> archiveCard, + @NonNull Consumer<Card> deleteCard + ) { + this.account = account; + this.activity = activity; + this.fragmentManager = fragmentManager; + this.boardRemoteId = boardRemoteId; + this.boardLocalId = boardLocalId; + this.assignCard = assignCard; + this.unassignCard = unassignCard; + this.archiveCard = archiveCard; + this.deleteCard = deleteCard; + } + + @Override + public boolean onCardOptionsItemSelected(@NonNull MenuItem menuItem, @NonNull FullCard fullCard) { + final int itemId = menuItem.getItemId(); + if (itemId == R.id.share_link) { + final Intent shareIntent = new Intent() + .setAction(Intent.ACTION_SEND) + .setType(TEXT_PLAIN) + .putExtra(Intent.EXTRA_SUBJECT, fullCard.getCard().getTitle()) + .putExtra(Intent.EXTRA_TITLE, fullCard.getCard().getTitle()) + .putExtra(Intent.EXTRA_TEXT, account.getUrl() + activity.getString(account.getServerDeckVersionAsObject().getShareLinkResource(), boardRemoteId, fullCard.getCard().getId())); + activity.startActivity(Intent.createChooser(shareIntent, fullCard.getCard().getTitle())); + return true; + } else if (itemId == R.id.share_content) { + final Intent shareIntent = new Intent() + .setAction(Intent.ACTION_SEND) + .setType(TEXT_PLAIN) + .putExtra(Intent.EXTRA_SUBJECT, fullCard.getCard().getTitle()) + .putExtra(Intent.EXTRA_TITLE, fullCard.getCard().getTitle()) + .putExtra(Intent.EXTRA_TEXT, CardUtil.getCardContentAsString(activity, fullCard)); + activity.startActivity(Intent.createChooser(shareIntent, fullCard.getCard().getTitle())); + } else if (itemId == R.id.action_card_assign) { + assignCard.accept(account, fullCard.getCard()); + return true; + } else if (itemId == R.id.action_card_unassign) { + unassignCard.accept(account, fullCard.getCard()); + return true; + } else if (itemId == R.id.action_card_move) { + DeckLog.verbose("[Move card] Launch move dialog for " + Card.class.getSimpleName() + " \"" + fullCard.getCard().getTitle() + "\" (#" + fullCard.getLocalId() + ")"); + MoveCardDialogFragment + .newInstance(fullCard.getAccountId(), boardLocalId, fullCard.getCard().getTitle(), fullCard.getLocalId(), CardUtil.cardHasCommentsOrAttachments(fullCard)) + .show(fragmentManager, MoveCardDialogFragment.class.getSimpleName()); + return true; + } else if (itemId == R.id.action_card_archive) { + archiveCard.accept(fullCard); + return true; + } else if (itemId == R.id.action_card_delete) { + deleteCard.accept(fullCard.getCard()); + return true; + } + return true; + } +}
\ No newline at end of file diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsViewModel.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsViewModel.java index b53e25115..2cff86806 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsViewModel.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsViewModel.java @@ -9,7 +9,12 @@ import androidx.lifecycle.LiveData; import java.util.List; import java.util.stream.Collectors; +import it.niedermann.nextcloud.deck.api.ResponseCallback; +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.Card; +import it.niedermann.nextcloud.deck.model.full.FullCard; import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; +import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.WrappedLiveData; import static androidx.lifecycle.Transformations.map; @@ -29,4 +34,24 @@ public class UpcomingCardsViewModel extends AndroidViewModel { cards.stream().filter(card -> card.getAccount() != null).collect(Collectors.toList()) ); } + + public void assignUser(@NonNull Account account, @NonNull Card card) { + new Thread(() -> syncManager.assignUserToCard(syncManager.getUserByUidDirectly(card.getAccountId(), account.getUserName()), card)).start(); + } + + public void unassignUser(@NonNull Account account, @NonNull Card card) { + new Thread(() -> syncManager.unassignUserFromCard(syncManager.getUserByUidDirectly(card.getAccountId(), account.getUserName()), card)).start(); + } + + public void archiveCard(@NonNull FullCard card, @NonNull ResponseCallback<FullCard> callback) { + syncManager.archiveCard(card, callback); + } + + public void deleteCard(@NonNull Card card, @NonNull ResponseCallback<Void> callback) { + syncManager.deleteCard(card, callback); + } + + public WrappedLiveData<Void> moveCard(long originAccountId, long originCardLocalId, long targetAccountId, long targetBoardLocalId, long targetStackLocalId) { + return syncManager.moveCard(originAccountId, originCardLocalId, targetAccountId, targetBoardLocalId, targetStackLocalId); + } } |