package org.mercury_im.messenger.ui.chat; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.Toolbar; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.impl.JidCreate; import org.mercury_im.messenger.MercuryImApplication; import org.mercury_im.messenger.R; import java.util.UUID; import butterknife.BindView; import butterknife.ButterKnife; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.schedulers.Schedulers; public class ChatActivity extends AppCompatActivity implements ChatInputFragment.OnChatInputActionListener, SearchView.OnQueryTextListener { public static final String EXTRA_JID = "JID"; public static final String EXTRA_ACCOUNT = "ACCOUNT"; @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.recyclerView) RecyclerView recyclerView; private final MessagesRecyclerViewAdapter recyclerViewAdapter = new MessagesRecyclerViewAdapter(); private ChatViewModel chatViewModel; private final CompositeDisposable disposable = new CompositeDisposable(); private EntityBareJid jid; private UUID accountId; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("Mercury", "onCreate"); setContentView(R.layout.activity_chat); ButterKnife.bind(this); MercuryImApplication.getApplication().getAppComponent().inject(this); if (savedInstanceState == null) { savedInstanceState = getIntent().getExtras(); if (savedInstanceState == null) return; } setSupportActionBar(toolbar); // Show back arrow getSupportActionBar().setDisplayHomeAsUpEnabled(true); recyclerView.setAdapter(recyclerViewAdapter); recyclerView.setLayoutManager(new LinearLayoutManager(this)); String jidString = savedInstanceState.getString(EXTRA_JID); if (jidString != null) { jid = JidCreate.entityBareFromOrThrowUnchecked(jidString); // JID will never change, so just set it once getSupportActionBar().setSubtitle(jid.asUnescapedString()); accountId = UUID.fromString(savedInstanceState.getString(EXTRA_ACCOUNT)); chatViewModel = new ViewModelProvider(this).get(ChatViewModel.class); chatViewModel.init(accountId, jid); // Listen for updates to contact information and messages observeViewModel(chatViewModel); } } public void observeViewModel(ChatViewModel viewModel) { viewModel.getContactDisplayName().observe(this, name -> getSupportActionBar().setTitle(name)); viewModel.getMessages().observe(this, messageModels -> { recyclerViewAdapter.updateMessages(messageModels); recyclerView.scrollToPosition(messageModels.size() - 1); }); } public void onStop() { super.onStop(); disposable.clear(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_chat, menu); final MenuItem searchItem = menu.findItem(R.id.action_search); final SearchView searchView = (SearchView) searchItem.getActionView(); searchView.setOnQueryTextListener(this); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_debug: Log.d("CHATACTIVITY", "Fetch MAM messages!"); chatViewModel.requestMamMessages() .subscribeOn(Schedulers.io()) .subscribe(); break; // menu_chat case R.id.action_call: case R.id.action_clear_history: case R.id.action_notification_settings: case R.id.action_delete_chat: // long_click_message case R.id.action_edit_message: case R.id.action_reply_message: case R.id.action_copy_message: case R.id.action_forward_message: case R.id.action_delete_message: case R.id.action_message_details: // short_click_message case R.id.action_react_message: Toast.makeText(this, R.string.not_yet_implemented, Toast.LENGTH_SHORT).show(); return true; } return false; } @Override protected void onSaveInstanceState(@NonNull Bundle outState) { outState.putString(EXTRA_JID, jid.toString()); outState.putString(EXTRA_ACCOUNT, accountId.toString()); super.onSaveInstanceState(outState); } @Override public void onButtonEmojiClicked() { Toast.makeText(this, R.string.not_yet_implemented, Toast.LENGTH_SHORT).show(); } @Override public void onButtonMediaClicked() { Toast.makeText(this, R.string.not_yet_implemented, Toast.LENGTH_SHORT).show(); } @Override public void onComposingBodyChanged(String body) { } @Override public void onComposingBodySend(String body) { String msg = body.trim(); if (msg.isEmpty()) { return; } /* // TODO: Improve by using rx new Thread() { @Override public void run() { try { ChatManager.getInstanceFor(connectionCenter.getConnection(accountId).getConnection()) .chatWith(jid).send(msg); } catch (SmackException.NotConnectedException e) { Logger.getAnonymousLogger().log(Level.SEVERE,"NotConnectedException : \n" + e.getStackTrace().toString()); } catch (InterruptedException e) { Logger.getAnonymousLogger().log(Level.SEVERE,"InterruptedException" + e.getStackTrace().toString()); } } }.start(); */ } @Override public boolean onQueryTextSubmit(String query) { // Ignore. Logic is in onQueryTextChange. return false; } @Override public boolean onQueryTextChange(String query) { chatViewModel.queryTextChanged(query); return false; } @Override public boolean onSupportNavigateUp() { // Go back when left arrow is pressed in toolbar onBackPressed(); return true; } }