mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 21:29:54 +01:00
Merge branch '722-implement-ux-design-for-inviting-new-members-to-a-group' into 'master'
Implement UX design for inviting new members to a group Closes #722 See merge request !373
This commit is contained in:
@@ -142,6 +142,17 @@
|
|||||||
/>
|
/>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".android.privategroup.creation.GroupInviteActivity"
|
||||||
|
android:label="@string/groups_invite_members"
|
||||||
|
android:parentActivityName=".android.NavDrawerActivity"
|
||||||
|
android:windowSoftInputMode="adjustResize|stateHidden">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
|
android:value=".android.privategroup.conversation.GroupActivity"
|
||||||
|
/>
|
||||||
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".android.sharing.ForumInvitationActivity"
|
android:name=".android.sharing.ForumInvitationActivity"
|
||||||
android:label="@string/forum_invitations_title"
|
android:label="@string/forum_invitations_title"
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_group_invite"
|
android:id="@+id/action_group_invite"
|
||||||
android:enabled="false"
|
|
||||||
android:icon="@drawable/ic_add_white"
|
android:icon="@drawable/ic_add_white"
|
||||||
android:title="@string/groups_invite_members"
|
android:title="@string/groups_invite_members"
|
||||||
app:showAsAction="ifRoom"/>
|
app:showAsAction="ifRoom"/>
|
||||||
|
|||||||
@@ -157,6 +157,7 @@
|
|||||||
<string name="groups_create_group_button">Create Group</string>
|
<string name="groups_create_group_button">Create Group</string>
|
||||||
<string name="groups_create_group_invitation_button">Send Invitation</string>
|
<string name="groups_create_group_invitation_button">Send Invitation</string>
|
||||||
<string name="groups_create_group_hint">Add a name for your private group</string>
|
<string name="groups_create_group_hint">Add a name for your private group</string>
|
||||||
|
<string name="groups_invitation_sent">Group invitation has been sent</string>
|
||||||
<string name="groups_compose_message">Compose Message</string>
|
<string name="groups_compose_message">Compose Message</string>
|
||||||
<string name="groups_message_sent">Message sent</string>
|
<string name="groups_message_sent">Message sent</string>
|
||||||
<string name="groups_message_received">Message received</string>
|
<string name="groups_message_received">Message received</string>
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import org.briarproject.android.privategroup.conversation.GroupActivity;
|
|||||||
import org.briarproject.android.privategroup.creation.CreateGroupActivity;
|
import org.briarproject.android.privategroup.creation.CreateGroupActivity;
|
||||||
import org.briarproject.android.privategroup.creation.CreateGroupFragment;
|
import org.briarproject.android.privategroup.creation.CreateGroupFragment;
|
||||||
import org.briarproject.android.privategroup.creation.CreateGroupMessageFragment;
|
import org.briarproject.android.privategroup.creation.CreateGroupMessageFragment;
|
||||||
|
import org.briarproject.android.privategroup.creation.GroupInviteActivity;
|
||||||
import org.briarproject.android.privategroup.invitation.GroupInvitationActivity;
|
import org.briarproject.android.privategroup.invitation.GroupInvitationActivity;
|
||||||
import org.briarproject.android.privategroup.list.GroupListFragment;
|
import org.briarproject.android.privategroup.list.GroupListFragment;
|
||||||
import org.briarproject.android.privategroup.memberlist.GroupMemberListActivity;
|
import org.briarproject.android.privategroup.memberlist.GroupMemberListActivity;
|
||||||
@@ -80,6 +81,7 @@ public interface ActivityComponent {
|
|||||||
|
|
||||||
void inject(CreateGroupActivity activity);
|
void inject(CreateGroupActivity activity);
|
||||||
void inject(GroupActivity activity);
|
void inject(GroupActivity activity);
|
||||||
|
void inject(GroupInviteActivity activity);
|
||||||
void inject(GroupInvitationActivity activity);
|
void inject(GroupInvitationActivity activity);
|
||||||
void inject(GroupMemberListActivity activity);
|
void inject(GroupMemberListActivity activity);
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import org.briarproject.R;
|
|||||||
import org.briarproject.android.ActivityComponent;
|
import org.briarproject.android.ActivityComponent;
|
||||||
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
||||||
import org.briarproject.android.privategroup.memberlist.GroupMemberListActivity;
|
import org.briarproject.android.privategroup.memberlist.GroupMemberListActivity;
|
||||||
|
import org.briarproject.android.privategroup.creation.GroupInviteActivity;
|
||||||
import org.briarproject.android.threaded.ThreadListActivity;
|
import org.briarproject.android.threaded.ThreadListActivity;
|
||||||
import org.briarproject.android.threaded.ThreadListController;
|
import org.briarproject.android.threaded.ThreadListController;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
@@ -34,6 +35,8 @@ public class GroupActivity extends
|
|||||||
ThreadListActivity<PrivateGroup, GroupMessageItem, GroupMessageHeader>
|
ThreadListActivity<PrivateGroup, GroupMessageItem, GroupMessageHeader>
|
||||||
implements OnClickListener {
|
implements OnClickListener {
|
||||||
|
|
||||||
|
private final static int REQUEST_INVITE = 1;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
GroupController controller;
|
GroupController controller;
|
||||||
|
|
||||||
@@ -133,17 +136,23 @@ public class GroupActivity extends
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||||
|
ActivityOptionsCompat options =
|
||||||
|
makeCustomAnimation(this, android.R.anim.slide_in_left,
|
||||||
|
android.R.anim.slide_out_right);
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.action_group_compose_message:
|
case R.id.action_group_compose_message:
|
||||||
showTextInput(null);
|
showTextInput(null);
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_group_member_list:
|
case R.id.action_group_member_list:
|
||||||
Intent i = new Intent(this, GroupMemberListActivity.class);
|
Intent i1 = new Intent(this, GroupMemberListActivity.class);
|
||||||
i.putExtra(GROUP_ID, groupId.getBytes());
|
i1.putExtra(GROUP_ID, groupId.getBytes());
|
||||||
ActivityOptionsCompat options =
|
ActivityCompat.startActivity(this, i1, options.toBundle());
|
||||||
makeCustomAnimation(this, android.R.anim.slide_in_left,
|
return true;
|
||||||
android.R.anim.slide_out_right);
|
case R.id.action_group_invite:
|
||||||
ActivityCompat.startActivity(this, i, options.toBundle());
|
Intent i2 = new Intent(this, GroupInviteActivity.class);
|
||||||
|
i2.putExtra(GROUP_ID, groupId.getBytes());
|
||||||
|
ActivityCompat.startActivityForResult(this, i2, REQUEST_INVITE,
|
||||||
|
options.toBundle());
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_group_leave:
|
case R.id.action_group_leave:
|
||||||
showLeaveGroupDialog();
|
showLeaveGroupDialog();
|
||||||
@@ -155,6 +164,13 @@ public class GroupActivity extends
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int request, int result, Intent data) {
|
||||||
|
if (request == REQUEST_INVITE && result == RESULT_OK) {
|
||||||
|
displaySnackbarShort(R.string.groups_invitation_sent);
|
||||||
|
} else super.onActivityResult(request, result, data);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getMaxBodyLength() {
|
protected int getMaxBodyLength() {
|
||||||
return MAX_GROUP_POST_BODY_LENGTH;
|
return MAX_GROUP_POST_BODY_LENGTH;
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
package org.briarproject.android.privategroup.creation;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.briarproject.R;
|
||||||
|
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
||||||
|
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
|
||||||
|
import org.briarproject.android.sharing.ContactSelectorActivity;
|
||||||
|
import org.briarproject.api.contact.Contact;
|
||||||
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.db.DatabaseExecutor;
|
||||||
|
import org.briarproject.api.db.DbException;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static android.widget.Toast.LENGTH_SHORT;
|
||||||
|
import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_INVITATION_MSG_LENGTH;
|
||||||
|
|
||||||
|
public abstract class BaseGroupInviteActivity
|
||||||
|
extends ContactSelectorActivity
|
||||||
|
implements MessageFragmentListener {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CreateGroupController controller;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle bundle) {
|
||||||
|
super.onCreate(bundle);
|
||||||
|
|
||||||
|
// Subclasses may initialise the group ID in different places,
|
||||||
|
// restore it if it was saved
|
||||||
|
if (bundle != null) {
|
||||||
|
byte[] groupBytes = bundle.getByteArray(GROUP_ID);
|
||||||
|
if (groupBytes != null) groupId = new GroupId(groupBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
if (groupId != null) {
|
||||||
|
outState.putByteArray(GROUP_ID, groupId.getBytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contactsSelected(GroupId groupId,
|
||||||
|
Collection<ContactId> contacts) {
|
||||||
|
super.contactsSelected(groupId, contacts);
|
||||||
|
|
||||||
|
CreateGroupMessageFragment fragment = new CreateGroupMessageFragment();
|
||||||
|
getSupportFragmentManager().beginTransaction()
|
||||||
|
.setCustomAnimations(android.R.anim.fade_in,
|
||||||
|
android.R.anim.fade_out,
|
||||||
|
android.R.anim.slide_in_left,
|
||||||
|
android.R.anim.slide_out_right)
|
||||||
|
.replace(R.id.fragmentContainer, fragment)
|
||||||
|
.addToBackStack(fragment.getUniqueTag())
|
||||||
|
.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onButtonClick(@NotNull String message) {
|
||||||
|
controller.sendInvitation(groupId, contacts, message,
|
||||||
|
new UiResultExceptionHandler<Void, DbException>(this) {
|
||||||
|
@Override
|
||||||
|
public void onResultUi(Void result) {
|
||||||
|
Toast.makeText(BaseGroupInviteActivity.this,
|
||||||
|
"Inviting members is not yet implemented",
|
||||||
|
LENGTH_SHORT).show();
|
||||||
|
setResult(RESULT_OK);
|
||||||
|
supportFinishAfterTransition();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onExceptionUi(DbException exception) {
|
||||||
|
// TODO proper error handling
|
||||||
|
setResult(RESULT_CANCELED);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaximumMessageLength() {
|
||||||
|
return MAX_GROUP_INVITATION_MSG_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,35 +4,23 @@ import android.content.Intent;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.ActivityCompat;
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.app.ActivityOptionsCompat;
|
import android.support.v4.app.ActivityOptionsCompat;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.ActivityComponent;
|
import org.briarproject.android.ActivityComponent;
|
||||||
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
||||||
import org.briarproject.android.privategroup.conversation.GroupActivity;
|
import org.briarproject.android.privategroup.conversation.GroupActivity;
|
||||||
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
|
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
|
||||||
import org.briarproject.android.sharing.ContactSelectorActivity;
|
|
||||||
import org.briarproject.android.sharing.ContactSelectorFragment;
|
import org.briarproject.android.sharing.ContactSelectorFragment;
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import static android.support.v4.app.ActivityOptionsCompat.makeCustomAnimation;
|
import static android.support.v4.app.ActivityOptionsCompat.makeCustomAnimation;
|
||||||
import static android.widget.Toast.LENGTH_SHORT;
|
|
||||||
import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_INVITATION_MSG_LENGTH;
|
|
||||||
|
|
||||||
public class CreateGroupActivity extends ContactSelectorActivity implements
|
public class CreateGroupActivity extends BaseGroupInviteActivity implements
|
||||||
CreateGroupListener, MessageFragmentListener {
|
CreateGroupListener, MessageFragmentListener {
|
||||||
|
|
||||||
@Inject
|
|
||||||
CreateGroupController controller;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectActivity(ActivityComponent component) {
|
public void injectActivity(ActivityComponent component) {
|
||||||
component.inject(this);
|
component.inject(this);
|
||||||
@@ -42,19 +30,21 @@ public class CreateGroupActivity extends ContactSelectorActivity implements
|
|||||||
public void onCreate(Bundle bundle) {
|
public void onCreate(Bundle bundle) {
|
||||||
super.onCreate(bundle);
|
super.onCreate(bundle);
|
||||||
|
|
||||||
setContentView(R.layout.activity_fragment_container);
|
|
||||||
|
|
||||||
if (bundle == null) {
|
if (bundle == null) {
|
||||||
CreateGroupFragment fragment = new CreateGroupFragment();
|
CreateGroupFragment fragment = new CreateGroupFragment();
|
||||||
getSupportFragmentManager().beginTransaction()
|
getSupportFragmentManager().beginTransaction()
|
||||||
.add(R.id.fragmentContainer, fragment)
|
.add(R.id.fragmentContainer, fragment)
|
||||||
.commit();
|
.commit();
|
||||||
} else {
|
|
||||||
byte[] groupBytes = bundle.getByteArray(GROUP_ID);
|
|
||||||
if (groupBytes != null) groupId = new GroupId(groupBytes);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@DatabaseExecutor
|
||||||
|
public boolean isDisabled(GroupId groupId, Contact c) throws DbException {
|
||||||
|
// contacts can always be invited into a new group
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
|
if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
|
||||||
@@ -66,14 +56,6 @@ public class CreateGroupActivity extends ContactSelectorActivity implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
if (groupId != null) {
|
|
||||||
outState.putByteArray(GROUP_ID, groupId.getBytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGroupNameChosen(String name) {
|
public void onGroupNameChosen(String name) {
|
||||||
controller.createGroup(name,
|
controller.createGroup(name,
|
||||||
@@ -106,53 +88,6 @@ public class CreateGroupActivity extends ContactSelectorActivity implements
|
|||||||
.commit();
|
.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDisabled(GroupId groupId, Contact c) throws DbException {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void contactsSelected(GroupId groupId,
|
|
||||||
Collection<ContactId> contacts) {
|
|
||||||
super.contactsSelected(groupId, contacts);
|
|
||||||
|
|
||||||
CreateGroupMessageFragment fragment = new CreateGroupMessageFragment();
|
|
||||||
getSupportFragmentManager().beginTransaction()
|
|
||||||
.setCustomAnimations(android.R.anim.fade_in,
|
|
||||||
android.R.anim.fade_out,
|
|
||||||
android.R.anim.slide_in_left,
|
|
||||||
android.R.anim.slide_out_right)
|
|
||||||
.replace(R.id.fragmentContainer, fragment)
|
|
||||||
.addToBackStack(fragment.getUniqueTag())
|
|
||||||
.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onButtonClick(@NotNull String message) {
|
|
||||||
controller.sendInvitation(groupId, contacts, message,
|
|
||||||
new UiResultExceptionHandler<Void, DbException>(this) {
|
|
||||||
@Override
|
|
||||||
public void onResultUi(Void result) {
|
|
||||||
Toast.makeText(CreateGroupActivity.this,
|
|
||||||
"Inviting members is not yet implemented",
|
|
||||||
LENGTH_SHORT).show();
|
|
||||||
openNewGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onExceptionUi(DbException exception) {
|
|
||||||
// TODO proper error handling
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMaximumMessageLength() {
|
|
||||||
return MAX_GROUP_INVITATION_MSG_LENGTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void openNewGroup() {
|
private void openNewGroup() {
|
||||||
Intent i = new Intent(this, GroupActivity.class);
|
Intent i = new Intent(this, GroupActivity.class);
|
||||||
i.putExtra(GROUP_ID, groupId.getBytes());
|
i.putExtra(GROUP_ID, groupId.getBytes());
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package org.briarproject.android.privategroup.creation;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import org.briarproject.R;
|
||||||
|
import org.briarproject.android.ActivityComponent;
|
||||||
|
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
|
||||||
|
import org.briarproject.android.sharing.ContactSelectorFragment;
|
||||||
|
import org.briarproject.api.contact.Contact;
|
||||||
|
import org.briarproject.api.db.DatabaseExecutor;
|
||||||
|
import org.briarproject.api.db.DbException;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
|
public class GroupInviteActivity extends BaseGroupInviteActivity
|
||||||
|
implements MessageFragmentListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void injectActivity(ActivityComponent component) {
|
||||||
|
component.inject(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle bundle) {
|
||||||
|
super.onCreate(bundle);
|
||||||
|
|
||||||
|
// Initialise the group ID,
|
||||||
|
// it will be saved and restored by the superclass
|
||||||
|
Intent i = getIntent();
|
||||||
|
byte[] g = i.getByteArrayExtra(GROUP_ID);
|
||||||
|
if (g == null) throw new IllegalStateException("No GroupId in intent.");
|
||||||
|
groupId = new GroupId(g);
|
||||||
|
|
||||||
|
if (bundle == null) {
|
||||||
|
ContactSelectorFragment fragment =
|
||||||
|
ContactSelectorFragment.newInstance(groupId);
|
||||||
|
getSupportFragmentManager().beginTransaction()
|
||||||
|
.replace(R.id.fragmentContainer, fragment)
|
||||||
|
.commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@DatabaseExecutor
|
||||||
|
public boolean isDisabled(GroupId groupId, Contact c) throws DbException {
|
||||||
|
// TODO disable contacts that can not be invited
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user