diff --git a/briar-android/res/menu/group_actions.xml b/briar-android/res/menu/group_actions.xml
index 8ebe58a1b..bf575e325 100644
--- a/briar-android/res/menu/group_actions.xml
+++ b/briar-android/res/menu/group_actions.xml
@@ -25,15 +25,12 @@
diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml
index f69c03741..8802b1543 100644
--- a/briar-android/res/values/strings.xml
+++ b/briar-android/res/values/strings.xml
@@ -163,6 +163,8 @@
Member List
Invite Members
Leave Group
+ Confirm Leaving Group
+ Are you sure that you want to leave this group?
Dissolve Group
joined the group.
@@ -180,6 +182,9 @@
You declined the group invitation from %s.
%s accepted your group invitation.
%s declined your group invitation.
+ Confirm Dissolving Group
+ Are you sure that you want to dissolve this group?\n\nAll other members will not be able to continue their conversation and might not receive the latest messages.
+ Dissolve
You don\'t have any forums yet.\n\nWhy don\'t you create a new one yourself by tapping the + icon at the top?\n\nYou can also ask your contacts to share forums with you.
diff --git a/briar-android/src/org/briarproject/android/forum/ForumActivity.java b/briar-android/src/org/briarproject/android/forum/ForumActivity.java
index 36d552473..22c713889 100644
--- a/briar-android/src/org/briarproject/android/forum/ForumActivity.java
+++ b/briar-android/src/org/briarproject/android/forum/ForumActivity.java
@@ -149,11 +149,11 @@ public class ForumActivity extends
OnClickListener okListener = new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- deleteNamedGroup();
+ deleteForum();
}
};
- AlertDialog.Builder builder = new AlertDialog.Builder(
- ForumActivity.this, R.style.BriarDialogTheme);
+ AlertDialog.Builder builder = new AlertDialog.Builder(this,
+ R.style.BriarDialogTheme);
builder.setTitle(getString(R.string.dialog_title_leave_forum));
builder.setMessage(getString(R.string.dialog_message_leave_forum));
builder.setNegativeButton(R.string.dialog_button_leave, okListener);
@@ -161,7 +161,7 @@ public class ForumActivity extends
builder.show();
}
- private void deleteNamedGroup() {
+ private void deleteForum() {
forumController.deleteNamedGroup(
new UiResultExceptionHandler(this) {
@Override
diff --git a/briar-android/src/org/briarproject/android/privategroup/conversation/GroupActivity.java b/briar-android/src/org/briarproject/android/privategroup/conversation/GroupActivity.java
index d17ed8d66..14000ec25 100644
--- a/briar-android/src/org/briarproject/android/privategroup/conversation/GroupActivity.java
+++ b/briar-android/src/org/briarproject/android/privategroup/conversation/GroupActivity.java
@@ -1,10 +1,13 @@
package org.briarproject.android.privategroup.conversation;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.annotation.StringRes;
import android.support.v7.app.ActionBar;
+import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.view.Menu;
import android.view.MenuInflater;
@@ -12,8 +15,10 @@ import android.view.MenuItem;
import org.briarproject.R;
import org.briarproject.android.ActivityComponent;
+import org.briarproject.android.controller.handler.UiResultExceptionHandler;
import org.briarproject.android.threaded.ThreadListActivity;
import org.briarproject.android.threaded.ThreadListController;
+import org.briarproject.api.db.DbException;
import org.briarproject.api.privategroup.GroupMessageHeader;
import org.briarproject.api.privategroup.PrivateGroup;
@@ -22,11 +27,16 @@ import javax.inject.Inject;
import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_POST_BODY_LENGTH;
public class GroupActivity extends
- ThreadListActivity {
+ ThreadListActivity
+ implements OnClickListener {
@Inject
GroupController controller;
+ private boolean isCreator;
+ private MenuItem leaveMenuItem;
+ private MenuItem dissolveMenuItem;
+
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
@@ -58,6 +68,20 @@ public class GroupActivity extends
actionBar.setSubtitle(getString(R.string.groups_created_by,
group.getAuthor().getName()));
}
+ controller.isCreator(group,
+ new UiResultExceptionHandler(this) {
+ @Override
+ public void onResultUi(Boolean isCreator) {
+ GroupActivity.this.isCreator = isCreator;
+ showMenuItems();
+ }
+
+ @Override
+ public void onExceptionUi(DbException exception) {
+ // TODO proper error handling
+ finish();
+ }
+ });
}
@Override
@@ -78,6 +102,10 @@ public class GroupActivity extends
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.group_actions, menu);
+ leaveMenuItem = menu.findItem(R.id.action_group_leave);
+ dissolveMenuItem = menu.findItem(R.id.action_group_dissolve);
+ showMenuItems();
+
return super.onCreateOptionsMenu(menu);
}
@@ -87,6 +115,12 @@ public class GroupActivity extends
case R.id.action_group_compose_message:
showTextInput(null);
return true;
+ case R.id.action_group_leave:
+ showLeaveGroupDialog();
+ return true;
+ case R.id.action_group_dissolve:
+ showDissolveGroupDialog();
+ return true;
default:
return super.onOptionsItemSelected(item);
}
@@ -109,4 +143,53 @@ public class GroupActivity extends
return R.string.groups_message_received;
}
+ private void showMenuItems() {
+ if (leaveMenuItem == null || dissolveMenuItem == null) return;
+ if (isCreator) {
+ leaveMenuItem.setVisible(false);
+ dissolveMenuItem.setVisible(true);
+ } else {
+ leaveMenuItem.setVisible(true);
+ dissolveMenuItem.setVisible(false);
+ }
+ }
+
+ private void showLeaveGroupDialog() {
+ AlertDialog.Builder builder =
+ new AlertDialog.Builder(this, R.style.BriarDialogTheme);
+ builder.setTitle(getString(R.string.groups_leave_dialog_title));
+ builder.setMessage(getString(R.string.groups_leave_dialog_message));
+ builder.setNegativeButton(R.string.dialog_button_leave, this);
+ builder.setPositiveButton(R.string.cancel, null);
+ builder.show();
+ }
+
+ private void showDissolveGroupDialog() {
+ AlertDialog.Builder builder =
+ new AlertDialog.Builder(this, R.style.BriarDialogTheme);
+ builder.setTitle(getString(R.string.groups_dissolve_dialog_title));
+ builder.setMessage(getString(R.string.groups_dissolve_dialog_message));
+ builder.setNegativeButton(R.string.groups_dissolve_button, this);
+ builder.setPositiveButton(R.string.cancel, null);
+ builder.show();
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ controller.deleteNamedGroup(
+ new UiResultExceptionHandler(this) {
+ @Override
+ public void onResultUi(Void v) {
+ // The activity is going to be destroyed by the
+ // GroupRemovedEvent being fired
+ }
+
+ @Override
+ public void onExceptionUi(DbException exception) {
+ // TODO proper error handling
+ finish();
+ }
+ });
+ }
+
}
diff --git a/briar-android/src/org/briarproject/android/privategroup/conversation/GroupController.java b/briar-android/src/org/briarproject/android/privategroup/conversation/GroupController.java
index 0292f2278..1a2fa951e 100644
--- a/briar-android/src/org/briarproject/android/privategroup/conversation/GroupController.java
+++ b/briar-android/src/org/briarproject/android/privategroup/conversation/GroupController.java
@@ -1,6 +1,8 @@
package org.briarproject.android.privategroup.conversation;
+import org.briarproject.android.controller.handler.ResultExceptionHandler;
import org.briarproject.android.threaded.ThreadListController;
+import org.briarproject.api.db.DbException;
import org.briarproject.api.privategroup.GroupMessageHeader;
import org.briarproject.api.privategroup.PrivateGroup;
@@ -8,4 +10,7 @@ public interface GroupController
extends
ThreadListController {
+ void isCreator(PrivateGroup group,
+ ResultExceptionHandler handler);
+
}
diff --git a/briar-android/src/org/briarproject/android/privategroup/conversation/GroupControllerImpl.java b/briar-android/src/org/briarproject/android/privategroup/conversation/GroupControllerImpl.java
index abbf10d42..df366c675 100644
--- a/briar-android/src/org/briarproject/android/privategroup/conversation/GroupControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/privategroup/conversation/GroupControllerImpl.java
@@ -30,6 +30,7 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static java.lang.Math.max;
+
import static java.util.logging.Level.WARNING;
public class GroupControllerImpl extends
@@ -174,4 +175,24 @@ public class GroupControllerImpl extends
return new GroupMessageItem(header, body);
}
+ @Override
+ public void isCreator(final PrivateGroup group,
+ final ResultExceptionHandler handler) {
+ runOnDbThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ LocalAuthor author = identityManager.getLocalAuthor();
+ boolean isCreator =
+ author.getId().equals(group.getAuthor().getId());
+ handler.onResult(isCreator);
+ } catch (DbException e) {
+ if (LOG.isLoggable(WARNING))
+ LOG.log(WARNING, e.toString(), e);
+ handler.onException(e);
+ }
+ }
+ });
+ }
+
}
diff --git a/briar-android/src/org/briarproject/android/threaded/ThreadListControllerImpl.java b/briar-android/src/org/briarproject/android/threaded/ThreadListControllerImpl.java
index 6ea72c892..018188a48 100644
--- a/briar-android/src/org/briarproject/android/threaded/ThreadListControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/threaded/ThreadListControllerImpl.java
@@ -41,16 +41,14 @@ public abstract class ThreadListControllerImpl bodyCache = new ConcurrentHashMap<>();
-
private volatile GroupId groupId;
+ protected final IdentityManager identityManager;
+ protected final AndroidNotificationManager notificationManager;
+ protected final Executor cryptoExecutor;
+ protected final Clock clock;
protected volatile ThreadListListener listener;
protected ThreadListControllerImpl(@DatabaseExecutor Executor dbExecutor,