1package eu.siacs.conversations.ui;
2
3import android.content.Context;
4import android.content.Intent;
5import android.os.Bundle;
6import android.text.Editable;
7import android.text.TextUtils;
8import android.text.TextWatcher;
9import android.view.Menu;
10import android.view.MenuItem;
11import android.view.View;
12import android.view.inputmethod.InputMethodManager;
13import android.widget.EditText;
14import android.widget.Toast;
15
16import androidx.annotation.NonNull;
17import androidx.databinding.DataBindingUtil;
18
19import com.google.common.collect.Collections2;
20import com.google.common.collect.Lists;
21import com.google.common.collect.Ordering;
22
23import java.util.ArrayList;
24import java.util.Collections;
25import java.util.Locale;
26
27import eu.siacs.conversations.R;
28import eu.siacs.conversations.databinding.ActivityMucUsersBinding;
29import eu.siacs.conversations.entities.Contact;
30import eu.siacs.conversations.entities.Conversation;
31import eu.siacs.conversations.entities.MucOptions;
32import eu.siacs.conversations.services.XmppConnectionService;
33import eu.siacs.conversations.ui.adapter.UserAdapter;
34import eu.siacs.conversations.ui.util.MucDetailsContextMenuHelper;
35import eu.siacs.conversations.xmpp.Jid;
36
37public class MucUsersActivity extends XmppActivity implements XmppConnectionService.OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, MenuItem.OnActionExpandListener, TextWatcher {
38
39 private UserAdapter userAdapter;
40
41 private Conversation mConversation = null;
42
43 private EditText mSearchEditText;
44
45 private ArrayList<MucOptions.User> allUsers = new ArrayList<>();
46
47 @Override
48 protected void refreshUiReal() {
49 }
50
51 @Override
52 void onBackendConnected() {
53 final Intent intent = getIntent();
54 final String uuid = intent == null ? null : intent.getStringExtra("uuid");
55 if (uuid != null) {
56 mConversation = xmppConnectionService.findConversationByUuid(uuid);
57 }
58 loadAndSubmitUsers();
59 }
60
61 private void loadAndSubmitUsers() {
62 if (mConversation != null) {
63 allUsers = mConversation.getMucOptions().getUsers();
64 submitFilteredList(mSearchEditText != null ? mSearchEditText.getText().toString() : null);
65 }
66 }
67
68 private void submitFilteredList(final String search) {
69 if (TextUtils.isEmpty(search)) {
70 userAdapter.submitList(Ordering.natural().immutableSortedCopy(allUsers));
71 } else {
72 final String needle = search.toLowerCase(Locale.getDefault());
73 userAdapter.submitList(
74 Ordering.natural()
75 .immutableSortedCopy(
76 Collections2.filter(
77 this.allUsers,
78 user -> {
79 final String name = user.getName();
80 final Contact contact = user.getContact();
81 return name != null
82 && name.toLowerCase(
83 Locale.getDefault())
84 .contains(needle)
85 || contact != null
86 && contact.getDisplayName()
87 .toLowerCase(
88 Locale.getDefault())
89 .contains(needle);
90 })));
91 }
92 }
93
94 @Override
95 public boolean onContextItemSelected(@NonNull MenuItem item) {
96 if (!MucDetailsContextMenuHelper.onContextItemSelected(item, userAdapter.getSelectedUser(), this)) {
97 return super.onContextItemSelected(item);
98 }
99 return true;
100 }
101
102 @Override
103 protected void onCreate(final Bundle savedInstanceState) {
104 super.onCreate(savedInstanceState);
105 ActivityMucUsersBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_muc_users);
106 setSupportActionBar(binding.toolbar);
107 configureActionBar(getSupportActionBar(), true);
108 this.userAdapter = new UserAdapter(getPreferences().getBoolean("advanced_muc_mode", false));
109 binding.list.setAdapter(this.userAdapter);
110 }
111
112
113 @Override
114 public void onMucRosterUpdate() {
115 loadAndSubmitUsers();
116 }
117
118 private void displayToast(final String msg) {
119 runOnUiThread(() -> Toast.makeText(this, msg, Toast.LENGTH_SHORT).show());
120 }
121
122 @Override
123 public void onAffiliationChangedSuccessful(Jid jid) {
124
125 }
126
127 @Override
128 public void onAffiliationChangeFailed(Jid jid, int resId) {
129 displayToast(getString(resId, jid.asBareJid().toString()));
130 }
131
132 @Override
133 public boolean onCreateOptionsMenu(final Menu menu) {
134 getMenuInflater().inflate(R.menu.muc_users_activity, menu);
135 final MenuItem menuSearchView = menu.findItem(R.id.action_search);
136 final View mSearchView = menuSearchView.getActionView();
137 mSearchEditText = mSearchView.findViewById(R.id.search_field);
138 mSearchEditText.addTextChangedListener(this);
139 mSearchEditText.setHint(R.string.search_participants);
140 menuSearchView.setOnActionExpandListener(this);
141 return true;
142 }
143
144 @Override
145 public boolean onMenuItemActionExpand(MenuItem item) {
146 mSearchEditText.post(() -> {
147 mSearchEditText.requestFocus();
148 final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
149 imm.showSoftInput(mSearchEditText, InputMethodManager.SHOW_IMPLICIT);
150 });
151 return true;
152 }
153
154 @Override
155 public boolean onMenuItemActionCollapse(MenuItem item) {
156 final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
157 imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
158 mSearchEditText.setText("");
159 submitFilteredList("");
160 return true;
161 }
162
163 @Override
164 public void beforeTextChanged(CharSequence s, int start, int count, int after) {
165
166 }
167
168 @Override
169 public void onTextChanged(CharSequence s, int start, int before, int count) {
170
171 }
172
173 @Override
174 public void afterTextChanged(Editable s) {
175 submitFilteredList(s.toString());
176 }
177}