diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java
index ce2c5b04b..6a12f407d 100644
--- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java
+++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java
@@ -17,40 +17,64 @@ import android.annotation.SuppressLint;
public class MucOptions {
public enum Affiliation {
- OWNER(R.string.owner),
- ADMIN(R.string.admin),
- MEMBER(R.string.member),
- OUTCAST(R.string.outcast),
- NONE(R.string.no_affiliation);
+ OWNER("owner", 4, R.string.owner),
+ ADMIN("admin", 3, R.string.admin),
+ MEMBER("member", 2, R.string.member),
+ OUTCAST("outcast", 0, R.string.outcast),
+ NONE("none", 1, R.string.no_affiliation);
- private Affiliation(int resId) {
+ private Affiliation(String string, int rank, int resId) {
+ this.string = string;
this.resId = resId;
+ this.rank = rank;
}
+ private String string;
private int resId;
+ private int rank;
public int getResId() {
return resId;
}
+
+ @Override
+ public String toString() {
+ return this.string;
+ }
+
+ public boolean outranks(Affiliation affiliation) {
+ return rank > affiliation.rank;
+ }
+
+ public boolean ranks(Affiliation affiliation) {
+ return rank >= affiliation.rank;
+ }
}
;
public enum Role {
- MODERATOR(R.string.moderator),
- VISITOR(R.string.visitor),
- PARTICIPANT(R.string.participant),
- NONE(R.string.no_role);
+ MODERATOR("moderator", R.string.moderator),
+ VISITOR("visitor", R.string.visitor),
+ PARTICIPANT("participant", R.string.participant),
+ NONE("none", R.string.no_role);
- private Role(int resId) {
+ private Role(String string, int resId) {
+ this.string = string;
this.resId = resId;
}
+ private String string;
private int resId;
public int getResId() {
return resId;
}
+
+ @Override
+ public String toString() {
+ return this.string;
+ }
}
public static final int ERROR_NO_ERROR = 0;
diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java
index 58933692f..988b9744b 100644
--- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java
+++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java
@@ -5,6 +5,7 @@ import java.util.Collections;
import java.util.List;
import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.services.MessageArchiveService;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.Xmlns;
@@ -148,4 +149,14 @@ public class IqGenerator extends AbstractGenerator {
query.addChild("password").setContent(newPassword);
return packet;
}
+
+ public IqPacket changeAffiliation(Conversation conference, Jid jid, String affiliation) {
+ IqPacket packet = new IqPacket(IqPacket.TYPE.SET);
+ packet.setTo(conference.getJid().toBareJid());
+ packet.setFrom(conference.getAccount().getJid());
+ Element item = packet.query("http://jabber.org/protocol/muc#admin").addChild("item");
+ item.setAttribute("jid", jid.toString());
+ item.setAttribute("affiliation", affiliation);
+ return packet;
+ }
}
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index 5d314ecf6..4ab2d42b2 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -1516,6 +1516,28 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
});
}
+ public void changeAffiliationInConference(final Conversation conference, Jid user, MucOptions.Affiliation affiliation, final OnAffiliationChanged callback) {
+ final Jid jid = user.toBareJid();
+ IqPacket request = this.mIqGenerator.changeAffiliation(conference, jid, affiliation.toString());
+ Log.d(Config.LOGTAG,request.toString());
+ sendIqPacket(conference.getAccount(),request,new OnIqPacketReceived() {
+ @Override
+ public void onIqPacketReceived(Account account, IqPacket packet) {
+ Log.d(Config.LOGTAG,packet.toString());
+ if (packet.getType() == IqPacket.TYPE.RESULT) {
+ callback.onAffiliationChangedSuccessful(jid);
+ } else {
+ callback.onAffiliationChangeFailed(jid,R.string.could_not_change_affiliation);
+ }
+ }
+ });
+ }
+
+ public interface OnAffiliationChanged {
+ public void onAffiliationChangedSuccessful(Jid jid);
+ public void onAffiliationChangeFailed(Jid jid, int resId);
+ }
+
public void disconnect(Account account, boolean force) {
if ((account.getStatus() == Account.State.ONLINE)
|| (account.getStatus() == Account.State.DISABLED)) {
diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java
index 5a30d7617..41190ef2f 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java
@@ -33,11 +33,13 @@ import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.MucOptions;
import eu.siacs.conversations.entities.MucOptions.User;
+import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.services.XmppConnectionService.OnMucRosterUpdate;
import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate;
+import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
-public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate {
+public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged {
public static final String ACTION_VIEW_MUC = "view_muc";
private Conversation mConversation;
private OnClickListener inviteListener = new OnClickListener() {
@@ -222,21 +224,44 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
if (tag instanceof User) {
getMenuInflater().inflate(R.menu.muc_details_context,menu);
final User user = (User) tag;
+ final User self = mConversation.getMucOptions().getSelf();
this.mSelectedUser = user;
String name;
- final Contact contact = user.getContact();
- if (contact != null) {
- name = contact.getDisplayName();
- } else if (user.getJid() != null) {
- name = user.getJid().toBareJid().toString();
- } else {
- name = user.getName();
- }
- menu.setHeaderTitle(name);
- MenuItem startConversation = menu.findItem(R.id.start_conversation);
- if (user.getJid() == null) {
- startConversation.setVisible(false);
+ if (user.getJid() != null) {
+ final Contact contact = user.getContact();
+ if (contact != null) {
+ name = contact.getDisplayName();
+ } else if (user.getJid() != null) {
+ name = user.getJid().toBareJid().toString();
+ } else {
+ name = user.getName();
+ }
+ menu.setHeaderTitle(name);
+ MenuItem startConversation = menu.findItem(R.id.start_conversation);
+ MenuItem giveMembership = menu.findItem(R.id.give_membership);
+ MenuItem removeMembership = menu.findItem(R.id.remove_membership);
+ MenuItem giveAdminPrivileges = menu.findItem(R.id.give_admin_privileges);
+ MenuItem removeAdminPrivileges = menu.findItem(R.id.remove_admin_privileges);
+ MenuItem removeFromRoom = menu.findItem(R.id.remove_from_room);
+ startConversation.setVisible(true);
+ if (self.getAffiliation().ranks(MucOptions.Affiliation.ADMIN) &&
+ self.getAffiliation().outranks(user.getAffiliation())) {
+ if (mAdvancedMode) {
+ if (user.getAffiliation() == MucOptions.Affiliation.NONE) {
+ giveMembership.setVisible(true);
+ } else {
+ removeMembership.setVisible(true);
+ }
+ }
+ if (user.getAffiliation() != MucOptions.Affiliation.ADMIN) {
+ giveAdminPrivileges.setVisible(true);
+ } else {
+ removeAdminPrivileges.setVisible(true);
+ }
+ removeFromRoom.setVisible(true);
+ }
}
+
}
super.onCreateContextMenu(menu,v,menuInfo);
}
@@ -247,6 +272,21 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
case R.id.start_conversation:
startConversation(mSelectedUser);
return true;
+ case R.id.give_admin_privileges:
+ xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.ADMIN,this);
+ return true;
+ case R.id.give_membership:
+ xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.MEMBER,this);
+ return true;
+ case R.id.remove_membership:
+ xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.NONE,this);
+ return true;
+ case R.id.remove_admin_privileges:
+ xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.MEMBER,this);
+ return true;
+ case R.id.remove_from_room:
+ xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.OUTCAST,this);
+ return true;
default:
return super.onContextItemSelected(item);
}
@@ -399,4 +439,14 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
}
}
}
+
+ @Override
+ public void onAffiliationChangedSuccessful(Jid jid) {
+
+ }
+
+ @Override
+ public void onAffiliationChangeFailed(Jid jid, int resId) {
+
+ }
}
diff --git a/src/main/res/menu/muc_details_context.xml b/src/main/res/menu/muc_details_context.xml
index 113934f3d..ad9f174ad 100644
--- a/src/main/res/menu/muc_details_context.xml
+++ b/src/main/res/menu/muc_details_context.xml
@@ -3,5 +3,26 @@
+ android:visible="false" />
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index bb3586109..d78e135a4 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -411,4 +411,10 @@
Outcast
Member
Advanced mode
+ Grant membership
+ Remove membership
+ Grant admin privileges
+ Remove admin privileges
+ Remove from room
+ Could not change affiliation