diff options
author | Stefan Niedermann <info@niedermann.it> | 2021-04-09 18:50:25 +0300 |
---|---|---|
committer | Niedermann IT-Dienstleistungen <stefan-niedermann@users.noreply.github.com> | 2021-04-10 14:38:50 +0300 |
commit | 763696b69b78e28ed643609eb8055689d7f58f22 (patch) | |
tree | 78e864aab31870009e7906d5ea293a925244cc06 /app/src/main | |
parent | e58becda69020ab84f01a00171b5e650adea7e75 (diff) |
#690 Upcoming cards
Signed-off-by: Stefan Niedermann <info@niedermann.it>
Diffstat (limited to 'app/src/main')
9 files changed, 260 insertions, 8 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7befbdb2a..0200a4f1c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -98,6 +98,11 @@ android:parentActivityName="it.niedermann.nextcloud.deck.ui.MainActivity" /> <activity + android:name=".ui.upcomingcards.UpcomingCardsActvitiy" + android:label="@string/widget_upcoming_title" + android:parentActivityName="it.niedermann.nextcloud.deck.ui.MainActivity" /> + + <activity android:name=".ui.card.EditActivity" android:label="@string/edit" android:parentActivityName="it.niedermann.nextcloud.deck.ui.MainActivity" /> diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/SyncManager.java b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/SyncManager.java index a8bdae45c..7866fe3f1 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/SyncManager.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/SyncManager.java @@ -66,7 +66,6 @@ import it.niedermann.nextcloud.deck.model.widget.filter.FilterWidget; import it.niedermann.nextcloud.deck.model.widget.filter.dto.FilterWidgetCard; import it.niedermann.nextcloud.deck.persistence.sync.adapters.ServerAdapter; import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DataBaseAdapter; -import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.LiveDataHelper; import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.WrappedLiveData; import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.extrawurst.UserSearchLiveData; import it.niedermann.nextcloud.deck.persistence.sync.helpers.DataPropagationHelper; @@ -84,6 +83,7 @@ import it.niedermann.nextcloud.deck.persistence.sync.helpers.providers.StackData import it.niedermann.nextcloud.deck.persistence.sync.helpers.providers.partial.BoardWithAclDownSyncDataProvider; import it.niedermann.nextcloud.deck.persistence.sync.helpers.providers.partial.BoardWithStacksAndLabelsUpSyncDataProvider; +import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.LiveDataHelper.wrapInLiveData; import static java.net.HttpURLConnection.HTTP_NOT_MODIFIED; import static java.net.HttpURLConnection.HTTP_UNAVAILABLE; @@ -1236,7 +1236,7 @@ public class SyncManager { @SuppressWarnings("JavadocReference") @AnyThread public WrappedLiveData<Void> moveCard(long originAccountId, long originCardLocalId, long targetAccountId, long targetBoardLocalId, long targetStackLocalId) { - return LiveDataHelper.wrapInLiveData(() -> { + return wrapInLiveData(() -> { final FullCard originalCard = dataBaseAdapter.getFullCardByLocalIdDirectly(originAccountId, originCardLocalId); int newIndex = dataBaseAdapter.getHighestCardOrderInStack(targetStackLocalId) + 1; final FullBoard originalBoard = dataBaseAdapter.getFullBoardByLocalCardIdDirectly(originCardLocalId); @@ -1891,6 +1891,13 @@ public class SyncManager { return dataBaseAdapter.getCardsForFilterWidget(filterWidgetId); } + @WorkerThread + public LiveData<List<FilterWidgetCard>> getCardsForFilterWidget(@NonNull FilterWidget filterWidget) { + return wrapInLiveData(() -> { + return dataBaseAdapter.getCardsForFilterWidget(filterWidget); + }); + } + // # single card widget /** diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DataBaseAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DataBaseAdapter.java index 4070d9ddb..ca2b90ec2 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DataBaseAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DataBaseAdapter.java @@ -1256,7 +1256,7 @@ public class DataBaseAdapter { return getCardsForFilterWidget(getFilterWidgetByIdDirectly(filterWidgetId)); } - public List<FilterWidgetCard> getCardsForFilterWidget(FilterWidget filterWidget) { + public List<FilterWidgetCard> getCardsForFilterWidget(@NonNull FilterWidget filterWidget) { FilterInformation filter = new FilterInformation(); Set<FullCard> cardsResult = new HashSet<>(); if (filterWidget.getDueType() != null) { diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java index 1a1db058f..4d3bc7eab 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java @@ -101,6 +101,7 @@ import it.niedermann.nextcloud.deck.ui.stack.EditStackListener; import it.niedermann.nextcloud.deck.ui.stack.OnScrollListener; import it.niedermann.nextcloud.deck.ui.stack.StackAdapter; import it.niedermann.nextcloud.deck.ui.stack.StackFragment; +import it.niedermann.nextcloud.deck.ui.upcomingcards.UpcomingCardsActvitiy; import it.niedermann.nextcloud.deck.util.CustomAppGlideModule; import it.niedermann.nextcloud.deck.util.DrawerMenuUtil; @@ -126,6 +127,7 @@ import static it.niedermann.nextcloud.deck.util.DrawerMenuUtil.MENU_ID_ABOUT; import static it.niedermann.nextcloud.deck.util.DrawerMenuUtil.MENU_ID_ADD_BOARD; import static it.niedermann.nextcloud.deck.util.DrawerMenuUtil.MENU_ID_ARCHIVED_BOARDS; import static it.niedermann.nextcloud.deck.util.DrawerMenuUtil.MENU_ID_SETTINGS; +import static it.niedermann.nextcloud.deck.util.DrawerMenuUtil.MENU_ID_UPCOMING_CARDS; public class MainActivity extends AppCompatActivity implements DeleteStackListener, EditStackListener, DeleteBoardListener, EditBoardListener, ArchiveBoardListener, OnScrollListener, OnNavigationItemSelectedListener { @@ -697,6 +699,9 @@ public class MainActivity extends AppCompatActivity implements DeleteStackListen case MENU_ID_ARCHIVED_BOARDS: startActivity(ArchivedBoardsActvitiy.createIntent(MainActivity.this, mainViewModel.getCurrentAccount())); break; + case MENU_ID_UPCOMING_CARDS: + startActivity(UpcomingCardsActvitiy.createIntent(MainActivity.this)); + break; default: setCurrentBoard(boardsList.get(item.getItemId())); break; 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 new file mode 100644 index 000000000..67c435073 --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsAdapter.java @@ -0,0 +1,102 @@ +package it.niedermann.nextcloud.deck.ui.upcomingcards; + +import android.app.Activity; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.FragmentManager; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; +import java.util.List; + +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.model.full.FullCard; +import it.niedermann.nextcloud.deck.ui.card.AbstractCardViewHolder; +import it.niedermann.nextcloud.deck.ui.card.CompactCardViewHolder; +import it.niedermann.nextcloud.deck.ui.card.DefaultCardOnlyTitleViewHolder; +import it.niedermann.nextcloud.deck.ui.card.DefaultCardViewHolder; +import it.niedermann.nextcloud.deck.ui.card.EditActivity; + +import static androidx.preference.PreferenceManager.getDefaultSharedPreferences; + +public class UpcomingCardsAdapter extends RecyclerView.Adapter<AbstractCardViewHolder> { + + private final boolean compactMode; + @NonNull + protected final FragmentManager fragmentManager; + @NonNull + protected final Activity activity; + @NonNull + protected List<UpcomingCardsAdapterItem> cardList = new ArrayList<>(); + @NonNull + protected String counterMaxValue; + @ColorInt + protected int mainColor; + + public UpcomingCardsAdapter(@NonNull Activity activity, @NonNull FragmentManager fragmentManager) { + 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); + setHasStableIds(true); + } + + @Override + public long getItemId(int position) { + return cardList.get(position).getFullCard().getLocalId(); + } + + @NonNull + @Override + public AbstractCardViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) { + if (viewType == R.layout.item_card_compact) { + return new CompactCardViewHolder(ItemCardCompactBinding.inflate(LayoutInflater.from(viewGroup.getContext()), viewGroup, false)); + } else if (viewType == R.layout.item_card_default_only_title) { + return new DefaultCardOnlyTitleViewHolder(ItemCardDefaultOnlyTitleBinding.inflate(LayoutInflater.from(viewGroup.getContext()), viewGroup, false)); + } + return new DefaultCardViewHolder(ItemCardDefaultBinding.inflate(LayoutInflater.from(viewGroup.getContext()), viewGroup, false)); + } + + @Override + public int getItemViewType(int position) { + if (compactMode) { + return R.layout.item_card_compact; + } else { + final FullCard fullCard = cardList.get(position).getFullCard(); + if (fullCard.getAttachments().size() == 0 + && fullCard.getAssignedUsers().size() == 0 + && fullCard.getLabels().size() == 0 + && fullCard.getCommentCount() == 0 + && fullCard.getCard().getTaskStatus().taskCount == 0) { + return R.layout.item_card_default_only_title; + } + return R.layout.item_card_default; + } + } + + @Override + public void onBindViewHolder(@NonNull AbstractCardViewHolder viewHolder, int position) { + UpcomingCardsAdapterItem item = cardList.get(position); + viewHolder.bind(item.getFullCard(), item.getAccount(), item.getCurrentBoardRemoteId(), false, R.menu.card_menu, (a, b) -> true, counterMaxValue, mainColor); + viewHolder.bindCardClickListener((v) -> activity.startActivity(EditActivity.createEditCardIntent(activity, item.getAccount(), item.getCurrentBoardLocalId(), item.getFullCard().getLocalId()))); + } + + @Override + public int getItemCount() { + return cardList.size(); + } + + public void setCardList(@NonNull List<UpcomingCardsAdapterItem> cardList) { + this.cardList.clear(); + this.cardList.addAll(cardList); + notifyDataSetChanged(); + } +} diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsAdapterItem.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsAdapterItem.java new file mode 100644 index 000000000..2bffb752b --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsAdapterItem.java @@ -0,0 +1,40 @@ +package it.niedermann.nextcloud.deck.ui.upcomingcards; + +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.full.FullCard; + +public class UpcomingCardsAdapterItem { + private final FullCard fullCard; + private final Account account; + private final long currentBoardLocalId; + private final Long currentBoardRemoteId; + private final boolean currentBoardHasEditPermission; + + public UpcomingCardsAdapterItem(FullCard fullCard, Account account, long currentBoardLocalId, Long currentBoardRemoteId, boolean currentBoardHasEditPermission) { + this.fullCard = fullCard; + this.account = account; + this.currentBoardLocalId = currentBoardLocalId; + this.currentBoardRemoteId = currentBoardRemoteId; + this.currentBoardHasEditPermission = currentBoardHasEditPermission; + } + + public FullCard getFullCard() { + return fullCard; + } + + public Account getAccount() { + return account; + } + + public Long getCurrentBoardLocalId() { + return currentBoardLocalId; + } + + public Long getCurrentBoardRemoteId() { + return currentBoardRemoteId; + } + + public boolean currentBoardHasEditPermission() { + return currentBoardHasEditPermission; + } +}
\ 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 new file mode 100644 index 000000000..f6d43043d --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsViewModel.java @@ -0,0 +1,54 @@ +package it.niedermann.nextcloud.deck.ui.upcomingcards; + +import android.app.Application; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; + +import java.util.List; +import java.util.stream.Collectors; + +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.Board; +import it.niedermann.nextcloud.deck.model.enums.ESortCriteria; +import it.niedermann.nextcloud.deck.model.widget.filter.EWidgetType; +import it.niedermann.nextcloud.deck.model.widget.filter.FilterWidget; +import it.niedermann.nextcloud.deck.model.widget.filter.FilterWidgetAccount; +import it.niedermann.nextcloud.deck.model.widget.filter.FilterWidgetSort; +import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; + +import static androidx.lifecycle.Transformations.map; +import static androidx.lifecycle.Transformations.switchMap; + +@SuppressWarnings("WeakerAccess") +public class UpcomingCardsViewModel extends AndroidViewModel { + + private final SyncManager syncManager; + + public UpcomingCardsViewModel(@NonNull Application application) { + super(application); + this.syncManager = new SyncManager(application); + } + + public LiveData<List<UpcomingCardsAdapterItem>> getUpcomingCards() { + return switchMap(syncManager.readAccounts(), (accounts) -> { + 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); + // TODO syncManager.getUserByUidDirectly(account.getId(), account.getUserName()).getLocalId()) +// fwa.setUsers(new FilterWidgetUser(new User(1L, "stefan")); + return fwa; + }).collect(Collectors.toList())); + return map(this.syncManager.getCardsForFilterWidget(new FilterWidget()), + (filterWidgetCards) -> { + return filterWidgetCards.stream().map((filterWidgetCard -> { + final Board board = filterWidgetCard.getBoard(); + return new UpcomingCardsAdapterItem(filterWidgetCard.getCard(), new Account(), board.getId(), board.getLocalId(), board.isPermissionEdit()); + })).collect(Collectors.toList()); + }); + }); + } +} diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/util/DrawerMenuUtil.java b/app/src/main/java/it/niedermann/nextcloud/deck/util/DrawerMenuUtil.java index 312dc7cf9..d315c1867 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/util/DrawerMenuUtil.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/util/DrawerMenuUtil.java @@ -2,7 +2,6 @@ package it.niedermann.nextcloud.deck.util; import android.view.Menu; import android.view.MenuItem; -import android.view.SubMenu; import androidx.annotation.NonNull; import androidx.appcompat.widget.AppCompatImageButton; @@ -25,6 +24,7 @@ public class DrawerMenuUtil { public static final int MENU_ID_ADD_BOARD = -2; public static final int MENU_ID_SETTINGS = -3; public static final int MENU_ID_ARCHIVED_BOARDS = -4; + public static final int MENU_ID_UPCOMING_CARDS = -5; private DrawerMenuUtil() { throw new UnsupportedOperationException("This class must not get instantiated"); @@ -36,10 +36,10 @@ public class DrawerMenuUtil { @NonNull List<Board> boards, boolean hasArchivedBoards, boolean currentServerVersionIsSupported) { - final SubMenu boardsMenu = menu.addSubMenu(R.string.simple_boards); + menu.add(Menu.NONE, MENU_ID_UPCOMING_CARDS, Menu.NONE, R.string.widget_upcoming_title).setIcon(R.drawable.calendar_blank_grey600_24dp); int index = 0; for (Board board : boards) { - final MenuItem m = boardsMenu + final MenuItem m = menu .add(Menu.NONE, index++, Menu.NONE, board.getTitle()).setIcon(ViewUtil.getTintedImageView(context, R.drawable.circle_grey600_36dp, board.getColor())) .setCheckable(true); if (currentServerVersionIsSupported) { @@ -92,11 +92,11 @@ public class DrawerMenuUtil { } if (hasArchivedBoards) { - boardsMenu.add(Menu.NONE, MENU_ID_ARCHIVED_BOARDS, Menu.NONE, R.string.archived_boards).setIcon(ViewUtil.getTintedImageView(context, R.drawable.ic_archive_white_24dp, ContextCompat.getColor(context, R.color.grey600))); + menu.add(Menu.NONE, MENU_ID_ARCHIVED_BOARDS, Menu.NONE, R.string.archived_boards).setIcon(ViewUtil.getTintedImageView(context, R.drawable.ic_archive_white_24dp, ContextCompat.getColor(context, R.color.grey600))); } if (currentServerVersionIsSupported) { - boardsMenu.add(Menu.NONE, MENU_ID_ADD_BOARD, Menu.NONE, R.string.add_board).setIcon(R.drawable.ic_add_grey_24dp); + menu.add(Menu.NONE, MENU_ID_ADD_BOARD, Menu.NONE, R.string.add_board).setIcon(R.drawable.ic_add_grey_24dp); } menu.add(Menu.NONE, MENU_ID_SETTINGS, Menu.NONE, R.string.simple_settings).setIcon(R.drawable.ic_settings_grey600_24dp); diff --git a/app/src/main/res/layout/activity_upcoming_cards.xml b/app/src/main/res/layout/activity_upcoming_cards.xml new file mode 100644 index 000000000..21b949435 --- /dev/null +++ b/app/src/main/res/layout/activity_upcoming_cards.xml @@ -0,0 +1,39 @@ +<?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="wrap_content" + android:orientation="vertical"> + + <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="?android:actionBarSize" + app:navigationIcon="@drawable/ic_arrow_back_white_24dp" + tools:title="@string/widget_upcoming_title" /> + </com.google.android.material.appbar.AppBarLayout> + + <it.niedermann.nextcloud.deck.ui.view.EmptyContentView + android:id="@+id/empty_content_view" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:visibility="gone" + app:title="@string/no_cards" /> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/recycler_view" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:clipToPadding="false" + android:paddingTop="@dimen/spacer_1x" + android:paddingBottom="@dimen/spacer_1x" + android:scrollbarStyle="outsideOverlay" + android:scrollbars="vertical" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" + tools:listitem="@layout/item_card_default" /> +</LinearLayout>
\ No newline at end of file |