diff options
author | Stefan Niedermann <info@niedermann.it> | 2020-10-03 21:24:48 +0300 |
---|---|---|
committer | Stefan Niedermann <info@niedermann.it> | 2020-10-03 22:32:20 +0300 |
commit | 1aa4d0207658b79434489b3af1172fa697ed4780 (patch) | |
tree | b8ea50a81b2d0be3ec8937da98f86ca29954c0d3 /app/src/main/java/it/niedermann/nextcloud/deck/ui/card | |
parent | 31276c8aab356b573c8cca25b701b67ffdbfd052 (diff) |
#679 show more than 7 assigned users
Signed-off-by: Stefan Niedermann <info@niedermann.it>
Diffstat (limited to 'app/src/main/java/it/niedermann/nextcloud/deck/ui/card')
4 files changed, 165 insertions, 32 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeAdapter.java new file mode 100644 index 000000000..aa8c3e8f6 --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeAdapter.java @@ -0,0 +1,80 @@ +package it.niedermann.nextcloud.deck.ui.card.details; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.core.util.Consumer; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; +import java.util.List; + +import it.niedermann.nextcloud.deck.databinding.ItemAssigneeBinding; +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.User; + +import static androidx.recyclerview.widget.RecyclerView.NO_ID; + +@SuppressWarnings("WeakerAccess") +public class AssigneeAdapter extends RecyclerView.Adapter<AssigneeViewHolder> { + + private final Account account; + @NonNull + private List<User> users = new ArrayList<>(); + @NonNull + private final Consumer<User> userClickedListener; + + AssigneeAdapter( + @NonNull Consumer<User> userClickedListener, + @NonNull Account account + ) { + super(); + this.userClickedListener = userClickedListener; + this.account = account; + setHasStableIds(true); + } + + @Override + public long getItemId(int position) { + Long id = users.get(position).getLocalId(); + return id == null ? NO_ID : id; + } + + @NonNull + @Override + public AssigneeViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + final Context context = parent.getContext(); + return new AssigneeViewHolder(ItemAssigneeBinding.inflate(LayoutInflater.from(context))); + } + + @Override + public void onBindViewHolder(@NonNull AssigneeViewHolder holder, int position) { + final User user = users.get(position); + holder.bind(account, user, userClickedListener); + } + + @Override + public int getItemCount() { + return users.size(); + } + + public void setUsers(@NonNull List<User> users) { + this.users.clear(); + this.users.addAll(users); + notifyDataSetChanged(); + } + + public void addUser(@NonNull User user) { + this.users.add(user); + notifyItemInserted(this.users.size()); + } + + public void removeUser(@NonNull User user) { + final int index = this.users.indexOf(user); + this.users.remove(user); + notifyItemRemoved(index); + } + +} diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeDecoration.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeDecoration.java new file mode 100644 index 000000000..096dcfa53 --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeDecoration.java @@ -0,0 +1,28 @@ +package it.niedermann.nextcloud.deck.ui.card.details; + +import android.graphics.Rect; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Px; +import androidx.recyclerview.widget.RecyclerView; + +public class AssigneeDecoration extends RecyclerView.ItemDecoration { + + private final int gutter; + + public AssigneeDecoration(@Px int gutter) { + this.gutter = gutter; + } + + @Override + public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { + final int position = parent.getChildAdapterPosition(view); + + if (position >= 0) { + // All columns get some spacing at the bottom and at the right side + outRect.right = gutter; + outRect.bottom = gutter; + } + } +} diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeViewHolder.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeViewHolder.java new file mode 100644 index 000000000..5d51077fd --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeViewHolder.java @@ -0,0 +1,29 @@ +package it.niedermann.nextcloud.deck.ui.card.details; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.util.Consumer; +import androidx.recyclerview.widget.RecyclerView; + +import it.niedermann.nextcloud.deck.R; +import it.niedermann.nextcloud.deck.databinding.ItemAssigneeBinding; +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.User; +import it.niedermann.nextcloud.deck.util.ViewUtil; + +public class AssigneeViewHolder extends RecyclerView.ViewHolder { + private ItemAssigneeBinding binding; + + @SuppressWarnings("WeakerAccess") + public AssigneeViewHolder(ItemAssigneeBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + + public void bind(@NonNull Account account, @NonNull User user, @Nullable Consumer<User> onClickListener) { + ViewUtil.addAvatar(binding.avatar, account.getUrl(), user.getUid(), R.drawable.ic_image_grey600_24dp); + if(onClickListener != null) { + itemView.setOnClickListener((v) -> onClickListener.accept(user)); + } + } +}
\ No newline at end of file diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDetailsFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDetailsFragment.java index 75f5700b6..63627ac8b 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDetailsFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDetailsFragment.java @@ -10,7 +10,6 @@ import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; import android.widget.LinearLayout; import androidx.annotation.NonNull; @@ -21,6 +20,7 @@ import androidx.core.graphics.ColorUtils; import androidx.core.graphics.drawable.DrawableCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.GridLayoutManager; import com.google.android.material.chip.Chip; import com.google.android.material.snackbar.Snackbar; @@ -54,7 +54,6 @@ import it.niedermann.nextcloud.deck.ui.card.UserAutoCompleteAdapter; import it.niedermann.nextcloud.deck.ui.exception.ExceptionDialogFragment; import it.niedermann.nextcloud.deck.util.ColorUtil; import it.niedermann.nextcloud.deck.util.MarkDownUtil; -import it.niedermann.nextcloud.deck.util.ViewUtil; import static android.text.format.DateFormat.getDateFormat; import static android.view.View.GONE; @@ -68,6 +67,7 @@ public class CardDetailsFragment extends BrandedFragment implements OnDateSetLis private FragmentCardEditTabDetailsBinding binding; private EditCardViewModel viewModel; private SyncManager syncManager; + private AssigneeAdapter adapter; private DateFormat dateFormat; private DateFormat dueTime = new SimpleDateFormat("HH:mm", Locale.ROOT); @Px @@ -111,7 +111,7 @@ public class CardDetailsFragment extends BrandedFragment implements OnDateSetLis avatarLayoutParams = new LinearLayout.LayoutParams(avatarSize, avatarSize); avatarLayoutParams.setMargins(0, 0, dpToPx(requireContext(), R.dimen.spacer_1x), 0); - setupPeople(); + setupAssignees(); setupLabels(); setupDueDate(); setupDescription(); @@ -332,7 +332,29 @@ public class CardDetailsFragment extends BrandedFragment implements OnDateSetLis return chip; } - private void setupPeople() { + private void setupAssignees() { + adapter = new AssigneeAdapter((user) -> { + if (viewModel.canEdit()) { + viewModel.getFullCard().getAssignedUsers().remove(user); + adapter.removeUser(user); + ((UserAutoCompleteAdapter) binding.people.getAdapter()).include(user); + BrandedSnackbar.make( + requireView(), getString(R.string.unassigned_user, user.getDisplayname()), + Snackbar.LENGTH_LONG) + .setAction(R.string.simple_undo, v1 -> { + viewModel.getFullCard().getAssignedUsers().add(user); + ((UserAutoCompleteAdapter) binding.people.getAdapter()).exclude(user); + adapter.addUser(user); + }).show(); + } + }, viewModel.getAccount()); + binding.assignees.setAdapter(adapter); + binding.assignees.post(() -> { + @Px final int gutter = dpToPx(requireContext(), R.dimen.spacer_1x); + final int spanCount = (int) (float) binding.assignees.getWidth() / (dpToPx(requireContext(), R.dimen.avatar_size) + gutter); + binding.assignees.setLayoutManager(new GridLayoutManager(getContext(), spanCount)); + binding.assignees.addItemDecoration(new AssigneeDecoration(gutter)); + }); if (viewModel.canEdit()) { Long localCardId = viewModel.getFullCard().getCard().getLocalId(); localCardId = localCardId == null ? -1 : localCardId; @@ -341,44 +363,18 @@ public class CardDetailsFragment extends BrandedFragment implements OnDateSetLis User user = (User) adapterView.getItemAtPosition(position); viewModel.getFullCard().getAssignedUsers().add(user); ((UserAutoCompleteAdapter) binding.people.getAdapter()).exclude(user); - addAvatar(viewModel.getAccount().getUrl(), user); + adapter.addUser(user); binding.people.setText(""); }); if (this.viewModel.getFullCard().getAssignedUsers() != null) { - binding.peopleList.removeAllViews(); - for (User user : this.viewModel.getFullCard().getAssignedUsers()) { - addAvatar(viewModel.getAccount().getUrl(), user); - } + adapter.setUsers(this.viewModel.getFullCard().getAssignedUsers()); } } else { binding.people.setEnabled(false); } } - private void addAvatar(String baseUrl, User user) { - ImageView avatar = new ImageView(activity); - avatar.setLayoutParams(avatarLayoutParams); - if (viewModel.canEdit()) { - avatar.setOnClickListener(v -> { - viewModel.getFullCard().getAssignedUsers().remove(user); - binding.peopleList.removeView(avatar); - ((UserAutoCompleteAdapter) binding.people.getAdapter()).include(user); - BrandedSnackbar.make( - requireView(), getString(R.string.unassigned_user, user.getDisplayname()), - Snackbar.LENGTH_LONG) - .setAction(R.string.simple_undo, v1 -> { - viewModel.getFullCard().getAssignedUsers().add(user); - ((UserAutoCompleteAdapter) binding.people.getAdapter()).exclude(user); - addAvatar(baseUrl, user); - }).show(); - }); - } - binding.peopleList.addView(avatar); - avatar.requestLayout(); - ViewUtil.addAvatar(avatar, baseUrl, user.getUid(), avatarSize, R.drawable.ic_person_grey600_24dp); - } - @Override public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) { Calendar c = Calendar.getInstance(); |