Some selection progress

Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
Mario Danic 2019-06-03 21:02:17 +02:00
parent 660b2be745
commit 55dd682830
5 changed files with 150 additions and 154 deletions

View File

@ -101,6 +101,8 @@ public class AdvancedUserItem extends AbstractFlexibleItem<AdvancedUserItem.User
@Override @Override
public void bindViewHolder(FlexibleAdapter adapter, UserItemViewHolder holder, int position, List payloads) { public void bindViewHolder(FlexibleAdapter adapter, UserItemViewHolder holder, int position, List payloads) {
holder.avatarImageView.setController(null);
if (adapter.hasFilter()) { if (adapter.hasFilter()) {
FlexibleUtils.highlightText(holder.contactDisplayName, participant.getName(), FlexibleUtils.highlightText(holder.contactDisplayName, participant.getName(),
String.valueOf(adapter.getFilter(String.class)), NextcloudTalkApplication.getSharedApplication() String.valueOf(adapter.getFilter(String.class)), NextcloudTalkApplication.getSharedApplication()

View File

@ -96,6 +96,10 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
@Override @Override
public void bindViewHolder(FlexibleAdapter<IFlexible> adapter, ConversationItemViewHolder holder, int position, List<Object> payloads) { public void bindViewHolder(FlexibleAdapter<IFlexible> adapter, ConversationItemViewHolder holder, int position, List<Object> payloads) {
Context context = NextcloudTalkApplication.getSharedApplication().getApplicationContext(); Context context = NextcloudTalkApplication.getSharedApplication().getApplicationContext();
holder.dialogAvatar.setController(null);
holder.dialogLastMessageUserAvatar.setController(null);
if (adapter.hasFilter()) { if (adapter.hasFilter()) {
FlexibleUtils.highlightText(holder.dialogName, conversation.getDisplayName(), FlexibleUtils.highlightText(holder.dialogName, conversation.getDisplayName(),
String.valueOf(adapter.getFilter(String.class)), NextcloudTalkApplication.getSharedApplication() String.valueOf(adapter.getFilter(String.class)), NextcloudTalkApplication.getSharedApplication()

View File

@ -66,7 +66,7 @@ public class UserItem extends AbstractFlexibleItem<UserItem.UserItemViewHolder>
public boolean equals(Object o) { public boolean equals(Object o) {
if (o instanceof UserItem) { if (o instanceof UserItem) {
UserItem inItem = (UserItem) o; UserItem inItem = (UserItem) o;
return participant.equals(inItem.getModel()); return participant.getUserId().equals(inItem.getModel().getUserId());
} }
return false; return false;
} }
@ -106,8 +106,10 @@ public class UserItem extends AbstractFlexibleItem<UserItem.UserItemViewHolder>
@Override @Override
public void bindViewHolder(FlexibleAdapter adapter, UserItemViewHolder holder, int position, List payloads) { public void bindViewHolder(FlexibleAdapter adapter, UserItemViewHolder holder, int position, List payloads) {
holder.simpleDraweeView.setController(null);
if (holder.checkedImageView != null) { if (holder.checkedImageView != null) {
if (adapter.isSelected(position)) { if (participant.isSelected()) {
holder.checkedImageView.setVisibility(View.VISIBLE); holder.checkedImageView.setVisibility(View.VISIBLE);
} else { } else {
holder.checkedImageView.setVisibility(View.GONE); holder.checkedImageView.setVisibility(View.GONE);
@ -133,6 +135,7 @@ public class UserItem extends AbstractFlexibleItem<UserItem.UserItemViewHolder>
Participant.ParticipantType.USER_FOLLOWING_LINK.equals(participant.getType())) { Participant.ParticipantType.USER_FOLLOWING_LINK.equals(participant.getType())) {
// TODO: Show generated avatar for guests // TODO: Show generated avatar for guests
} else { } else {
DraweeController draweeController = Fresco.newDraweeControllerBuilder() DraweeController draweeController = Fresco.newDraweeControllerBuilder()
.setOldController(holder.simpleDraweeView.getController()) .setOldController(holder.simpleDraweeView.getController())
.setAutoPlayAnimations(true) .setAutoPlayAnimations(true)
@ -213,16 +216,19 @@ public class UserItem extends AbstractFlexibleItem<UserItem.UserItemViewHolder>
break; break;
} }
if (!holder.contactMentionId.getText().equals(userType)) {
holder.contactMentionId.setText(userType); holder.contactMentionId.setText(userType);
holder.contactMentionId.setTextColor(NextcloudTalkApplication.getSharedApplication().getResources().getColor(R.color.colorPrimary)); holder.contactMentionId.setTextColor(NextcloudTalkApplication.getSharedApplication().getResources().getColor(R.color.colorPrimary));
} }
} }
} }
}
@Override @Override
public boolean filter(String constraint) { public boolean filter(String constraint) {
return participant.getDisplayName() != null && return participant.getDisplayName() != null &&
Pattern.compile(constraint, Pattern.CASE_INSENSITIVE | Pattern.LITERAL).matcher(participant.getDisplayName().trim()).find(); (Pattern.compile(constraint, Pattern.CASE_INSENSITIVE | Pattern.LITERAL).matcher(participant.getDisplayName().trim()).find() ||
Pattern.compile(constraint, Pattern.CASE_INSENSITIVE | Pattern.LITERAL).matcher(participant.getUserId().trim()).find());
} }
@Override @Override

View File

@ -89,7 +89,6 @@ import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode; import org.greenrobot.eventbus.ThreadMode;
import org.parceler.Parcels; import org.parceler.Parcels;
import retrofit2.HttpException;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.*; import java.util.*;
@ -100,7 +99,6 @@ public class ContactsController extends BaseController implements SearchView.OnQ
public static final String TAG = "ContactsController"; public static final String TAG = "ContactsController";
private static final String KEY_SEARCH_QUERY = "ContactsController.searchQuery";
@Nullable @Nullable
@BindView(R.id.initial_relative_layout) @BindView(R.id.initial_relative_layout)
RelativeLayout initialRelativeLayout; RelativeLayout initialRelativeLayout;
@ -140,7 +138,7 @@ public class ContactsController extends BaseController implements SearchView.OnQ
private Disposable contactsQueryDisposable; private Disposable contactsQueryDisposable;
private Disposable cacheQueryDisposable; private Disposable cacheQueryDisposable;
private FlexibleAdapter adapter; private FlexibleAdapter adapter;
private List<AbstractFlexibleItem> contactItems = new ArrayList<>(); private List<AbstractFlexibleItem> contactItems;
private BottomSheet bottomSheet; private BottomSheet bottomSheet;
private View view; private View view;
private int currentPage; private int currentPage;
@ -150,7 +148,6 @@ public class ContactsController extends BaseController implements SearchView.OnQ
private MenuItem searchItem; private MenuItem searchItem;
private SearchView searchView; private SearchView searchView;
private String searchQuery;
private boolean isNewConversationView; private boolean isNewConversationView;
private boolean isPublicCall; private boolean isPublicCall;
@ -203,6 +200,7 @@ public class ContactsController extends BaseController implements SearchView.OnQ
} }
if (adapter == null) { if (adapter == null) {
contactItems = new ArrayList<>();
adapter = new FlexibleAdapter<>(contactItems, getActivity(), true); adapter = new FlexibleAdapter<>(contactItems, getActivity(), true);
if (currentUser != null) { if (currentUser != null) {
@ -220,16 +218,6 @@ public class ContactsController extends BaseController implements SearchView.OnQ
adapter.setEndlessScrollListener(this, new ProgressItem()); adapter.setEndlessScrollListener(this, new ProgressItem());
adapter.registerAdapterDataObserver(new androidx.recyclerview.widget.RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
super.onChanged();
checkAndHandleDoneMenuItem();
adapter.filterItems();
adapter.onLoadMoreComplete(null);
}
});
adapter.setStickyHeaderElevation(5) adapter.setStickyHeaderElevation(5)
.setUnlinkAllItemsOnRemoveHeaders(true) .setUnlinkAllItemsOnRemoveHeaders(true)
.setDisplayHeadersAtStartUp(true) .setDisplayHeadersAtStartUp(true)
@ -239,18 +227,36 @@ public class ContactsController extends BaseController implements SearchView.OnQ
} }
private void selectionDone() { private void selectionDone() {
if (!isPublicCall && adapter.getSelectedPositions().size() == 1) { List abstractFlexibleItemList = adapter.getCurrentItems();
String roomType = "1";
int firstSelectedPosition = adapter.getSelectedPositions().get(0); ArrayList<String> userIds = new ArrayList<>();
Object selectedObject = adapter.getItem(firstSelectedPosition); ArrayList<String> groupIds = new ArrayList<>();
if (selectedObject != null && "groups".equals(((UserItem) selectedObject).getModel().getSource())) {
roomType = "2"; UserItem userItem;
for (int i = 0; i < abstractFlexibleItemList.size(); i++) {
if (abstractFlexibleItemList.get(i) instanceof UserItem) {
userItem = (UserItem) abstractFlexibleItemList.get(i);
if ("groups".equals(userItem.getModel().getSource())) {
groupIds.add(userItem.getModel().getUserId());
} else {
userIds.add(userItem.getModel().getUserId());
}
}
}
if (!isPublicCall && (groupIds.size() + userIds.size() == 1)) {
String userId;
String roomType = "1";
if (groupIds.size() == 1) {
roomType = "2";
userId = groupIds.get(0);
} else {
userId = userIds.get(0);
} }
if (selectedObject != null) {
RetrofitBucket retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(currentUser.getBaseUrl(), roomType, RetrofitBucket retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(currentUser.getBaseUrl(), roomType,
((UserItem) selectedObject).getModel().getUserId(), null); userId, null);
ncApi.createRoom(credentials, ncApi.createRoom(credentials,
retrofitBucket.getUrl(), retrofitBucket.getQueryMap()) retrofitBucket.getUrl(), retrofitBucket.getQueryMap())
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
@ -299,7 +305,6 @@ public class ContactsController extends BaseController implements SearchView.OnQ
public void onComplete() { public void onComplete() {
} }
}); });
}
} else { } else {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
@ -311,20 +316,6 @@ public class ContactsController extends BaseController implements SearchView.OnQ
} }
bundle.putParcelable(BundleKeys.KEY_CONVERSATION_TYPE, Parcels.wrap(roomType)); bundle.putParcelable(BundleKeys.KEY_CONVERSATION_TYPE, Parcels.wrap(roomType));
ArrayList<String> userIds = new ArrayList<>();
Set<Integer> selectedPositions = adapter.getSelectedPositionsAsSet();
ArrayList<String> groupIds = new ArrayList<>();
for (int selectedPosition : selectedPositions) {
if (adapter.getItem(selectedPosition) instanceof UserItem) {
UserItem userItem = (UserItem) adapter.getItem(selectedPosition);
if (!"groups".equals(userItem.getModel().getSource())) {
userIds.add(userItem.getModel().getUserId());
} else {
groupIds.add(userItem.getModel().getUserId());
}
}
}
bundle.putStringArrayList(BundleKeys.KEY_INVITED_PARTICIPANTS, userIds); bundle.putStringArrayList(BundleKeys.KEY_INVITED_PARTICIPANTS, userIds);
bundle.putStringArrayList(BundleKeys.KEY_INVITED_GROUP, groupIds); bundle.putStringArrayList(BundleKeys.KEY_INVITED_GROUP, groupIds);
bundle.putInt(BundleKeys.KEY_OPERATION_CODE, 11); bundle.putInt(BundleKeys.KEY_OPERATION_CODE, 11);
@ -396,13 +387,7 @@ public class ContactsController extends BaseController implements SearchView.OnQ
userHeaderItems = new HashMap<>(); userHeaderItems = new HashMap<>();
String query = (String) adapter.getFilter(String.class);
String query = "";
if (searchView != null && !TextUtils.isEmpty(searchView.getQuery())) {
query = searchView.getQuery().toString();
} else if (startFromScratch) {
contactItems = new ArrayList<>();
}
RetrofitBucket retrofitBucket; RetrofitBucket retrofitBucket;
boolean serverIs14OrUp = false; boolean serverIs14OrUp = false;
@ -461,7 +446,6 @@ public class ContactsController extends BaseController implements SearchView.OnQ
Participant participant; Participant participant;
List<AbstractFlexibleItem> newUserItemList = new ArrayList<>(); List<AbstractFlexibleItem> newUserItemList = new ArrayList<>();
newUserItemList.addAll(contactItems);
try { try {
if (!finalServerIs14OrUp) { if (!finalServerIs14OrUp) {
@ -552,14 +536,8 @@ public class ContactsController extends BaseController implements SearchView.OnQ
currentSearchPage = (int) modifiedQueryMap.get("page"); currentSearchPage = (int) modifiedQueryMap.get("page");
} }
boolean shouldFilterManually = false;
if (newUserItemList.size() == contactItems.size()) {
shouldFilterManually = true;
}
contactItems = newUserItemList;
userHeaderItems = new HashMap<>(); userHeaderItems = new HashMap<>();
contactItems.addAll(newUserItemList);
Collections.sort(newUserItemList, (o1, o2) -> { Collections.sort(newUserItemList, (o1, o2) -> {
String firstName; String firstName;
@ -591,13 +569,41 @@ public class ContactsController extends BaseController implements SearchView.OnQ
return firstName.compareToIgnoreCase(secondName); return firstName.compareToIgnoreCase(secondName);
}); });
Collections.sort(contactItems, (o1, o2) -> {
String firstName;
String secondName;
adapter.clearSelection();
if (!shouldFilterManually) { if (o1 instanceof UserItem) {
adapter.updateDataSet(newUserItemList, false); firstName = ((UserItem) o1).getModel().getDisplayName();
} else {
firstName = ((GenericTextHeaderItem) o1).getModel();
}
if (o2 instanceof UserItem) {
secondName = ((UserItem) o2).getModel().getDisplayName();
} else {
secondName = ((GenericTextHeaderItem) o2).getModel();
}
if (o1 instanceof UserItem && o2 instanceof UserItem) {
if ("groups".equals(((UserItem) o1).getModel().getSource()) && "groups".equals(((UserItem) o2).getModel().getSource())) {
return firstName.compareToIgnoreCase(secondName);
} else if ("groups".equals(((UserItem) o1).getModel().getSource())) {
return -1;
} else if ("groups".equals(((UserItem) o2).getModel().getSource())) {
return 1;
}
}
return firstName.compareToIgnoreCase(secondName);
});
if (newUserItemList.size() > 0) {
adapter.updateDataSet(newUserItemList);
} else { } else {
adapter.filterItems(); adapter.filterItems();
adapter.onLoadMoreComplete(null);
} }
if (swipeRefreshLayout != null) { if (swipeRefreshLayout != null) {
@ -609,24 +615,9 @@ public class ContactsController extends BaseController implements SearchView.OnQ
@Override @Override
public void onError(Throwable e) { public void onError(Throwable e) {
if (e instanceof HttpException) {
HttpException exception = (HttpException) e;
switch (exception.code()) {
case 401:
getRouter().pushController((RouterTransaction.with(new WebViewLoginController(currentUser.getBaseUrl(),
true))
.pushChangeHandler(new VerticalChangeHandler())
.popChangeHandler(new VerticalChangeHandler())));
break;
default:
break;
}
if (swipeRefreshLayout != null) { if (swipeRefreshLayout != null) {
swipeRefreshLayout.setRefreshing(false); swipeRefreshLayout.setRefreshing(false);
} }
}
dispose(contactsQueryDisposable); dispose(contactsQueryDisposable);
} }
@ -704,15 +695,11 @@ public class ContactsController extends BaseController implements SearchView.OnQ
public void onSaveViewState(@NonNull View view, @NonNull Bundle outState) { public void onSaveViewState(@NonNull View view, @NonNull Bundle outState) {
adapter.onSaveInstanceState(outState); adapter.onSaveInstanceState(outState);
super.onSaveViewState(view, outState); super.onSaveViewState(view, outState);
if (searchView != null && !TextUtils.isEmpty(searchView.getQuery())) {
outState.putString(KEY_SEARCH_QUERY, searchView.getQuery().toString());
}
} }
@Override @Override
public void onRestoreViewState(@NonNull View view, @NonNull Bundle savedViewState) { public void onRestoreViewState(@NonNull View view, @NonNull Bundle savedViewState) {
super.onRestoreViewState(view, savedViewState); super.onRestoreViewState(view, savedViewState);
searchQuery = savedViewState.getString(KEY_SEARCH_QUERY, "");
if (adapter != null) { if (adapter != null) {
adapter.onRestoreInstanceState(savedViewState); adapter.onRestoreInstanceState(savedViewState);
} }
@ -726,20 +713,14 @@ public class ContactsController extends BaseController implements SearchView.OnQ
@Override @Override
public boolean onQueryTextChange(String newText) { public boolean onQueryTextChange(String newText) {
if (adapter.hasNewFilter(newText) || !TextUtils.isEmpty(searchQuery)) { if (!newText.equals("") && adapter.hasNewFilter(newText)) {
Log.d("MARIO", "SETTING FILTER TO " + newText);
if (!TextUtils.isEmpty(searchQuery)) {
adapter.setFilter(searchQuery);
adapter.filterItems();
searchQuery = "";
} else {
adapter.setFilter(newText); adapter.setFilter(newText);
if (TextUtils.isEmpty(newText)) {
adapter.filterItems();
} else {
fetchData(true); fetchData(true);
} } else if (newText.equals("")) {
} Log.d("MARIO", "SETTING FILTER TO " + "CLEARING FILTER");
adapter.setFilter("");
adapter.updateDataSet(contactItems);
} }
if (swipeRefreshLayout != null) { if (swipeRefreshLayout != null) {
@ -898,23 +879,27 @@ public class ContactsController extends BaseController implements SearchView.OnQ
} }
}); });
} else { } else {
adapter.toggleSelection(position); Participant participant = ((UserItem) adapter.getItem(position)).getModel();
participant.setSelected(!participant.isSelected());
if (currentUser.hasSpreedCapabilityWithName("last-room-activity") if (currentUser.hasSpreedCapabilityWithName("last-room-activity")
&& !currentUser.hasSpreedCapabilityWithName("invite-groups-and-mails") && && !currentUser.hasSpreedCapabilityWithName("invite-groups-and-mails") &&
"groups".equals(((UserItem) adapter.getItem(position)).getModel().getSource()) && "groups".equals(((UserItem) adapter.getItem(position)).getModel().getSource()) &&
participant.isSelected() &&
adapter.getSelectedItemCount() > 1) { adapter.getSelectedItemCount() > 1) {
List<Integer> selectedPositions = adapter.getSelectedPositions(); List<UserItem> currentItems = adapter.getCurrentItems();
for (int i = 0; i < selectedPositions.size(); i++) { Participant internalParticipant;
if (!selectedPositions.get(i).equals(position) && "groups".equals(((UserItem) adapter.getItem(selectedPositions.get(i))).getModel().getSource())) { for (int i = 0; i < currentItems.size(); i++) {
adapter.toggleSelection(selectedPositions.get(i)); internalParticipant = currentItems.get(i).getModel();
if (internalParticipant.getUserId().equals(participant.getUserId()) &&
"groups".equals(internalParticipant.getSource()) && internalParticipant.isSelected()) {
internalParticipant.setSelected(false);
} }
} }
} }
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
checkAndHandleDoneMenuItem(); checkAndHandleDoneMenuItem();
} }
} }
@ -937,17 +922,16 @@ public class ContactsController extends BaseController implements SearchView.OnQ
isPublicCall = !isPublicCall; isPublicCall = !isPublicCall;
if (isPublicCall) { if (isPublicCall) {
List<Integer> selectedPositions = adapter.getSelectedPositions(); List<AbstractFlexibleItem> currentItems = adapter.getCurrentItems();
for (int selectedPosition : selectedPositions) { Participant internalParticipant;
if (adapter.getItem(selectedPosition) instanceof UserItem) { for (int i = 0; i < currentItems.size(); i++) {
UserItem userItem = (UserItem) adapter.getItem(selectedPosition); if (currentItems.get(i) instanceof UserItem) {
if ("groups".equals(userItem.getModel().getSource())) { internalParticipant = ((UserItem) currentItems.get(i)).getModel();
adapter.toggleSelection(selectedPosition); if ("groups".equals(internalParticipant.getSource()) && internalParticipant.isSelected()) {
internalParticipant.setSelected(false);
} }
} }
} }
} }
for (int i = 0; i < adapter.getItemCount(); i++) { for (int i = 0; i < adapter.getItemCount(); i++) {
@ -978,11 +962,7 @@ public class ContactsController extends BaseController implements SearchView.OnQ
@Override @Override
public void onLoadMore(int lastPosition, int currentPage) { public void onLoadMore(int lastPosition, int currentPage) {
String query = ""; String query = (String) adapter.getFilter(String.class);
if (searchView != null && !TextUtils.isEmpty(searchView.getQuery())) {
query = searchView.getQuery().toString();
}
if (!alreadyFetching && ((searchView != null && searchView.isIconified() && canFetchFurther) if (!alreadyFetching && ((searchView != null && searchView.isIconified() && canFetchFurther)
|| (!TextUtils.isEmpty(query) && canFetchSearchFurther))) { || (!TextUtils.isEmpty(query) && canFetchSearchFurther))) {

View File

@ -21,6 +21,7 @@
package com.nextcloud.talk.models.json.participants; package com.nextcloud.talk.models.json.participants;
import com.bluelinelabs.logansquare.annotation.JsonField; import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonIgnore;
import com.bluelinelabs.logansquare.annotation.JsonObject; import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter; import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter;
import com.nextcloud.talk.models.json.converters.ObjectParcelConverter; import com.nextcloud.talk.models.json.converters.ObjectParcelConverter;
@ -58,6 +59,9 @@ public class Participant {
Object inCall; Object inCall;
String source; String source;
boolean selected;
public ParticipantFlags getParticipantFlags() { public ParticipantFlags getParticipantFlags() {
ParticipantFlags participantFlags = ParticipantFlags.NOT_IN_CALL; ParticipantFlags participantFlags = ParticipantFlags.NOT_IN_CALL;
if (inCall != null) { if (inCall != null) {