blob: 1a28e8a90ca61419ffaf7fe223686a22c5c36af6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
package it.niedermann.nextcloud.deck.util;
import static java.util.stream.Collectors.toList;
import android.content.Context;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import androidx.annotation.NonNull;
import androidx.viewbinding.ViewBinding;
import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import it.niedermann.android.reactivelivedata.ReactiveLiveData;
import it.niedermann.nextcloud.deck.DeckLog;
import it.niedermann.nextcloud.deck.model.Account;
import it.niedermann.nextcloud.deck.model.interfaces.IRemoteEntity;
import it.niedermann.nextcloud.deck.repository.SyncRepository;
public abstract class AutoCompleteAdapter<ItemType extends IRemoteEntity> extends BaseAdapter implements Filterable {
@NonNull
private List<ItemType> itemList = new ArrayList<>();
@NonNull
private final List<ItemType> itemsToExclude = new ArrayList<>();
@NonNull
protected SyncRepository syncRepository;
protected final Account account;
protected final long boardId;
protected final ReactiveLiveData<String> constraint$ = new ReactiveLiveData<String>();
private final AutoCompleteFilter filter = new AutoCompleteFilter() {
@Override
protected Filter.FilterResults performFiltering(CharSequence constraint) {
constraint$.postValue(constraint == null ? "" : constraint.toString());
return filterResults;
}
};
protected AutoCompleteAdapter(@NonNull Context context, @NonNull Account account, long boardId) throws NextcloudFilesAppAccountNotFoundException {
this.account = account;
this.boardId = boardId;
this.syncRepository = new SyncRepository(context, account);
}
@Override
public int getCount() {
return itemList.size();
}
@Override
public ItemType getItem(int position) {
return itemList.get(position);
}
@Override
public long getItemId(int position) {
// Create proposals do have null as local ID
final var localId = itemList.get(position).getLocalId();
return localId == null ? Long.MIN_VALUE : localId;
}
protected List<ItemType> filterExcluded(@NonNull List<ItemType> users) {
return users.stream().filter(this::userIsNotInExclusionList).collect(toList());
}
private boolean userIsNotInExclusionList(@NonNull ItemType user) {
return itemsToExclude
.stream()
.map(IRemoteEntity::getLocalId)
.noneMatch(idToExclude -> Objects.equals(user.getLocalId(), idToExclude));
}
protected static class ViewHolder<ViewBindingType extends ViewBinding> {
public final ViewBindingType binding;
public ViewHolder(ViewBindingType binding) {
this.binding = binding;
}
}
public abstract class AutoCompleteFilter extends Filter {
protected final Filter.FilterResults filterResults = new Filter.FilterResults();
@Override
public void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
if (!itemList.equals(results.values)) {
//noinspection unchecked
itemList = (List<ItemType>) results.values;
}
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
private void publishResults(List<ItemType> list) {
DeckLog.verbose("New result list", list.stream().map(IRemoteEntity::toString).collect(toList()));
filterResults.values = list;
filterResults.count = list.size();
publishResults("", filterResults);
}
public Filter.FilterResults getFilter() {
return filterResults;
}
}
protected void publishResults(List<ItemType> list) {
filter.publishResults(list);
}
@Override
public Filter getFilter() {
return filter;
}
public void exclude(ItemType item) {
this.itemsToExclude.add(item);
}
public void doNotLongerExclude(ItemType item) {
this.itemsToExclude.remove(item);
}
}
|