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
|
package it.niedermann.nextcloud.deck.ui.card;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.activity.ComponentActivity;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import it.niedermann.android.reactivelivedata.ReactiveLiveData;
import it.niedermann.android.util.ColorUtil;
import it.niedermann.nextcloud.deck.R;
import it.niedermann.nextcloud.deck.databinding.ItemAutocompleteLabelBinding;
import it.niedermann.nextcloud.deck.model.Account;
import it.niedermann.nextcloud.deck.model.Board;
import it.niedermann.nextcloud.deck.model.Label;
import it.niedermann.nextcloud.deck.model.full.FullBoard;
import it.niedermann.nextcloud.deck.util.AutoCompleteAdapter;
public class LabelAutoCompleteAdapter extends AutoCompleteAdapter<Label> {
@NonNull
protected final Context context;
@ColorInt
private final int createLabelColor;
private final ReactiveLiveData<Boolean> canManage$;
public LabelAutoCompleteAdapter(@NonNull ComponentActivity activity, @NonNull Account account, long boardId, long cardId) throws NextcloudFilesAppAccountNotFoundException {
super(activity, account, boardId);
this.context = activity;
final String[] colors = activity.getResources().getStringArray(R.array.board_default_colors);
createLabelColor = Color.parseColor(colors[new Random().nextInt(colors.length)]);
canManage$ = new ReactiveLiveData<>(syncRepository.getFullBoardById(account.getId(), boardId))
.map(FullBoard::getBoard)
.map(Board::isPermissionManage);
constraint$
.flatMap(constraint -> TextUtils.isEmpty(constraint)
? syncRepository.findProposalsForLabelsToAssign(account.getId(), boardId, cardId)
: syncRepository.searchNotYetAssignedLabelsByTitle(account, boardId, cardId, constraint))
.map(this::filterExcluded)
.flatMap(this::addCreateLabelIfNeeded)
.distinctUntilChanged()
.observe(activity, this::publishResults);
}
private ReactiveLiveData<List<Label>> addCreateLabelIfNeeded(@NonNull List<Label> labels) {
return canManage$
.combineWith(() -> constraint$)
.map(args -> {
final var canManage = args.first;
final var constraint = args.second;
if (canManage && !TextUtils.isEmpty(constraint) && !labelTitleIsPresent(labels, constraint)) {
labels.add(createLabel(constraint));
}
return labels;
});
}
private boolean labelTitleIsPresent(@NonNull Collection<Label> labels, @NonNull CharSequence title) {
return labels.stream().map(Label::getTitle).anyMatch(title::equals);
}
@NonNull
private Label createLabel(String title) {
final var label = new Label();
label.setLocalId(null);
label.setBoardId(boardId);
label.setAccountId(account.getId());
label.setTitle(title);
label.setColor(createLabelColor);
return label;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ItemAutocompleteLabelBinding binding;
if (convertView != null) {
binding = ItemAutocompleteLabelBinding.bind(convertView);
} else {
binding = ItemAutocompleteLabelBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
}
final var label = getItem(position);
final int labelColor = label.getColor();
final int color = ColorUtil.INSTANCE.getForegroundColorForBackgroundColor(labelColor);
if (label.getLocalId() == null) {
binding.label.setText(String.format(context.getString(R.string.label_add, label.getTitle())));
} else {
binding.label.setText(label.getTitle());
}
binding.label.setChipBackgroundColor(ColorStateList.valueOf(labelColor));
binding.label.setTextColor(color);
if (label.getLocalId() == null) {
final var plusIcon = DrawableCompat.wrap(ContextCompat.getDrawable(binding.label.getContext(), R.drawable.ic_plus));
DrawableCompat.setTint(plusIcon, color);
binding.label.setChipIcon(plusIcon);
} else {
binding.label.setChipIcon(null);
}
return binding.getRoot();
}
}
|