From eba94ddd0d705a7659cc16cb17f7c140ee9ed3b6 Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Fri, 9 Apr 2021 19:51:04 +0200 Subject: #690 Upcoming cards Section headers Signed-off-by: Stefan Niedermann --- .../ui/upcomingcards/UpcomingCardsAdapter.java | 104 ++++++++++++++++++++- .../ui/upcomingcards/UpcomingCardsViewModel.java | 29 ++---- 2 files changed, 109 insertions(+), 24 deletions(-) (limited to 'app/src/main/java/it/niedermann/nextcloud') 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 d879c5589..3d17728c3 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 @@ -1,24 +1,34 @@ package it.niedermann.nextcloud.deck.ui.upcomingcards; import android.app.Activity; +import android.content.Context; import android.view.LayoutInflater; import android.view.ViewGroup; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; import androidx.core.content.ContextCompat; import androidx.fragment.app.FragmentManager; import androidx.recyclerview.widget.RecyclerView; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; +import it.niedermann.nextcloud.deck.DeckLog; import it.niedermann.nextcloud.deck.R; 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.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; @@ -27,6 +37,7 @@ import it.niedermann.nextcloud.deck.ui.card.DefaultCardViewHolder; import it.niedermann.nextcloud.deck.ui.card.EditActivity; import static androidx.preference.PreferenceManager.getDefaultSharedPreferences; +import static java.time.temporal.ChronoUnit.DAYS; public class UpcomingCardsAdapter extends RecyclerView.Adapter { @@ -135,8 +146,97 @@ public class UpcomingCardsAdapter extends RecyclerView.Adapter items) { this.items.clear(); - this.items.add(new UpcomingCardsAdapterSectionItem("Hello there")); - this.items.addAll(items); + + final Comparator comparator = Comparator.comparing((card -> { + if (card != null && + card.getFullCard() != null && + card.getFullCard().getCard() != null && + card.getFullCard().getCard().getDueDate() != null) { + return card.getFullCard().getCard().getDueDate(); + } + return null; + }), Comparator.nullsLast(Comparator.naturalOrder())); + comparator.thenComparing(card -> { + if (card != null && + card.getFullCard() != null && + card.getFullCard().getCard().getDueDate() != null) { + + Card c = card.getFullCard().getCard(); + + if (c.getLastModified() == null && c.getLastModifiedLocal() != null) { + return c.getLastModifiedLocal(); + } else if (c.getLastModified() != null && c.getLastModifiedLocal() == null) { + return c.getLastModified(); + } else { + return c.getLastModifiedLocal().toEpochMilli() > c.getLastModified().toEpochMilli() ? + c.getLastModifiedLocal() : c.getLastModified(); + } + } + return null; + }, Comparator.nullsLast(Comparator.naturalOrder())); + + Collections.sort( + items, + comparator + ); + EUpcomingDueType lastDueType = null; + for (UpcomingCardsAdapterItem filterWidgetCard : items) { + final EUpcomingDueType nextDueType = getDueType(filterWidgetCard.getFullCard().getCard().getDueDate()); + DeckLog.info(filterWidgetCard.getFullCard().getCard().getTitle() + ":", nextDueType.name()); + if (!nextDueType.equals(lastDueType)) { + this.items.add(new UpcomingCardsAdapterSectionItem(nextDueType.toString(activity))); + lastDueType = nextDueType; + } + this.items.add(filterWidgetCard); + } + notifyDataSetChanged(); } + + @NonNull + private static EUpcomingDueType getDueType(@Nullable Instant dueDate) { + if (dueDate == null) { + return EUpcomingDueType.NO_DUE; + } + + long diff = DAYS.between(LocalDate.now(), dueDate.atZone(ZoneId.systemDefault()).toLocalDate()); + + if (diff > 7) { + return EUpcomingDueType.LATER; + } else if (diff > 1) { + return EUpcomingDueType.WEEK; + } else if (diff > 0) { + return EUpcomingDueType.TOMORROW; + } else if (diff == 0) { + return EUpcomingDueType.TODAY; + } else { + return EUpcomingDueType.OVERDUE; + } + } + + private enum EUpcomingDueType { + OVERDUE(1, R.string.filter_overdue), + TODAY(2, R.string.filter_today), + TOMORROW(3, R.string.filter_tomorrow), + WEEK(4, R.string.filter_week), + LATER(5, R.string.filter_later), + NO_DUE(6, R.string.filter_no_due); + + private final int value; + private final int id; + + EUpcomingDueType(int id, @StringRes int value) { + this.value = value; + this.id = id; + } + + public int getId() { + return id; + } + + @NonNull + public String toString(Context context) { + return context.getString(this.value); + } + } } 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 6b589b36e..3e9482a57 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 @@ -7,10 +7,13 @@ import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import java.util.List; +import java.util.stream.Collectors; import it.niedermann.nextcloud.deck.model.widget.filter.FilterWidget; import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; +import static androidx.lifecycle.Transformations.map; + @SuppressWarnings("WeakerAccess") public class UpcomingCardsViewModel extends AndroidViewModel { @@ -22,27 +25,9 @@ public class UpcomingCardsViewModel extends AndroidViewModel { } public LiveData> getUpcomingCards() { - return this.syncManager.getCardsForFilterWidget(new FilterWidget()); -// final MutableLiveData> ret = new MutableLiveData<>(); -// new Thread(() -> { -// List accounts = syncManager.readAccountsDirectly(); -// -// final FilterWidget config = new FilterWidget(); -// config.setWidgetType(EWidgetType.UPCOMING_WIDGET); -// config.setSorts(new FilterWidgetSort(ESortCriteria.DUE_DATE, true)); -// config.setAccounts(accounts.stream().map(account -> { -// final FilterWidgetAccount fwa = new FilterWidgetAccount(account.getId(), false); -// fwa.setUsers(new FilterWidgetUser(syncManager.getUserByUidDirectly(account.getId(), account.getUserName()).getLocalId())); -// return fwa; -// }).collect(Collectors.toList())); -// List filterWidgetCards = this.syncManager.getCardsForFilterWidget(new FilterWidget()); -// ret.postValue(filterWidgetCards.stream().map((filterWidgetCard -> { -// final Board board = syncManager.getBoardById( -// syncManager.getBoardLocalIdByLocalCardIdDirectly(filterWidgetCard.getCard().getLocalId()) -// ); -// return new UpcomingCardsAdapterItem(filterWidgetCard.getCard(), new Account(), board.getId(), board.getLocalId(), board.isPermissionEdit()); -// })).collect(Collectors.toList())); -// }).start(); -// return ret; + // FIXME remove mapping after https://github.com/stefan-niedermann/nextcloud-deck/issues/923 + return map(this.syncManager.getCardsForFilterWidget(new FilterWidget()), (cards) -> + cards.stream().filter(card -> card.getAccount() != null).collect(Collectors.toList()) + ); } } -- cgit v1.2.3