aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java34
-rw-r--r--src/main/java/de/pixart/messenger/entities/Conversation.java26
-rw-r--r--src/main/java/de/pixart/messenger/entities/MucOptions.java2
-rw-r--r--src/main/java/de/pixart/messenger/services/XmppConnectionService.java13
-rw-r--r--src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java2
-rw-r--r--src/main/java/de/pixart/messenger/ui/ConversationFragment.java37
-rw-r--r--src/main/java/de/pixart/messenger/ui/StartConversationActivity.java2
-rw-r--r--src/main/java/de/pixart/messenger/ui/util/ConversationMenuConfigurator.java12
-rw-r--r--src/main/java/de/pixart/messenger/ui/util/MucDetailsContextMenuHelper.java11
-rw-r--r--src/main/res/layout/activity_muc_details.xml1
-rw-r--r--src/main/res/menu/muc_details_context.xml68
11 files changed, 94 insertions, 114 deletions
diff --git a/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java b/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java
index 09b3b1320..885db348d 100644
--- a/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java
+++ b/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java
@@ -840,40 +840,6 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
});
}
- public enum AxolotlCapability {
- FULL,
- MISSING_PRESENCE,
- MISSING_KEYS,
- WRONG_CONFIGURATION,
- NO_MEMBERS
- }
-
- public boolean isConversationAxolotlCapable(Conversation conversation) {
- return conversation.isSingleOrPrivateAndNonAnonymous();
- }
-
- public Pair<AxolotlCapability, Jid> isConversationAxolotlCapableDetailed(Conversation conversation) {
- if (conversation.isSingleOrPrivateAndNonAnonymous()) {
- final List<Jid> jids = getCryptoTargets(conversation);
- for (Jid jid : jids) {
- if (!hasAny(jid) && (!deviceIds.containsKey(jid) || deviceIds.get(jid).isEmpty())) {
- if (conversation.getAccount().getRoster().getContact(jid).mutualPresenceSubscription()) {
- return new Pair<>(AxolotlCapability.MISSING_KEYS, jid);
- } else {
- return new Pair<>(AxolotlCapability.MISSING_PRESENCE, jid);
- }
- }
- }
- if (jids.size() > 0) {
- return new Pair<>(AxolotlCapability.FULL, null);
- } else {
- return new Pair<>(AxolotlCapability.NO_MEMBERS, null);
- }
- } else {
- return new Pair<>(AxolotlCapability.WRONG_CONFIGURATION, null);
- }
- }
-
public List<Jid> getCryptoTargets(Conversation conversation) {
final List<Jid> jids;
if (conversation.getMode() == Conversation.MODE_SINGLE) {
diff --git a/src/main/java/de/pixart/messenger/entities/Conversation.java b/src/main/java/de/pixart/messenger/entities/Conversation.java
index ee882ebec..65d9de107 100644
--- a/src/main/java/de/pixart/messenger/entities/Conversation.java
+++ b/src/main/java/de/pixart/messenger/entities/Conversation.java
@@ -64,9 +64,10 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
private static final String ATTRIBUTE_NEXT_MESSAGE_TIMESTAMP = "next_message_timestamp";
private static final String ATTRIBUTE_CRYPTO_TARGETS = "crypto_targets";
private static final String ATTRIBUTE_NEXT_ENCRYPTION = "next_encryption";
- public static final String ATTRIBUTE_MEMBERS_ONLY = "members_only";
- public static final String ATTRIBUTE_MODERATED = "moderated";
- public static final String ATTRIBUTE_NON_ANONYMOUS = "non_anonymous";
+ static final String ATTRIBUTE_MEMBERS_ONLY = "members_only";
+ static final String ATTRIBUTE_MODERATED = "moderated";
+ static final String ATTRIBUTE_NON_ANONYMOUS = "non_anonymous";
+ public static final String ATTRIBUTE_FORMERLY_PRIVATE_NON_ANONYMOUS = "formerly_private_non_anonymous";
protected final ArrayList<Message> messages = new ArrayList<>();
public AtomicBoolean messagesLoaded = new AtomicBoolean(true);
protected Account account = null;
@@ -78,7 +79,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
private int status;
private long created;
private int mode;
- private JSONObject attributes = new JSONObject();
+ private JSONObject attributes;
private Jid nextCounterpart;
private transient SessionImpl otrSession;
private transient String otrFingerprint = null;
@@ -811,7 +812,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
}
- private static boolean suitableForOmemoByDefault(final Conversation conversation) {
+ public static boolean suitableForOmemoByDefault(final Conversation conversation) {
if (conversation.getJid().asBareJid().equals(Config.BUG_REPORTS)) {
return false;
}
@@ -823,12 +824,11 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
if (Config.OMEMO_EXCEPTIONS.CONTACT_DOMAINS.contains(contact) || Config.OMEMO_EXCEPTIONS.ACCOUNT_DOMAINS.contains(account)) {
return false;
}
- final AxolotlService axolotlService = conversation.getAccount().getAxolotlService();
- return axolotlService != null && axolotlService.isConversationAxolotlCapable(conversation);
+ return conversation.isSingleOrPrivateAndNonAnonymous() || conversation.getBooleanAttribute(ATTRIBUTE_FORMERLY_PRIVATE_NON_ANONYMOUS, false);
}
- public void setNextEncryption(int encryption) {
- this.setAttribute(ATTRIBUTE_NEXT_ENCRYPTION, String.valueOf(encryption));
+ public boolean setNextEncryption(int encryption) {
+ return this.setAttribute(ATTRIBUTE_NEXT_ENCRYPTION, encryption);
}
public String getNextMessage() {
@@ -954,15 +954,17 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
}
public boolean setAttribute(String key, boolean value) {
- boolean prev = getBooleanAttribute(key, false);
- setAttribute(key, Boolean.toString(value));
- return prev != value;
+ return setAttribute(key, String.valueOf(value));
}
private boolean setAttribute(String key, long value) {
return setAttribute(key, Long.toString(value));
}
+ private boolean setAttribute(String key, int value) {
+ return setAttribute(key, String.valueOf(value));
+ }
+
public boolean setAttribute(String key, String value) {
synchronized (this.attributes) {
try {
diff --git a/src/main/java/de/pixart/messenger/entities/MucOptions.java b/src/main/java/de/pixart/messenger/entities/MucOptions.java
index 3ab763632..c3050f3fa 100644
--- a/src/main/java/de/pixart/messenger/entities/MucOptions.java
+++ b/src/main/java/de/pixart/messenger/entities/MucOptions.java
@@ -511,7 +511,7 @@ public class MucOptions {
return users;
}
- public String createNameFromParticipants() {
+ String createNameFromParticipants() {
List<User> users = getUsersRelevantForNameAndAvatar();
if (users.size() >= 2) {
StringBuilder builder = new StringBuilder();
diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
index 3b960cdb8..551ff7818 100644
--- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
+++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
@@ -1461,15 +1461,16 @@ public class XmppConnectionService extends Service {
boolean saveInDb = addToConversation;
message.setStatus(Message.STATUS_WAITING);
+ if (message.getEncryption() != Message.ENCRYPTION_NONE && conversation.getMode() == Conversation.MODE_MULTI && conversation.isPrivateAndNonAnonymous()) {
+ if (conversation.setAttribute(Conversation.ATTRIBUTE_FORMERLY_PRIVATE_NON_ANONYMOUS, true)) {
+ databaseBackend.updateConversation(conversation);
+ }
+ }
+
if (!resend && message.getEncryption() != Message.ENCRYPTION_OTR) {
conversation.endOtrIfNeeded();
conversation.findUnsentMessagesWithEncryption(Message.ENCRYPTION_OTR,
- new Conversation.OnMessageFound() {
- @Override
- public void onMessageFound(Message message) {
- markMessage(message, Message.STATUS_SEND_FAILED);
- }
- });
+ message1 -> markMessage(message1, Message.STATUS_SEND_FAILED));
}
if (account.isOnlineAndConnected()) {
diff --git a/src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java b/src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java
index 6f6ab0976..646ab8027 100644
--- a/src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java
@@ -389,6 +389,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.muc_details, menu);
+ final MenuItem share = menu.findItem(R.id.action_share);
+ share.setVisible(mConversation != null && !mConversation.isPrivateAndNonAnonymous());
return super.onCreateOptionsMenu(menu);
}
diff --git a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
index c5fd018e3..946e45fcc 100644
--- a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
+++ b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
@@ -385,7 +385,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
private OnClickListener mHideUnencryptionHint = new OnClickListener() {
@Override
public void onClick(View v) {
- if (Config.supportOmemo() && conversation.getAccount().getAxolotlService().isConversationAxolotlCapable(conversation)) {
+ if (Config.supportOmemo() && Conversation.suitableForOmemoByDefault(conversation) && conversation.isSingleOrPrivateAndNonAnonymous()) {
conversation.setNextEncryption(Message.ENCRYPTION_AXOLOTL);
activity.xmppConnectionService.updateConversation(conversation);
activity.refreshUi();
@@ -1488,38 +1488,43 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
if (conversation == null) {
return;
}
+ final boolean updated;
switch (item.getItemId()) {
case R.id.encryption_choice_none:
- conversation.setNextEncryption(Message.ENCRYPTION_NONE);
+ updated = conversation.setNextEncryption(Message.ENCRYPTION_NONE);
item.setChecked(true);
break;
case R.id.encryption_choice_otr:
- conversation.setNextEncryption(Message.ENCRYPTION_OTR);
+ updated = conversation.setNextEncryption(Message.ENCRYPTION_OTR);
item.setChecked(true);
break;
case R.id.encryption_choice_pgp:
if (activity.hasPgp()) {
if (conversation.getAccount().getPgpSignature() != null) {
- conversation.setNextEncryption(Message.ENCRYPTION_PGP);
+ updated = conversation.setNextEncryption(Message.ENCRYPTION_PGP);
item.setChecked(true);
} else {
+ updated = false;
activity.announcePgp(conversation.getAccount(), conversation, null, activity.onOpenPGPKeyPublished);
}
} else {
activity.showInstallPgpDialog();
+ updated = false;
}
break;
case R.id.encryption_choice_axolotl:
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(conversation.getAccount())
+ "Enabled axolotl for Contact " + conversation.getContact().getJid());
- conversation.setNextEncryption(Message.ENCRYPTION_AXOLOTL);
+ updated = conversation.setNextEncryption(Message.ENCRYPTION_AXOLOTL);
item.setChecked(true);
break;
default:
- conversation.setNextEncryption(Message.ENCRYPTION_NONE);
+ updated = conversation.setNextEncryption(Message.ENCRYPTION_NONE);
break;
}
- activity.xmppConnectionService.updateConversation(conversation);
+ if (updated) {
+ activity.xmppConnectionService.updateConversation(conversation);
+ }
updateChatMsgHint();
getActivity().invalidateOptionsMenu();
activity.refreshUi();
@@ -2445,22 +2450,10 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
&& conversation.isWithStranger()) {
showSnackbar(R.string.received_message_from_stranger, R.string.block, mBlockClickListener);
} else if (activity.xmppConnectionService.warnUnecryptedChat()) {
- AxolotlService axolotlService = account.getAxolotlService();
- if ((mode == Conversation.MODE_SINGLE) && (conversation.getNextEncryption() == Message.ENCRYPTION_NONE &&
- ((Config.supportOmemo() && axolotlService != null && conversation.getAccount().getAxolotlService().isConversationAxolotlCapable(conversation)) ||
- (Config.supportOpenPgp() && account.isPgpDecryptionServiceConnected()) ||
- Config.supportOtr()))) {
- if (ENCRYPTION_EXCEPTIONS.contains(conversation.getJid().toString()) || conversation.getJid().toString().equals(account.getJid().getDomain())) {
- hideSnackbar();
- } else {
- showSnackbar(R.string.conversation_unencrypted_hint, R.string.ok, mHideUnencryptionHint, null);
- }
- } else if ((mode == Conversation.MODE_MULTI && conversation.getMucOptions().membersOnly() && conversation.getMucOptions().nonanonymous()) &&
- (conversation.getNextEncryption() == Message.ENCRYPTION_NONE &&
- ((Config.supportOmemo() && axolotlService != null && conversation.getAccount().getAxolotlService().isConversationAxolotlCapable(conversation)) ||
- (Config.supportOpenPgp() && account.isPgpDecryptionServiceConnected())))) {
+ if (conversation.getNextEncryption() == Message.ENCRYPTION_NONE && conversation.isSingleOrPrivateAndNonAnonymous() && ((Config.supportOmemo() && Conversation.suitableForOmemoByDefault(conversation)) ||
+ (Config.supportOpenPgp() && account.isPgpDecryptionServiceConnected()) || (
+ mode == Conversation.MODE_SINGLE && Config.supportOtr()))) {
if (ENCRYPTION_EXCEPTIONS.contains(conversation.getJid().toString()) || conversation.getJid().toString().equals(account.getJid().getDomain())) {
- Log.d(Config.LOGTAG, "Don't show unencrypted warning because " + conversation.getJid().toString() + " is on exception list");
hideSnackbar();
} else {
showSnackbar(R.string.conversation_unencrypted_hint, R.string.ok, mHideUnencryptionHint, null);
diff --git a/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java b/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java
index 97e1f9fd3..035bbf8d4 100644
--- a/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java
@@ -484,7 +484,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
EnterJidDialog dialog = EnterJidDialog.newInstance(
mActivatedAccounts,
getString(R.string.add_contact),
- getString(R.string.create),
+ getString(R.string.add),
prefilledJid,
null,
invite == null || !invite.hasFingerprints(),
diff --git a/src/main/java/de/pixart/messenger/ui/util/ConversationMenuConfigurator.java b/src/main/java/de/pixart/messenger/ui/util/ConversationMenuConfigurator.java
index dd69b2337..45a1989e7 100644
--- a/src/main/java/de/pixart/messenger/ui/util/ConversationMenuConfigurator.java
+++ b/src/main/java/de/pixart/messenger/ui/util/ConversationMenuConfigurator.java
@@ -101,11 +101,17 @@ public class ConversationMenuConfigurator {
final MenuItem pgp = menu.findItem(R.id.encryption_choice_pgp);
final MenuItem axolotl = menu.findItem(R.id.encryption_choice_axolotl);
+ final int next = conversation.getNextEncryption();
+
boolean visible;
if (OmemoSetting.isAlways()) {
visible = false;
} else if (conversation.getMode() == Conversation.MODE_MULTI) {
- visible = (Config.supportOpenPgp() || Config.supportOmemo()) && Config.multipleEncryptionChoices();
+ if (next == Message.ENCRYPTION_NONE && !conversation.isPrivateAndNonAnonymous() && !conversation.getBooleanAttribute(Conversation.ATTRIBUTE_FORMERLY_PRIVATE_NON_ANONYMOUS, false)) {
+ visible = false;
+ } else {
+ visible = (Config.supportOpenPgp() || Config.supportOmemo()) && Config.multipleEncryptionChoices();
+ }
} else {
visible = Config.multipleEncryptionChoices();
}
@@ -127,10 +133,6 @@ public class ConversationMenuConfigurator {
pgp.setVisible(Config.supportOpenPgp());
none.setVisible(Config.supportUnencrypted() || conversation.getMode() == Conversation.MODE_MULTI);
axolotl.setVisible(Config.supportOmemo());
- final AxolotlService axolotlService = conversation.getAccount().getAxolotlService();
- if (axolotlService == null || !axolotlService.isConversationAxolotlCapable(conversation)) {
- axolotl.setEnabled(false);
- }
switch (conversation.getNextEncryption()) {
case Message.ENCRYPTION_NONE:
none.setChecked(true);
diff --git a/src/main/java/de/pixart/messenger/ui/util/MucDetailsContextMenuHelper.java b/src/main/java/de/pixart/messenger/ui/util/MucDetailsContextMenuHelper.java
index 6e596637c..c5c69577d 100644
--- a/src/main/java/de/pixart/messenger/ui/util/MucDetailsContextMenuHelper.java
+++ b/src/main/java/de/pixart/messenger/ui/util/MucDetailsContextMenuHelper.java
@@ -62,7 +62,10 @@ public final class MucDetailsContextMenuHelper {
MenuItem giveOwnerPrivileges = menu.findItem(R.id.give_owner_privileges);
MenuItem removeOwnerPrivileges = menu.findItem(R.id.revoke_owner_privileges);
MenuItem removeFromRoom = menu.findItem(R.id.remove_from_room);
+ MenuItem managePermisisons = menu.findItem(R.id.manage_permissions);
+ removeFromRoom.setTitle(isGroupChat ? R.string.remove_from_room : R.string.remove_from_channel);
MenuItem banFromConference = menu.findItem(R.id.ban_from_conference);
+ banFromConference.setTitle(isGroupChat ? R.string.ban_from_conference : R.string.ban_from_channel);
MenuItem invite = menu.findItem(R.id.invite);
MenuItem highlightInMuc = menu.findItem(R.id.highlight_in_muc);
startConversation.setVisible(true);
@@ -79,8 +82,10 @@ public final class MucDetailsContextMenuHelper {
} else if (activity instanceof ConferenceDetailsActivity) {
highlightInMuc.setVisible(true);
}
- if (self.getAffiliation().ranks(MucOptions.Affiliation.ADMIN) && self.getAffiliation().outranks(user.getAffiliation())) {
+ boolean managePermissionsVisible = false;
+ if ((self.getAffiliation().ranks(MucOptions.Affiliation.ADMIN) && self.getAffiliation().outranks(user.getAffiliation())) || self.getAffiliation() == MucOptions.Affiliation.OWNER) {
if (advancedMode) {
+ managePermissionsVisible = true;
if (!user.getAffiliation().ranks(MucOptions.Affiliation.MEMBER)) {
giveMembership.setVisible(true);
} else if (user.getAffiliation() == MucOptions.Affiliation.MEMBER) {
@@ -91,12 +96,14 @@ public final class MucDetailsContextMenuHelper {
}
} else {
if (!Config.DISABLE_BAN || conversation.getMucOptions().membersOnly()) {
+ managePermissionsVisible = true;
removeFromRoom.setVisible(true);
}
}
}
if (self.getAffiliation().ranks(MucOptions.Affiliation.OWNER)) {
if (isGroupChat || advancedMode || user.getAffiliation() == MucOptions.Affiliation.OWNER) {
+ managePermissionsVisible = true;
if (!user.getAffiliation().ranks(MucOptions.Affiliation.OWNER)) {
giveOwnerPrivileges.setVisible(true);
} else if (user.getAffiliation() == MucOptions.Affiliation.OWNER) {
@@ -104,6 +111,7 @@ public final class MucDetailsContextMenuHelper {
}
}
if (!isGroupChat || advancedMode || user.getAffiliation() == MucOptions.Affiliation.ADMIN) {
+ managePermissionsVisible = true;
if (!user.getAffiliation().ranks(MucOptions.Affiliation.ADMIN)) {
giveAdminPrivileges.setVisible(true);
} else if (user.getAffiliation() == MucOptions.Affiliation.ADMIN) {
@@ -111,6 +119,7 @@ public final class MucDetailsContextMenuHelper {
}
}
}
+ managePermisisons.setVisible(managePermissionsVisible);
sendPrivateMessage.setVisible(true);
sendPrivateMessage.setEnabled(mucOptions.allowPm());
} else {
diff --git a/src/main/res/layout/activity_muc_details.xml b/src/main/res/layout/activity_muc_details.xml
index 355d5c1d0..9b2b3333c 100644
--- a/src/main/res/layout/activity_muc_details.xml
+++ b/src/main/res/layout/activity_muc_details.xml
@@ -173,7 +173,6 @@
android:layout_centerVertical="true"
android:layout_toStartOf="@+id/change_conference_button"
android:layout_toLeftOf="@+id/change_conference_button"
- android:text="@string/private_conference"
android:textAppearance="@style/TextAppearance.Conversations.Body1" />
<ImageButton
diff --git a/src/main/res/menu/muc_details_context.xml b/src/main/res/menu/muc_details_context.xml
index 373397e62..0a8ad87c4 100644
--- a/src/main/res/menu/muc_details_context.xml
+++ b/src/main/res/menu/muc_details_context.xml
@@ -21,35 +21,41 @@
android:title="@string/send_private_message"
android:visible="false" />
<item
- android:id="@+id/give_membership"
- android:title="@string/grant_membership"
- android:visible="false" />
- <item
- android:id="@+id/remove_membership"
- android:title="@string/remove_membership"
- android:visible="false" />
- <item
- android:id="@+id/give_admin_privileges"
- android:title="@string/grant_admin_privileges"
- android:visible="false" />
- <item
- android:id="@+id/remove_admin_privileges"
- android:title="@string/remove_admin_privileges"
- android:visible="false" />
- <item
- android:id="@+id/give_owner_privileges"
- android:title="@string/grant_owner_privileges"
- android:visible="false" />
- <item
- android:id="@+id/revoke_owner_privileges"
- android:title="@string/remove_owner_privileges"
- android:visible="false" />
- <item
- android:id="@+id/remove_from_room"
- android:title="@string/remove_from_room"
- android:visible="false" />
- <item
- android:id="@+id/ban_from_conference"
- android:title="@string/ban_from_conference"
- android:visible="false" />
+ android:id="@+id/manage_permissions"
+ android:title="@string/manage_permission">
+ <menu>
+ <item
+ android:id="@+id/give_membership"
+ android:title="@string/grant_membership"
+ android:visible="false" />
+ <item
+ android:id="@+id/remove_membership"
+ android:title="@string/remove_membership"
+ android:visible="false" />
+ <item
+ android:id="@+id/give_admin_privileges"
+ android:title="@string/grant_admin_privileges"
+ android:visible="false" />
+ <item
+ android:id="@+id/remove_admin_privileges"
+ android:title="@string/remove_admin_privileges"
+ android:visible="false" />
+ <item
+ android:id="@+id/give_owner_privileges"
+ android:title="@string/grant_owner_privileges"
+ android:visible="false" />
+ <item
+ android:id="@+id/revoke_owner_privileges"
+ android:title="@string/remove_owner_privileges"
+ android:visible="false" />
+ <item
+ android:id="@+id/ban_from_conference"
+ android:title="@string/ban_from_conference"
+ android:visible="false" />
+ <item
+ android:id="@+id/remove_from_room"
+ android:title="@string/remove_from_room"
+ android:visible="false" />
+ </menu>
+ </item>
</menu>