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