From f9f07063876ec5f3917ce72385b015e1b5f31d7e Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Fri, 26 Apr 2019 23:12:05 +0200 Subject: implement channel discovery refactor muc search to use http cache channel search results --- .../messenger/ui/ChannelDiscoveryActivity.java | 196 +++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 src/main/java/de/pixart/messenger/ui/ChannelDiscoveryActivity.java (limited to 'src/main/java/de/pixart/messenger/ui/ChannelDiscoveryActivity.java') diff --git a/src/main/java/de/pixart/messenger/ui/ChannelDiscoveryActivity.java b/src/main/java/de/pixart/messenger/ui/ChannelDiscoveryActivity.java new file mode 100644 index 000000000..e0b70b6ac --- /dev/null +++ b/src/main/java/de/pixart/messenger/ui/ChannelDiscoveryActivity.java @@ -0,0 +1,196 @@ +package de.pixart.messenger.ui; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.SharedPreferences; +import android.databinding.DataBindingUtil; +import android.os.Bundle; +import android.support.v7.widget.Toolbar; +import android.text.Html; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.TextView; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +import de.pixart.messenger.R; +import de.pixart.messenger.databinding.ActivityChannelDiscoveryBinding; +import de.pixart.messenger.entities.Account; +import de.pixart.messenger.entities.Conversation; +import de.pixart.messenger.http.services.MuclumbusService; +import de.pixart.messenger.services.ChannelDiscoveryService; +import de.pixart.messenger.ui.adapter.ChannelSearchResultAdapter; +import de.pixart.messenger.ui.util.PendingItem; +import de.pixart.messenger.ui.util.SoftKeyboardUtils; +import de.pixart.messenger.utils.AccountUtils; +import rocks.xmpp.addr.Jid; + +public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.OnActionExpandListener, TextView.OnEditorActionListener, ChannelDiscoveryService.OnChannelSearchResultsFound, ChannelSearchResultAdapter.OnChannelSearchResultSelected { + private static final String CHANNEL_DISCOVERY_OPT_IN = "channel_discovery_opt_in"; + private final ChannelSearchResultAdapter adapter = new ChannelSearchResultAdapter(); + private ActivityChannelDiscoveryBinding binding; + private final PendingItem mInitialSearchValue = new PendingItem<>(); + private MenuItem mMenuSearchView; + private EditText mSearchEditText; + private boolean optedIn = false; + + @Override + protected void refreshUiReal() { + + } + + @Override + void onBackendConnected() { + if (optedIn) { + String query; + if (mMenuSearchView != null && mMenuSearchView.isActionViewExpanded()) { + query = mSearchEditText.getText().toString(); + } else { + query = mInitialSearchValue.peek(); + } + xmppConnectionService.discoverChannels(query, this); + } + } + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = DataBindingUtil.setContentView(this, R.layout.activity_channel_discovery); + setSupportActionBar((Toolbar) binding.toolbar); + configureActionBar(getSupportActionBar(), true); + binding.list.setAdapter(this.adapter); + this.adapter.setOnChannelSearchResultSelectedListener(this); + optedIn = getPreferences().getBoolean(CHANNEL_DISCOVERY_OPT_IN, false); + + final String search = savedInstanceState == null ? null : savedInstanceState.getString("search"); + if (search != null) { + mInitialSearchValue.push(search); + } + } + + @Override + public boolean onCreateOptionsMenu(final Menu menu) { + getMenuInflater().inflate(R.menu.muc_users_activity, menu); + mMenuSearchView = menu.findItem(R.id.action_search); + final View mSearchView = mMenuSearchView.getActionView(); + mSearchEditText = mSearchView.findViewById(R.id.search_field); + mSearchEditText.setHint(R.string.search_channels); + String initialSearchValue = mInitialSearchValue.pop(); + if (initialSearchValue != null) { + mMenuSearchView.expandActionView(); + mSearchEditText.append(initialSearchValue); + mSearchEditText.requestFocus(); + if (optedIn) { + xmppConnectionService.discoverChannels(initialSearchValue, this); + } + } + mSearchEditText.setOnEditorActionListener(this); + mMenuSearchView.setOnActionExpandListener(this); + return true; + } + + @Override + public boolean onMenuItemActionExpand(MenuItem item) { + mSearchEditText.post(() -> { + mSearchEditText.requestFocus(); + final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(mSearchEditText, InputMethodManager.SHOW_IMPLICIT); + }); + return true; + } + + @Override + public boolean onMenuItemActionCollapse(MenuItem item) { + final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY); + mSearchEditText.setText(""); + toggleLoadingScreen(); + if (optedIn) { + xmppConnectionService.discoverChannels(null, this); + } + return true; + } + + private void toggleLoadingScreen() { + adapter.submitList(Collections.emptyList()); + binding.progressBar.setVisibility(View.VISIBLE); + } + + @Override + public void onStart() { + super.onStart(); + if (!optedIn) { + final AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.channel_discovery_opt_in_title); + builder.setMessage(Html.fromHtml(getString(R.string.channel_discover_opt_in_message))); + builder.setNegativeButton(R.string.cancel, (dialog, which) -> finish()); + builder.setPositiveButton(R.string.confirm, (dialog, which) -> optIn()); + builder.setOnCancelListener(dialog -> finish()); + final AlertDialog dialog = builder.create(); + dialog.setCanceledOnTouchOutside(false); + dialog.show(); + } + } + + @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + if (mMenuSearchView != null && mMenuSearchView.isActionViewExpanded()) { + savedInstanceState.putString("search", mSearchEditText != null ? mSearchEditText.getText().toString() : null); + } + super.onSaveInstanceState(savedInstanceState); + } + + private void optIn() { + SharedPreferences preferences = getPreferences(); + preferences.edit().putBoolean(CHANNEL_DISCOVERY_OPT_IN, true).apply(); + optedIn = true; + xmppConnectionService.discoverChannels(null, this); + } + + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (optedIn) { + xmppConnectionService.discoverChannels(v.getText().toString(), this); + } + toggleLoadingScreen(); + SoftKeyboardUtils.hideSoftKeyboard(this); + return true; + } + + @Override + public void onChannelSearchResultsFound(List results) { + runOnUiThread(() -> { + adapter.submitList(results); + binding.list.setVisibility(View.VISIBLE); + binding.progressBar.setVisibility(View.GONE); + }); + } + + @Override + public void onChannelSearchResult(final MuclumbusService.Room result) { + List accounts = AccountUtils.getEnabledAccounts(xmppConnectionService); + if (accounts.size() == 1) { + joinChannelSearchResult(accounts.get(0), result); + } else if (accounts.size() > 0) { + final AtomicReference account = new AtomicReference<>(accounts.get(0)); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.choose_account); + builder.setSingleChoiceItems(accounts.toArray(new CharSequence[0]), 0, (dialog, which) -> account.set(accounts.get(which))); + builder.setPositiveButton(R.string.join, (dialog, which) -> joinChannelSearchResult(account.get(), result)); + builder.setNegativeButton(R.string.cancel, null); + builder.create().show(); + } + } + + public void joinChannelSearchResult(String accountJid, MuclumbusService.Room result) { + Account account = xmppConnectionService.findAccountByJid(Jid.of(accountJid)); + final Conversation conversation = xmppConnectionService.findOrCreateConversation(account, result.getRoom(), true, true, true); + switchToConversation(conversation); + } +} \ No newline at end of file -- cgit v1.2.3