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 protected 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 final ActivityMucUsersBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_muc_users);
106 setSupportActionBar(binding.toolbar);
107 Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
108 configureActionBar(getSupportActionBar(), true);
109 this.userAdapter = new UserAdapter(getPreferences().getBoolean("advanced_muc_mode", false));
110 binding.list.setAdapter(this.userAdapter);
111 }
112
113
114 @Override
115 public void onMucRosterUpdate() {
116 loadAndSubmitUsers();
117 }
118
119 private void displayToast(final String msg) {
120 runOnUiThread(() -> Toast.makeText(this, msg, Toast.LENGTH_SHORT).show());
121 }
122
123 @Override
124 public void onAffiliationChangedSuccessful(Jid jid) {
125
126 }
127
128 @Override
129 public void onAffiliationChangeFailed(Jid jid, int resId) {
130 displayToast(getString(resId, jid.asBareJid().toString()));
131 }
132
133 @Override
134 public boolean onCreateOptionsMenu(final Menu menu) {
135 getMenuInflater().inflate(R.menu.muc_users_activity, menu);
136 final MenuItem menuSearchView = menu.findItem(R.id.action_search);
137 final View mSearchView = menuSearchView.getActionView();
138 mSearchEditText = mSearchView.findViewById(R.id.search_field);
139 mSearchEditText.addTextChangedListener(this);
140 mSearchEditText.setHint(R.string.search_participants);
141 menuSearchView.setOnActionExpandListener(this);
142 return true;
143 }
144
145 @Override
146 public boolean onMenuItemActionExpand(MenuItem item) {
147 mSearchEditText.post(() -> {
148 mSearchEditText.requestFocus();
149 final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
150 imm.showSoftInput(mSearchEditText, InputMethodManager.SHOW_IMPLICIT);
151 });
152 return true;
153 }
154
155 @Override
156 public boolean onMenuItemActionCollapse(MenuItem item) {
157 final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
158 imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
159 mSearchEditText.setText("");
160 submitFilteredList("");
161 return true;
162 }
163
164 @Override
165 public void beforeTextChanged(CharSequence s, int start, int count, int after) {
166
167 }
168
169 @Override
170 public void onTextChanged(CharSequence s, int start, int before, int count) {
171
172 }
173
174 @Override
175 public void afterTextChanged(Editable s) {
176 submitFilteredList(s.toString());
177 }
178}