diff --git a/src/conversations/java/eu/siacs/conversations/ui/ManageAccountActivity.java b/src/conversations/java/eu/siacs/conversations/ui/ManageAccountActivity.java index 888a1f13e..c8de942b6 100644 --- a/src/conversations/java/eu/siacs/conversations/ui/ManageAccountActivity.java +++ b/src/conversations/java/eu/siacs/conversations/ui/ManageAccountActivity.java @@ -126,6 +126,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda R.menu.manageaccounts_context, menu); AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo; this.selectedAccount = accountList.get(acmi.position); + if (this.selectedAccount.isEnabled()) { menu.findItem(R.id.mgmt_account_enable).setVisible(false); menu.findItem(R.id.mgmt_account_announce_pgp).setVisible(Config.supportOpenPgp()); @@ -134,6 +135,15 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda menu.findItem(R.id.mgmt_account_announce_pgp).setVisible(false); menu.findItem(R.id.mgmt_account_publish_avatar).setVisible(false); } + + if (selectedAccount.isOnlineAndConnected()) { + if (!selectedAccount.getXmppConnection().getFeatures().register()) { + menu.findItem(R.id.action_change_password_on_server).setVisible(false); + } + } else { + menu.findItem(R.id.action_change_password_on_server).setVisible(false); + } + menu.setHeaderTitle(this.selectedAccount.getJid().asBareJid().toEscapedString()); } @@ -187,6 +197,9 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda case R.id.mgmt_account_enable: enableAccount(selectedAccount); return true; + case R.id.action_change_password_on_server: + gotoChangePassword(selectedAccount); + return true; case R.id.mgmt_account_delete: deleteAccount(selectedAccount); return true; @@ -376,6 +389,11 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda } } + private void gotoChangePassword(Account selectedAccount) { + final Intent changePasswordIntent = new Intent(this, ChangePasswordActivity.class); + changePasswordIntent.putExtra(EXTRA_ACCOUNT, selectedAccount.getJid().toEscapedString()); + startActivity(changePasswordIntent); + } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationsOverviewFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationsOverviewFragment.java index eebd94df5..b4d408bbd 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationsOverviewFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationsOverviewFragment.java @@ -37,12 +37,14 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.os.Bundle; import android.util.Log; +import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; import android.widget.Toast; import androidx.databinding.DataBindingUtil; @@ -51,6 +53,7 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.snackbar.Snackbar; +import com.google.common.base.Optional; import com.google.common.collect.Collections2; import java.util.ArrayList; @@ -63,6 +66,7 @@ import eu.siacs.conversations.databinding.FragmentConversationsOverviewBinding; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Conversational; +import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.ui.adapter.ConversationAdapter; import eu.siacs.conversations.ui.interfaces.OnConversationArchived; import eu.siacs.conversations.ui.interfaces.OnConversationSelected; @@ -74,6 +78,7 @@ import eu.siacs.conversations.ui.util.StyledAttributes; import eu.siacs.conversations.utils.AccountUtils; import eu.siacs.conversations.utils.EasyOnboardingInvite; import eu.siacs.conversations.utils.ThemeHelper; +import eu.siacs.conversations.xmpp.jingle.OngoingRtpSession; import static androidx.recyclerview.widget.ItemTouchHelper.LEFT; import static androidx.recyclerview.widget.ItemTouchHelper.RIGHT; @@ -299,6 +304,7 @@ public class ConversationsOverviewFragment extends XmppFragment { }); this.binding.list.setAdapter(this.conversationsAdapter); this.binding.list.setLayoutManager(new LinearLayoutManager(getActivity(),LinearLayoutManager.VERTICAL,false)); + registerForContextMenu(this.binding.list); this.touchHelper = new ItemTouchHelper(this.callback); this.touchHelper.attachToRecyclerView(this.binding.list); return binding.getRoot(); @@ -312,6 +318,60 @@ public class ConversationsOverviewFragment extends XmppFragment { easyOnboardInvite.setVisible(EasyOnboardingInvite.anyHasSupport(activity == null ? null : activity.xmppConnectionService)); } + @Override + public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { + activity.getMenuInflater().inflate(R.menu.conversations, menu); + + final MenuItem menuMucDetails = menu.findItem(R.id.action_muc_details); + final MenuItem menuContactDetails = menu.findItem(R.id.action_contact_details); + final MenuItem menuMute = menu.findItem(R.id.action_mute); + final MenuItem menuUnmute = menu.findItem(R.id.action_unmute); + final MenuItem menuOngoingCall = menu.findItem(R.id.action_ongoing_call); + final MenuItem menuTogglePinned = menu.findItem(R.id.action_toggle_pinned); + + Conversation conversation = conversations.get(((AdapterView.AdapterContextMenuInfo) menuInfo).position); + if (conversation != null) { + if (conversation.getMode() == Conversation.MODE_MULTI) { + menuContactDetails.setVisible(false); + menuMucDetails.setTitle(conversation.getMucOptions().isPrivateAndNonAnonymous() ? R.string.action_muc_details : R.string.channel_details); + menuOngoingCall.setVisible(false); + } else { + final XmppConnectionService service = activity == null ? null : activity.xmppConnectionService; + final Optional ongoingRtpSession = service == null ? Optional.absent() : service.getJingleConnectionManager().getOngoingRtpConnection(conversation.getContact()); + if (ongoingRtpSession.isPresent()) { + menuOngoingCall.setVisible(true); + } else { + menuOngoingCall.setVisible(false); + } + menuContactDetails.setVisible(!conversation.withSelf()); + menuMucDetails.setVisible(false); + } + if (conversation.isMuted()) { + menuMute.setVisible(false); + } else { + menuUnmute.setVisible(false); + } + if (conversation.getBooleanAttribute(Conversation.ATTRIBUTE_PINNED_ON_TOP, false)) { + menuTogglePinned.setTitle(R.string.remove_from_favorites); + } else { + menuTogglePinned.setTitle(R.string.add_to_favorites); + } + } + super.onCreateContextMenu(menu, view, menuInfo); + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + Conversation conversation = conversations.get(((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()).position); + ConversationFragment fragment = new ConversationFragment(); + fragment.setHasOptionsMenu(false); + fragment.onAttach(activity); + fragment.reInit(conversation, null); + boolean r = fragment.onOptionsItemSelected(item); + refresh(); + return r; + } + @Override public void onBackendConnected() { refresh(); diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index 9822ac004..57f872fc1 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -312,6 +312,7 @@ public class ConversationAdapter private ConversationViewHolder(ConversationListRowBinding binding) { super(binding.getRoot()); this.binding = binding; + binding.getRoot().setLongClickable(true); } } } diff --git a/src/main/java/eu/siacs/conversations/ui/widget/BaseRecyclerView.kt b/src/main/java/eu/siacs/conversations/ui/widget/BaseRecyclerView.kt new file mode 100644 index 000000000..23bc4a21e --- /dev/null +++ b/src/main/java/eu/siacs/conversations/ui/widget/BaseRecyclerView.kt @@ -0,0 +1,34 @@ +package eu.siacs.conversations.ui.widget + +import android.content.Context +import android.util.AttributeSet +import android.view.ContextMenu.ContextMenuInfo +import android.view.View +import android.widget.AdapterView.AdapterContextMenuInfo +import androidx.recyclerview.widget.RecyclerView + + +class BaseRecyclerView : RecyclerView { + private var adapterContextMenuInfo: AdapterContextMenuInfo? = null + + constructor(context: Context) : super(context) + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( + context, + attrs, + defStyleAttr + ) + + override fun getContextMenuInfo(): ContextMenuInfo? { + return adapterContextMenuInfo + } + + override fun showContextMenuForChild(originalView: View): Boolean { + adapterContextMenuInfo = AdapterContextMenuInfo( + originalView, + getChildAdapterPosition(originalView), + getChildItemId(originalView) + ) + return super.showContextMenuForChild(originalView) + } +} \ No newline at end of file diff --git a/src/main/res/layout/fragment_conversations_overview.xml b/src/main/res/layout/fragment_conversations_overview.xml index e51238e93..60c5966dc 100644 --- a/src/main/res/layout/fragment_conversations_overview.xml +++ b/src/main/res/layout/fragment_conversations_overview.xml @@ -7,7 +7,7 @@ android:layout_height="match_parent"> - + + + + + + + + + diff --git a/src/main/res/menu/manageaccounts_context.xml b/src/main/res/menu/manageaccounts_context.xml index 74ac5d968..962df6364 100644 --- a/src/main/res/menu/manageaccounts_context.xml +++ b/src/main/res/menu/manageaccounts_context.xml @@ -15,6 +15,12 @@ android:id="@+id/mgmt_account_disable" app:showAsAction="never" android:title="@string/mgmt_account_disable"/> + + +