Create GroupDissolvedEvent and react to it

Also react to incoming group invitations
This commit is contained in:
Torsten Grote
2016-11-07 16:09:07 -02:00
parent 1809943f1d
commit 62040d45b8
12 changed files with 139 additions and 12 deletions

View File

@@ -155,7 +155,7 @@
<item quantity="other">%d messages</item>
</plurals>
<string name="groups_group_is_empty">This group is empty</string>
<string name="groups_group_is_dissolved">This group is dissolved</string>
<string name="groups_group_is_dissolved">This group has been dissolved</string>
<string name="groups_remove">Remove</string>
<string name="groups_create_group_title">Create Private Group</string>
<string name="groups_no_messages">This group is empty.\n\nYou can use the pen icon at the top to compose the first message.</string>
@@ -168,11 +168,16 @@
<string name="groups_message_received">Message received</string>
<string name="groups_member_list">Member List</string>
<string name="groups_invite_members">Invite Members</string>
<string name="groups_member_joined">joined the group.</string>
<string name="groups_leave">Leave Group</string>
<string name="groups_leave_dialog_title">Confirm Leaving Group</string>
<string name="groups_leave_dialog_message">Are you sure that you want to leave this group?</string>
<string name="groups_dissolve">Dissolve Group</string>
<string name="groups_member_joined">joined the group.</string>
<string name="groups_dissolve_dialog_title">Confirm Dissolving Group</string>
<string name="groups_dissolve_dialog_message">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.</string>
<string name="groups_dissolve_button">Dissolve</string>
<string name="groups_dissolved_dialog_title">Group Has Been Dissolved</string>
<string name="groups_dissolved_dialog_message">The creator of this group has dissolved it.\n\nYou can no longer write messages to the group and might not receive all posts that have been written.</string>
<!-- Private Group Invitations -->
<string name="groups_invitations_title">Group Invitations</string>
@@ -188,9 +193,6 @@
<string name="groups_invitations_response_declined_sent">You declined the group invitation from %s.</string>
<string name="groups_invitations_response_accepted_received">%s accepted your group invitation.</string>
<string name="groups_invitations_response_declined_received">%s declined your group invitation.</string>
<string name="groups_dissolve_dialog_title">Confirm Dissolving Group</string>
<string name="groups_dissolve_dialog_message">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.</string>
<string name="groups_dissolve_button">Dissolve</string>
<!-- Forums -->
<string name="no_forums">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.</string>

View File

@@ -4,6 +4,7 @@ import android.support.annotation.Nullable;
import org.briarproject.android.api.AndroidNotificationManager;
import org.briarproject.android.controller.handler.ResultExceptionHandler;
import org.briarproject.android.threaded.ThreadListController.ThreadListListener;
import org.briarproject.android.threaded.ThreadListControllerImpl;
import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.crypto.CryptoExecutor;
@@ -32,7 +33,7 @@ import static java.lang.Math.max;
import static java.util.logging.Level.WARNING;
public class ForumControllerImpl
extends ThreadListControllerImpl<Forum, ForumItem, ForumPostHeader, ForumPost>
extends ThreadListControllerImpl<Forum, ForumItem, ForumPostHeader, ForumPost, ThreadListListener<ForumPostHeader>>
implements ForumController {
private static final Logger LOG =

View File

@@ -18,8 +18,9 @@ import android.view.MenuItem;
import org.briarproject.R;
import org.briarproject.android.ActivityComponent;
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
import org.briarproject.android.privategroup.memberlist.GroupMemberListActivity;
import org.briarproject.android.privategroup.conversation.GroupController.GroupListener;
import org.briarproject.android.privategroup.creation.GroupInviteActivity;
import org.briarproject.android.privategroup.memberlist.GroupMemberListActivity;
import org.briarproject.android.threaded.ThreadListActivity;
import org.briarproject.android.threaded.ThreadListController;
import org.briarproject.api.db.DbException;
@@ -29,11 +30,12 @@ import org.briarproject.api.privategroup.PrivateGroup;
import javax.inject.Inject;
import static android.support.v4.app.ActivityOptionsCompat.makeCustomAnimation;
import static android.view.View.GONE;
import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_POST_BODY_LENGTH;
public class GroupActivity extends
ThreadListActivity<PrivateGroup, GroupMessageItem, GroupMessageHeader>
implements OnClickListener {
implements GroupListener, OnClickListener {
private final static int REQUEST_INVITE = 2;
@@ -200,6 +202,12 @@ public class GroupActivity extends
if (writeMenuItem != null) writeMenuItem.setVisible(enabled);
textInput.setSendButtonEnabled(enabled);
list.getRecyclerView().setAlpha(enabled ? 1f : 0.5f);
if (!enabled) {
textInput.setVisibility(GONE);
if (textInput.isKeyboardOpen()) textInput.hideSoftKeyboard();
if (textInput.isEmojiDrawerOpen()) textInput.hideEmojiDrawer();
}
}
private void showMenuItems() {
@@ -254,4 +262,15 @@ public class GroupActivity extends
});
}
@Override
public void onGroupDissolved() {
setGroupEnabled(false);
AlertDialog.Builder builder =
new AlertDialog.Builder(this, R.style.BriarDialogTheme);
builder.setTitle(getString(R.string.groups_dissolved_dialog_title));
builder.setMessage(getString(R.string.groups_dissolved_dialog_message));
builder.setNeutralButton(R.string.ok, null);
builder.show();
}
}

View File

@@ -1,5 +1,7 @@
package org.briarproject.android.privategroup.conversation;
import android.support.annotation.UiThread;
import org.briarproject.android.controller.handler.ResultExceptionHandler;
import org.briarproject.android.threaded.ThreadListController;
import org.briarproject.api.db.DbException;
@@ -16,4 +18,9 @@ public interface GroupController
void isDissolved(
ResultExceptionHandler<Boolean, DbException> handler);
interface GroupListener extends ThreadListListener<GroupMessageHeader> {
@UiThread
void onGroupDissolved();
}
}

View File

@@ -4,12 +4,14 @@ import android.support.annotation.Nullable;
import org.briarproject.android.api.AndroidNotificationManager;
import org.briarproject.android.controller.handler.ResultExceptionHandler;
import org.briarproject.android.privategroup.conversation.GroupController.GroupListener;
import org.briarproject.android.threaded.ThreadListControllerImpl;
import org.briarproject.api.crypto.CryptoExecutor;
import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.GroupDissolvedEvent;
import org.briarproject.api.event.GroupMessageAddedEvent;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
@@ -34,7 +36,7 @@ import static java.lang.Math.max;
import static java.util.logging.Level.WARNING;
public class GroupControllerImpl extends
ThreadListControllerImpl<PrivateGroup, GroupMessageItem, GroupMessageHeader, GroupMessage>
ThreadListControllerImpl<PrivateGroup, GroupMessageItem, GroupMessageHeader, GroupMessage, GroupListener>
implements GroupController {
private static final Logger LOG =
@@ -78,6 +80,16 @@ public class GroupControllerImpl extends
}
});
}
} else if (e instanceof GroupDissolvedEvent) {
GroupDissolvedEvent g = (GroupDissolvedEvent) e;
if (getGroupId().equals(g.getGroupId())) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() {
@Override
public void run() {
listener.onGroupDissolved();
}
});
}
}
}

View File

@@ -70,4 +70,8 @@ class GroupItem {
return dissolved;
}
void setDissolved() {
dissolved = true;
}
}

View File

@@ -38,11 +38,18 @@ public interface GroupListController extends DbController {
@UiThread
void onGroupMessageAdded(GroupMessageHeader header);
@UiThread
void onGroupInvitationReceived();
@UiThread
void onGroupAdded(GroupId groupId);
@UiThread
void onGroupRemoved(GroupId groupId);
@UiThread
void onGroupDissolved(GroupId groupId);
}
}

View File

@@ -13,6 +13,8 @@ import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.GroupAddedEvent;
import org.briarproject.api.event.GroupDissolvedEvent;
import org.briarproject.api.event.GroupInvitationReceivedEvent;
import org.briarproject.api.event.GroupMessageAddedEvent;
import org.briarproject.api.event.GroupRemovedEvent;
import org.briarproject.api.lifecycle.LifecycleManager;
@@ -89,6 +91,10 @@ public class GroupListControllerImpl extends DbControllerImpl
GroupMessageAddedEvent g = (GroupMessageAddedEvent) e;
LOG.info("Private group message added");
onGroupMessageAdded(g.getHeader());
} else if (e instanceof GroupInvitationReceivedEvent) {
GroupInvitationReceivedEvent g = (GroupInvitationReceivedEvent) e;
LOG.info("Private group invitation received");
onGroupInvitationReceived();
} else if (e instanceof GroupAddedEvent) {
GroupAddedEvent g = (GroupAddedEvent) e;
ClientId id = g.getGroup().getClientId();
@@ -103,6 +109,10 @@ public class GroupListControllerImpl extends DbControllerImpl
LOG.info("Private group removed");
onGroupRemoved(g.getGroup().getId());
}
} else if (e instanceof GroupDissolvedEvent) {
GroupDissolvedEvent g = (GroupDissolvedEvent) e;
LOG.info("Private group dissolved");
onGroupDissolved(g.getGroupId());
}
}
@@ -115,6 +125,15 @@ public class GroupListControllerImpl extends DbControllerImpl
});
}
private void onGroupInvitationReceived() {
listener.runOnUiThreadUnlessDestroyed(new Runnable() {
@Override
public void run() {
listener.onGroupInvitationReceived();
}
});
}
private void onGroupAdded(final GroupId g) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() {
@Override
@@ -133,6 +152,15 @@ public class GroupListControllerImpl extends DbControllerImpl
});
}
private void onGroupDissolved(final GroupId g) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() {
@Override
public void run() {
listener.onGroupDissolved(g);
}
});
}
@Override
public void loadGroups(
final ResultExceptionHandler<Collection<GroupItem>, DbException> handler) {

View File

@@ -151,6 +151,11 @@ public class GroupListFragment extends BaseFragment implements
}
}
@Override
public void onGroupInvitationReceived() {
loadAvailableGroups();
}
@UiThread
@Override
public void onGroupAdded(GroupId groupId) {
@@ -164,6 +169,17 @@ public class GroupListFragment extends BaseFragment implements
adapter.removeItem(groupId);
}
@Override
public void onGroupDissolved(GroupId groupId) {
adapter.incrementRevision();
int position = adapter.findItemPosition(groupId);
GroupItem item = adapter.getItemAt(position);
if (item != null) {
item.setDissolved();
adapter.updateItemAt(position, item);
}
}
@Override
public String getUniqueTag() {
return TAG;

View File

@@ -6,6 +6,7 @@ import android.support.annotation.CallSuper;
import org.briarproject.android.api.AndroidNotificationManager;
import org.briarproject.android.controller.DbControllerImpl;
import org.briarproject.android.controller.handler.ResultExceptionHandler;
import org.briarproject.android.threaded.ThreadListController.ThreadListListener;
import org.briarproject.api.clients.ThreadedMessage;
import org.briarproject.api.clients.NamedGroup;
import org.briarproject.api.clients.PostHeader;
@@ -34,7 +35,7 @@ import java.util.logging.Logger;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends ThreadItem, H extends PostHeader, M extends ThreadedMessage>
public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends ThreadItem, H extends PostHeader, M extends ThreadedMessage, L extends ThreadListListener<H>>
extends DbControllerImpl
implements ThreadListController<G, I, H>, EventListener {
@@ -49,7 +50,7 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
protected final AndroidNotificationManager notificationManager;
protected final Executor cryptoExecutor;
protected final Clock clock;
protected volatile ThreadListListener<H> listener;
protected volatile L listener;
protected ThreadListControllerImpl(@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager, IdentityManager identityManager,
@@ -72,7 +73,7 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
@SuppressWarnings("unchecked")
@Override
public void onActivityCreate(Activity activity) {
listener = (ThreadListListener<H>) activity;
listener = (L) activity;
}
@CallSuper

View File

@@ -0,0 +1,26 @@
package org.briarproject.api.event;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.GroupId;
import javax.annotation.concurrent.Immutable;
/**
* An event that is broadcast when a private group was dissolved
* by a remote creator.
*/
@Immutable
@NotNullByDefault
public class GroupDissolvedEvent extends Event {
private final GroupId groupId;
public GroupDissolvedEvent(GroupId groupId) {
this.groupId = groupId;
}
public GroupId getGroupId() {
return groupId;
}
}

View File

@@ -10,6 +10,8 @@ import org.briarproject.api.data.MetadataParser;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.GroupDissolvedEvent;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.Author.Status;
import org.briarproject.api.identity.AuthorId;
@@ -176,6 +178,8 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
} catch (FormatException e) {
throw new DbException(e);
}
Event e = new GroupDissolvedEvent(g);
txn.attach(e);
}
@Override