diff options
10 files changed, 127 insertions, 58 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/model/internal/FilterInformation.java b/app/src/main/java/it/niedermann/nextcloud/deck/model/internal/FilterInformation.java index a81628bf0..f3892dfa5 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/model/internal/FilterInformation.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/model/internal/FilterInformation.java @@ -1,6 +1,7 @@ package it.niedermann.nextcloud.deck.model.internal; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import org.jetbrains.annotations.NotNull; @@ -21,15 +22,14 @@ public class FilterInformation implements Serializable { private List<Label> labels = new ArrayList<>(); public FilterInformation() { + // Default constructor } - public FilterInformation(FilterInformation filterInformation) { - this.dueType = filterInformation.getDueType(); - for (User user : users) { - this.users.add(user); - } - for (Label label : labels) { - this.labels.add(label); + public FilterInformation(@Nullable FilterInformation filterInformation) { + if (filterInformation != null) { + this.dueType = filterInformation.getDueType(); + this.users.addAll(filterInformation.getUsers()); + this.labels.addAll(filterInformation.getLabels()); } } @@ -52,20 +52,20 @@ public class FilterInformation implements Serializable { return labels; } - public void addAllLabels(@NonNull List<Label> labels) { - this.labels.addAll(labels); + public void addLabel(@NonNull Label label) { + this.labels.add(label); } - public void addAllUsers(@NonNull List<User> users) { - this.users.addAll(users); + public void addUser(@NonNull User user) { + this.users.add(user); } - public void clearLabels() { - labels.clear(); + public void removeLabel(@NonNull Label label) { + labels.remove(label); } - public void clearUsers() { - users.clear(); + public void removeUser(@NonNull User user) { + users.remove(user); } @NotNull @@ -77,4 +77,14 @@ public class FilterInformation implements Serializable { ", labels=" + labels + '}'; } + + /** + * @return whether or not the given filterInformation has any actual filters set + */ + public static boolean hasActiveFilter(@Nullable FilterInformation filterInformation) { + if (filterInformation == null) { + return false; + } + return filterInformation.getDueType() != EDueType.NO_FILTER || filterInformation.getUsers().size() > 0 || filterInformation.getLabels().size() > 0; + } } 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 2a0016f82..cec0e3cef 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 @@ -66,7 +66,6 @@ import it.niedermann.nextcloud.deck.model.Stack; import it.niedermann.nextcloud.deck.model.full.FullBoard; import it.niedermann.nextcloud.deck.model.full.FullCard; import it.niedermann.nextcloud.deck.model.full.FullStack; -import it.niedermann.nextcloud.deck.model.internal.FilterInformation; import it.niedermann.nextcloud.deck.model.ocs.Capabilities; import it.niedermann.nextcloud.deck.model.ocs.Version; import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; @@ -511,7 +510,7 @@ public class MainActivity extends BrandedActivity implements DeleteStackListener protected void setCurrentBoard(@NonNull Board board) { viewModel.setCurrentBoard(board); - viewModel.postFilterInformation(null); + viewModel.clearFilterInformation(); lastBoardId = board.getLocalId(); Application.saveCurrentBoardId(this, viewModel.getCurrentAccount().getId(), viewModel.getCurrentBoardLocalId()); @@ -666,8 +665,7 @@ public class MainActivity extends BrandedActivity implements DeleteStackListener } inflater.inflate(R.menu.main_menu, menu); menu.findItem(R.id.archived_cards).setVisible(false); - final FilterInformation filterInformation = viewModel.getFilterInformation().getValue(); - menu.findItem(R.id.filter).setIcon(filterInformation == null + menu.findItem(R.id.filter).setIcon(viewModel.getFilterInformation().getValue() == null ? R.drawable.ic_filter_list_white_24dp : R.drawable.ic_filter_list_active_white_24dp); return super.onCreateOptionsMenu(menu); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainViewModel.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainViewModel.java index b3e6d7090..dcbecf0bd 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainViewModel.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainViewModel.java @@ -1,7 +1,6 @@ package it.niedermann.nextcloud.deck.ui; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; @@ -10,16 +9,34 @@ import it.niedermann.nextcloud.deck.model.Account; import it.niedermann.nextcloud.deck.model.Board; import it.niedermann.nextcloud.deck.model.internal.FilterInformation; +import static it.niedermann.nextcloud.deck.model.internal.FilterInformation.hasActiveFilter; + @SuppressWarnings("WeakerAccess") public class MainViewModel extends ViewModel { @NonNull + private FilterInformation filterInformationDraft = new FilterInformation(); + @NonNull private MutableLiveData<FilterInformation> filterInformation = new MutableLiveData<>(); private Account currentAccount; private Board currentBoard; - public void postFilterInformation(@Nullable FilterInformation filterInformation) { - this.filterInformation.postValue(filterInformation); + public void publishFilterInformationDraft() { + this.filterInformation.postValue(hasActiveFilter(filterInformationDraft) ? filterInformationDraft : null); + } + + public void clearFilterInformation() { + this.filterInformationDraft = new FilterInformation(); + this.publishFilterInformationDraft(); + } + + @NonNull + public FilterInformation getFilterInformationDraft() { + return this.filterInformationDraft; + } + + public void createFilterInformationDraft() { + this.filterInformationDraft = new FilterInformation(this.filterInformation.getValue()); } @NonNull diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/FilterAssigneesFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/FilterAssigneesFragment.java index 4ef9f1c76..1d29ff034 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/FilterAssigneesFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/FilterAssigneesFragment.java @@ -12,6 +12,7 @@ import androidx.lifecycle.ViewModelProvider; import it.niedermann.nextcloud.deck.R; import it.niedermann.nextcloud.deck.databinding.DialogFilterAssigneesBinding; +import it.niedermann.nextcloud.deck.model.User; import it.niedermann.nextcloud.deck.model.internal.FilterInformation; import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; import it.niedermann.nextcloud.deck.ui.MainViewModel; @@ -19,9 +20,9 @@ import it.niedermann.nextcloud.deck.ui.MainViewModel; import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.LiveDataHelper.observeOnce; import static it.niedermann.nextcloud.deck.util.DimensionUtil.dpToPx; -public class FilterAssigneesFragment extends Fragment { +public class FilterAssigneesFragment extends Fragment implements SelectionListener<User> { - private FilterInformation filterInformation; + private FilterInformation filterInformationDraft; private DialogFilterAssigneesBinding binding; private MainViewModel mainViewModel; private UserFilterAdapter userAdapter; @@ -34,16 +35,23 @@ public class FilterAssigneesFragment extends Fragment { mainViewModel = new ViewModelProvider(requireActivity()).get(MainViewModel.class); final SyncManager syncManager = new SyncManager(requireActivity()); - this.filterInformation = mainViewModel.getFilterInformation().getValue(); - if (this.filterInformation == null) { - this.filterInformation = new FilterInformation(); - } + this.filterInformationDraft = mainViewModel.getFilterInformationDraft(); observeOnce(syncManager.findProposalsForUsersToAssign(mainViewModel.getCurrentAccount().getId(), mainViewModel.getCurrentBoardLocalId()), requireActivity(), (users) -> { - userAdapter = new UserFilterAdapter(dpToPx(requireContext(), R.dimen.avatar_size), mainViewModel.getCurrentAccount(), users, this.filterInformation.getUsers()); + userAdapter = new UserFilterAdapter(dpToPx(requireContext(), R.dimen.avatar_size), mainViewModel.getCurrentAccount(), users, this.filterInformationDraft.getUsers(), this); binding.users.setNestedScrollingEnabled(false); binding.users.setAdapter(userAdapter); }); return binding.getRoot(); } + + @Override + public void onItemSelected(User item) { + filterInformationDraft.addUser(item); + } + + @Override + public void onItemDeselected(User item) { + filterInformationDraft.removeUser(item); + } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/FilterDialogFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/FilterDialogFragment.java index 113449c93..326f914a1 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/FilterDialogFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/FilterDialogFragment.java @@ -46,12 +46,14 @@ public class FilterDialogFragment extends BrandedDialogFragment { binding.viewPager.setOffscreenPageLimit(tabTitles.length); new TabLayoutMediator(binding.tabLayout, binding.viewPager, (tab, position) -> tab.setText(tabTitles[position])).attach(); + mainViewModel.createFilterInformationDraft(); + return dialogBuilder .setTitle(R.string.simple_filter) .setView(binding.getRoot()) .setNeutralButton(android.R.string.cancel, null) - .setNegativeButton(R.string.simple_clear, (a, b) -> mainViewModel.postFilterInformation(null)) - .setPositiveButton(R.string.simple_filter, null) + .setNegativeButton(R.string.simple_clear, (a, b) -> mainViewModel.clearFilterInformation()) + .setPositiveButton(R.string.simple_filter, (a, b) -> mainViewModel.publishFilterInformationDraft()) .create(); } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/FilterDuedateFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/FilterDuedateFragment.java index 50ee3f41c..ac9514773 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/FilterDuedateFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/FilterDuedateFragment.java @@ -16,9 +16,9 @@ import it.niedermann.nextcloud.deck.model.enums.EDueType; import it.niedermann.nextcloud.deck.model.internal.FilterInformation; import it.niedermann.nextcloud.deck.ui.MainViewModel; -public class FilterDuedateFragment extends Fragment { +public class FilterDuedateFragment extends Fragment implements AdapterView.OnItemSelectedListener { - private FilterInformation filterInformation; + private FilterInformation filterInformationDraft; private DialogFilterDuedateBinding binding; private MainViewModel mainViewModel; private OverdueFilterAdapter overdueAdapter; @@ -30,22 +30,19 @@ public class FilterDuedateFragment extends Fragment { mainViewModel = new ViewModelProvider(requireActivity()).get(MainViewModel.class); overdueAdapter = new OverdueFilterAdapter(requireContext()); binding.overdue.setAdapter(overdueAdapter); - this.filterInformation = mainViewModel.getFilterInformation().getValue(); - if (this.filterInformation == null) { - this.filterInformation = new FilterInformation(); - } - binding.overdue.setSelection(overdueAdapter.getPosition(this.filterInformation.getDueType())); - binding.overdue.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { - filterInformation.setDueType(overdueAdapter.getItem(position)); - } - - @Override - public void onNothingSelected(AdapterView<?> parent) { - filterInformation.setDueType(EDueType.NO_FILTER); - } - }); + this.filterInformationDraft = mainViewModel.getFilterInformationDraft(); + binding.overdue.setSelection(overdueAdapter.getPosition(this.filterInformationDraft.getDueType())); + binding.overdue.setOnItemSelectedListener(this); return binding.getRoot(); } + + @Override + public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { + filterInformationDraft.setDueType(overdueAdapter.getItem(position)); + } + + @Override + public void onNothingSelected(AdapterView<?> parent) { + filterInformationDraft.setDueType(EDueType.NO_FILTER); + } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/FilterLabelsFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/FilterLabelsFragment.java index 59d0006ac..cf20f0d06 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/FilterLabelsFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/FilterLabelsFragment.java @@ -11,15 +11,16 @@ import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import it.niedermann.nextcloud.deck.databinding.DialogFilterLabelsBinding; +import it.niedermann.nextcloud.deck.model.Label; import it.niedermann.nextcloud.deck.model.internal.FilterInformation; import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; import it.niedermann.nextcloud.deck.ui.MainViewModel; import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.LiveDataHelper.observeOnce; -public class FilterLabelsFragment extends Fragment { +public class FilterLabelsFragment extends Fragment implements SelectionListener<Label> { - private FilterInformation filterInformation; + private FilterInformation filterInformationDraft; private DialogFilterLabelsBinding binding; private MainViewModel mainViewModel; private LabelFilterAdapter labelAdapter; @@ -31,15 +32,22 @@ public class FilterLabelsFragment extends Fragment { mainViewModel = new ViewModelProvider(requireActivity()).get(MainViewModel.class); final SyncManager syncManager = new SyncManager(requireActivity()); - this.filterInformation = mainViewModel.getFilterInformation().getValue(); - if (this.filterInformation == null) { - this.filterInformation = new FilterInformation(); - } + this.filterInformationDraft = mainViewModel.getFilterInformationDraft(); observeOnce(syncManager.findProposalsForLabelsToAssign(mainViewModel.getCurrentAccount().getId(), mainViewModel.getCurrentBoardLocalId()), requireActivity(), (labels) -> { - labelAdapter = new LabelFilterAdapter(labels, this.filterInformation.getLabels()); + labelAdapter = new LabelFilterAdapter(labels, this.filterInformationDraft.getLabels(), this); binding.labels.setNestedScrollingEnabled(false); binding.labels.setAdapter(labelAdapter); }); return binding.getRoot(); } + + @Override + public void onItemSelected(Label item) { + filterInformationDraft.addLabel(item); + } + + @Override + public void onItemDeselected(Label item) { + filterInformationDraft.removeLabel(item); + } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/LabelFilterAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/LabelFilterAdapter.java index 1eee5c8bb..e5c84b019 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/LabelFilterAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/LabelFilterAdapter.java @@ -6,6 +6,7 @@ import android.view.LayoutInflater; import android.view.ViewGroup; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; @@ -21,11 +22,14 @@ public class LabelFilterAdapter extends RecyclerView.Adapter<LabelFilterAdapter. private final List<Label> labels = new ArrayList<>(); @NonNull private final List<Label> selectedLabels = new ArrayList<>(); + @Nullable + private final SelectionListener<Label> selectionListener; - public LabelFilterAdapter(@NonNull List<Label> labels, @NonNull List<Label> selectedLabels) { + public LabelFilterAdapter(@NonNull List<Label> labels, @NonNull List<Label> selectedLabels, @Nullable SelectionListener<Label> selectionListener) { super(); this.labels.addAll(labels); this.selectedLabels.addAll(selectedLabels); + this.selectionListener = selectionListener; setHasStableIds(true); notifyDataSetChanged(); } @@ -75,9 +79,15 @@ public class LabelFilterAdapter extends RecyclerView.Adapter<LabelFilterAdapter. if (selectedLabels.contains(label)) { selectedLabels.remove(label); itemView.setSelected(false); + if (selectionListener != null) { + selectionListener.onItemDeselected(label); + } } else { selectedLabels.add(label); itemView.setSelected(true); + if (selectionListener != null) { + selectionListener.onItemSelected(label); + } } }); } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/SelectionListener.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/SelectionListener.java new file mode 100644 index 000000000..84e635743 --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/SelectionListener.java @@ -0,0 +1,9 @@ +package it.niedermann.nextcloud.deck.ui.filter; + +import it.niedermann.nextcloud.deck.model.interfaces.IRemoteEntity; + +public interface SelectionListener<T extends IRemoteEntity> { + void onItemSelected(T item); + + void onItemDeselected(T item); +} diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/UserFilterAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/UserFilterAdapter.java index 89697e209..4744f42ce 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/UserFilterAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/filter/UserFilterAdapter.java @@ -4,6 +4,7 @@ import android.view.LayoutInflater; import android.view.ViewGroup; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.Px; import androidx.recyclerview.widget.RecyclerView; @@ -26,13 +27,16 @@ public class UserFilterAdapter extends RecyclerView.Adapter<UserFilterAdapter.Us private final List<User> users = new ArrayList<>(); @NonNull private final List<User> selectedUsers = new ArrayList<>(); + @Nullable + private final SelectionListener<User> selectionListener; - public UserFilterAdapter(@Px int avatarSize, @NonNull Account account, @NonNull List<User> users, @NonNull List<User> selectedUsers) { + public UserFilterAdapter(@Px int avatarSize, @NonNull Account account, @NonNull List<User> users, @NonNull List<User> selectedUsers, @Nullable SelectionListener selectionListener) { super(); this.avatarSize = avatarSize; this.account = account; this.users.addAll(users); this.selectedUsers.addAll(selectedUsers); + this.selectionListener = selectionListener; setHasStableIds(true); notifyDataSetChanged(); } @@ -79,9 +83,15 @@ public class UserFilterAdapter extends RecyclerView.Adapter<UserFilterAdapter.Us if (selectedUsers.contains(user)) { selectedUsers.remove(user); itemView.setSelected(false); + if(selectionListener != null) { + selectionListener.onItemDeselected(user); + } } else { selectedUsers.add(user); itemView.setSelected(true); + if(selectionListener != null) { + selectionListener.onItemSelected(user); + } } }); } |