1package eu.siacs.conversations.ui.adapter;
2
3import android.content.Context;
4import android.widget.ArrayAdapter;
5import android.widget.Filter;
6
7import androidx.annotation.NonNull;
8
9import java.util.ArrayList;
10import java.util.Collection;
11import java.util.Collections;
12import java.util.Locale;
13import java.util.regex.Pattern;
14
15import eu.siacs.conversations.Config;
16
17public class KnownHostsAdapter extends ArrayAdapter<String> {
18
19 private static final Pattern E164_PATTERN = Pattern.compile("^\\+[1-9]\\d{1,14}$");
20
21 private ArrayList<String> domains;
22 private final Filter domainFilter = new Filter() {
23
24 @Override
25 protected FilterResults performFiltering(CharSequence constraint) {
26 final ArrayList<String> suggestions = new ArrayList<>();
27 final String[] split = constraint == null ? new String[0] : constraint.toString().split("@");
28 if (split.length == 1) {
29 final String local = split[0].toLowerCase(Locale.ENGLISH);
30 if (Config.QUICKSY_DOMAIN != null && E164_PATTERN.matcher(local).matches()) {
31 suggestions.add(local + '@' + Config.QUICKSY_DOMAIN.toEscapedString());
32 } else {
33 for (String domain : domains) {
34 suggestions.add(local + '@' + domain);
35 }
36 }
37 } else if (split.length == 2) {
38 final String localPart = split[0].toLowerCase(Locale.ENGLISH);
39 final String domainPart = split[1].toLowerCase(Locale.ENGLISH);
40 if (domains.contains(domainPart)) {
41 return new FilterResults();
42 }
43 for (String domain : domains) {
44 if (domain.contains(domainPart)) {
45 suggestions.add(localPart + "@" + domain);
46 }
47 }
48 } else {
49 return new FilterResults();
50 }
51 FilterResults filterResults = new FilterResults();
52 filterResults.values = suggestions;
53 filterResults.count = suggestions.size();
54 return filterResults;
55 }
56
57 @Override
58 protected void publishResults(CharSequence constraint, FilterResults results) {
59 ArrayList filteredList = (ArrayList) results.values;
60 if (results.count > 0) {
61 clear();
62 addAll(filteredList);
63 notifyDataSetChanged();
64 }
65 }
66 };
67
68 public KnownHostsAdapter(Context context, int viewResourceId, Collection<String> mKnownHosts) {
69 super(context, viewResourceId, new ArrayList<>());
70 domains = new ArrayList<>(mKnownHosts);
71 Collections.sort(domains);
72 }
73
74 public KnownHostsAdapter(Context context, int viewResourceId) {
75 super(context, viewResourceId, new ArrayList<>());
76 domains = new ArrayList<>();
77 }
78
79 public void refresh(Collection<String> knownHosts) {
80 domains = new ArrayList<>(knownHosts);
81 Collections.sort(domains);
82 notifyDataSetChanged();
83 }
84
85 @Override
86 @NonNull
87 public Filter getFilter() {
88 return domainFilter;
89 }
90}