Skip to content
Snippets Groups Projects
Verified Commit 8fdce5ba authored by Torsten Grote's avatar Torsten Grote
Browse files

Group Member List UI

parent 0b11aea7
No related branches found
No related tags found
No related merge requests found
Showing
with 398 additions and 15 deletions
...@@ -128,7 +128,17 @@ ...@@ -128,7 +128,17 @@
android:parentActivityName=".android.NavDrawerActivity"> android:parentActivityName=".android.NavDrawerActivity">
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value=".android.NavDrawerActivity" android:value=".android.NavDrawerActivity"/>
</activity>
<activity
android:name=".android.privategroup.memberlist.GroupMemberListActivity"
android:label="@string/app_name"
android:parentActivityName=".android.privategroup.conversation.GroupActivity"
android:windowSoftInputMode="adjustResize|stateHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.privategroup.conversation.GroupActivity"
/> />
</activity> </activity>
......
<vector android:alpha="0.56" android:height="48dp" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportHeight="24.0" android:viewportWidth="24.0" android:width="48dp"
android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android"> android:height="48dp"
<path android:fillColor="#FF000000" android:pathData="M9.01,14L2,14v2h7.01v3L13,15l-3.99,-4v3zM14.99,13v-3L22,10L22,8h-7.01L14.99,5L11,9l3.99,4z"/> android:alpha="0.54"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M9.01,14L2,14v2h7.01v3L13,15l-3.99,-4v3zM14.99,13v-3L22,10L22,8h-7.01L14.99,5L11,9l3.99,4z"/>
</vector> </vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:alpha="0.54"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M6.99,11L3,15l3.99,4v-3H14v-2H6.99v-3zM21,9l-3.99,-4v3H10v2h7.01v3L21,9z"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:orientation="horizontal"
android:paddingBottom="@dimen/margin_medium"
android:paddingTop="@dimen/margin_medium">
<org.briarproject.android.view.AuthorView
android:id="@+id/authorView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:persona="list"/>
<ImageView
android:id="@+id/sharingView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_sharing"
android:layout_marginLeft="@dimen/margin_medium"
android:contentDescription="@string/forum_invitation_already_sharing"/>
</LinearLayout>
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
<item <item
android:id="@+id/action_group_member_list" android:id="@+id/action_group_member_list"
android:enabled="false"
android:icon="@drawable/ic_group_white" android:icon="@drawable/ic_group_white"
android:title="@string/groups_member_list" android:title="@string/groups_member_list"
app:showAsAction="ifRoom"/> app:showAsAction="ifRoom"/>
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
<enum name="normal" value="0"/> <enum name="normal" value="0"/>
<enum name="reblogger" value="1"/> <enum name="reblogger" value="1"/>
<enum name="commenter" value="2"/> <enum name="commenter" value="2"/>
<enum name="list" value="3"/>
</attr> </attr>
</declare-styleable> </declare-styleable>
......
...@@ -28,21 +28,22 @@ import org.briarproject.android.keyagreement.KeyAgreementActivity; ...@@ -28,21 +28,22 @@ import org.briarproject.android.keyagreement.KeyAgreementActivity;
import org.briarproject.android.keyagreement.ShowQrCodeFragment; import org.briarproject.android.keyagreement.ShowQrCodeFragment;
import org.briarproject.android.panic.PanicPreferencesActivity; import org.briarproject.android.panic.PanicPreferencesActivity;
import org.briarproject.android.panic.PanicResponderActivity; import org.briarproject.android.panic.PanicResponderActivity;
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.conversation.GroupActivity;
import org.briarproject.android.privategroup.creation.CreateGroupMessageFragment; import org.briarproject.android.privategroup.creation.CreateGroupMessageFragment;
import org.briarproject.android.privategroup.list.GroupListFragment;
import org.briarproject.android.privategroup.invitation.GroupInvitationActivity; import org.briarproject.android.privategroup.invitation.GroupInvitationActivity;
import org.briarproject.android.sharing.ShareBlogActivity; import org.briarproject.android.privategroup.list.GroupListFragment;
import org.briarproject.android.privategroup.memberlist.GroupMemberListActivity;
import org.briarproject.android.sharing.BlogInvitationActivity;
import org.briarproject.android.sharing.BlogSharingStatusActivity; import org.briarproject.android.sharing.BlogSharingStatusActivity;
import org.briarproject.android.sharing.ContactSelectorFragment; import org.briarproject.android.sharing.ContactSelectorFragment;
import org.briarproject.android.sharing.BlogInvitationActivity;
import org.briarproject.android.sharing.ForumInvitationActivity; import org.briarproject.android.sharing.ForumInvitationActivity;
import org.briarproject.android.sharing.ShareForumActivity;
import org.briarproject.android.sharing.ShareForumMessageFragment;
import org.briarproject.android.sharing.ForumSharingStatusActivity; import org.briarproject.android.sharing.ForumSharingStatusActivity;
import org.briarproject.android.sharing.ShareBlogActivity;
import org.briarproject.android.sharing.ShareBlogMessageFragment; import org.briarproject.android.sharing.ShareBlogMessageFragment;
import org.briarproject.android.sharing.ShareForumActivity;
import org.briarproject.android.sharing.ShareForumMessageFragment;
import org.thoughtcrime.securesms.components.emoji.EmojiProvider; import org.thoughtcrime.securesms.components.emoji.EmojiProvider;
import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel; import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel;
...@@ -80,6 +81,7 @@ public interface ActivityComponent { ...@@ -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(GroupInvitationActivity activity); void inject(GroupInvitationActivity activity);
void inject(GroupMemberListActivity activity);
void inject(CreateForumActivity activity); void inject(CreateForumActivity activity);
......
...@@ -29,6 +29,8 @@ import org.briarproject.android.privategroup.invitation.GroupInvitationControlle ...@@ -29,6 +29,8 @@ import org.briarproject.android.privategroup.invitation.GroupInvitationControlle
import org.briarproject.android.privategroup.invitation.GroupInvitationControllerImpl; import org.briarproject.android.privategroup.invitation.GroupInvitationControllerImpl;
import org.briarproject.android.privategroup.list.GroupListController; import org.briarproject.android.privategroup.list.GroupListController;
import org.briarproject.android.privategroup.list.GroupListControllerImpl; import org.briarproject.android.privategroup.list.GroupListControllerImpl;
import org.briarproject.android.privategroup.memberlist.GroupMemberListController;
import org.briarproject.android.privategroup.memberlist.GroupMemberListControllerImpl;
import org.briarproject.android.sharing.BlogInvitationController; import org.briarproject.android.sharing.BlogInvitationController;
import org.briarproject.android.sharing.BlogInvitationControllerImpl; import org.briarproject.android.sharing.BlogInvitationControllerImpl;
import org.briarproject.android.sharing.ForumInvitationController; import org.briarproject.android.sharing.ForumInvitationController;
...@@ -131,6 +133,13 @@ public class ActivityModule { ...@@ -131,6 +133,13 @@ public class ActivityModule {
return groupInvitationController; return groupInvitationController;
} }
@ActivityScope
@Provides
protected GroupMemberListController provideGroupMemberListController(
GroupMemberListControllerImpl groupMemberListController) {
return groupMemberListController;
}
@ActivityScope @ActivityScope
@Provides @Provides
protected ForumController provideForumController( protected ForumController provideForumController(
......
...@@ -6,6 +6,8 @@ import android.content.Intent; ...@@ -6,6 +6,8 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.LayoutRes; import android.support.annotation.LayoutRes;
import android.support.annotation.StringRes; import android.support.annotation.StringRes;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
...@@ -16,6 +18,7 @@ import android.view.MenuItem; ...@@ -16,6 +18,7 @@ import android.view.MenuItem;
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.memberlist.GroupMemberListActivity;
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;
...@@ -24,6 +27,7 @@ import org.briarproject.api.privategroup.PrivateGroup; ...@@ -24,6 +27,7 @@ import org.briarproject.api.privategroup.PrivateGroup;
import javax.inject.Inject; import javax.inject.Inject;
import static android.support.v4.app.ActivityOptionsCompat.makeCustomAnimation;
import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_POST_BODY_LENGTH; import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_POST_BODY_LENGTH;
public class GroupActivity extends public class GroupActivity extends
...@@ -133,12 +137,20 @@ public class GroupActivity extends ...@@ -133,12 +137,20 @@ public class GroupActivity extends
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:
Intent i = new Intent(this, GroupMemberListActivity.class);
i.putExtra(GROUP_ID, groupId.getBytes());
i.putExtra(GROUP_NAME, getTitle());
ActivityOptionsCompat options =
makeCustomAnimation(this, android.R.anim.slide_in_left,
android.R.anim.slide_out_right);
ActivityCompat.startActivity(this, i, options.toBundle());
return true;
case R.id.action_group_leave: case R.id.action_group_leave:
showLeaveGroupDialog(); showLeaveGroupDialog();
return true; return true;
case R.id.action_group_dissolve: case R.id.action_group_dissolve:
showDissolveGroupDialog(); showDissolveGroupDialog();
return true;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
......
package org.briarproject.android.privategroup.memberlist;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.view.MenuItem;
import org.briarproject.R;
import org.briarproject.android.ActivityComponent;
import org.briarproject.android.BriarActivity;
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
import org.briarproject.android.view.BriarRecyclerView;
import org.briarproject.api.db.DbException;
import org.briarproject.api.sync.GroupId;
import java.util.Collection;
import javax.inject.Inject;
public class GroupMemberListActivity extends BriarActivity {
@Inject
GroupMemberListController controller;
private MemberListAdapter adapter;
private BriarRecyclerView list;
private GroupId groupId;
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
}
@Override
public void onCreate(final Bundle state) {
super.onCreate(state);
setContentView(R.layout.list);
Intent i = getIntent();
byte[] b = i.getByteArrayExtra(GROUP_ID);
if (b == null) throw new IllegalStateException("No GroupId in intent.");
groupId = new GroupId(b);
String name = i.getStringExtra(GROUP_NAME);
if (name == null) throw new IllegalStateException("No name in intent.");
setTitle(name + " " + getString(R.string.groups_member_list));
list = (BriarRecyclerView) findViewById(R.id.list);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
list.setLayoutManager(linearLayoutManager);
adapter = new MemberListAdapter(this);
list.setAdapter(adapter);
}
@Override
public void onStart() {
super.onStart();
controller.loadMembers(groupId,
new UiResultExceptionHandler<Collection<MemberListItem>, DbException>(this) {
@Override
public void onResultUi(Collection<MemberListItem> members) {
adapter.addAll(members);
}
@Override
public void onExceptionUi(DbException exception) {
// TODO proper error handling
finish();
}
});
list.startPeriodicUpdate();
}
@Override
public void onStop() {
super.onStop();
list.stopPeriodicUpdate();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
package org.briarproject.android.privategroup.memberlist;
import org.briarproject.android.controller.DbController;
import org.briarproject.android.controller.handler.ResultExceptionHandler;
import org.briarproject.api.db.DbException;
import org.briarproject.api.sync.GroupId;
import java.util.Collection;
public interface GroupMemberListController extends DbController {
void loadMembers(GroupId groupId,
ResultExceptionHandler<Collection<MemberListItem>, DbException> handler);
}
package org.briarproject.android.privategroup.memberlist;
import org.briarproject.android.controller.DbControllerImpl;
import org.briarproject.android.controller.handler.ResultExceptionHandler;
import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.db.DbException;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.privategroup.GroupMember;
import org.briarproject.api.privategroup.PrivateGroupManager;
import org.briarproject.api.sync.GroupId;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
public class GroupMemberListControllerImpl extends DbControllerImpl
implements GroupMemberListController {
private static final Logger LOG =
Logger.getLogger(GroupMemberListControllerImpl.class.getName());
private final PrivateGroupManager privateGroupManager;
@Inject
GroupMemberListControllerImpl(@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager,
PrivateGroupManager privateGroupManager) {
super(dbExecutor, lifecycleManager);
this.privateGroupManager = privateGroupManager;
}
@Override
public void loadMembers(final GroupId groupId, final
ResultExceptionHandler<Collection<MemberListItem>, DbException> handler) {
runOnDbThread(new Runnable() {
@Override
public void run() {
try {
Collection<MemberListItem> items = new ArrayList<>();
Collection<GroupMember> members =
privateGroupManager.getMembers(groupId);
for (GroupMember m : members) {
items.add(new MemberListItem(m));
}
handler.onResult(items);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
}
});
}
}
package org.briarproject.android.privategroup.memberlist;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.briarproject.R;
import org.briarproject.android.util.BriarAdapter;
class MemberListAdapter extends
BriarAdapter<MemberListItem, MemberListItemHolder> {
MemberListAdapter(Context context) {
super(context, MemberListItem.class);
}
@Override
public MemberListItemHolder onCreateViewHolder(ViewGroup viewGroup,
int i) {
View v = LayoutInflater.from(ctx).inflate(
R.layout.list_item_group_member, viewGroup, false);
return new MemberListItemHolder(v);
}
@Override
public void onBindViewHolder(MemberListItemHolder ui, int position) {
ui.bind(items.get(position));
}
@Override
public int compare(MemberListItem m1, MemberListItem m2) {
return m1.getMember().getName().compareTo(m2.getMember().getName());
}
@Override
public boolean areContentsTheSame(MemberListItem m1, MemberListItem m2) {
if (m1.isSharing() != m2.isSharing()) return false;
if (m1.getStatus() != m2.getStatus()) return false;
return true;
}
@Override
public boolean areItemsTheSame(MemberListItem m1, MemberListItem m2) {
return m1.getMember().equals(m2.getMember());
}
}
package org.briarproject.android.privategroup.memberlist;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.Author.Status;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.privategroup.GroupMember;
import javax.annotation.concurrent.NotThreadSafe;
@NotThreadSafe
@NotNullByDefault
public class MemberListItem {
private final Author member;
private Status status;
private boolean sharing;
public MemberListItem(GroupMember groupMember) {
this.member = groupMember.getAuthor();
this.sharing = groupMember.isShared();
this.status = groupMember.getStatus();
}
public Author getMember() {
return member;
}
public boolean isSharing() {
return sharing;
}
public Status getStatus() {
return status;
}
}
package org.briarproject.android.privategroup.memberlist;
import android.support.annotation.UiThread;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import org.briarproject.R;
import org.briarproject.android.view.AuthorView;
import org.briarproject.api.nullsafety.NotNullByDefault;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
@UiThread
@NotNullByDefault
class MemberListItemHolder extends RecyclerView.ViewHolder {
private final AuthorView author;
private final ImageView sharing;
MemberListItemHolder(View v) {
super(v);
author = (AuthorView) v.findViewById(R.id.authorView);
sharing = (ImageView) v.findViewById(R.id.sharingView);
}
protected void bind(MemberListItem item) {
author.setAuthor(item.getMember());
author.setAuthorStatus(item.getStatus());
if (item.isSharing()) {
sharing.setVisibility(VISIBLE);
} else {
sharing.setVisibility(INVISIBLE);
}
}
}
...@@ -12,7 +12,6 @@ import android.util.AttributeSet; ...@@ -12,7 +12,6 @@ import android.util.AttributeSet;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
...@@ -136,7 +135,7 @@ public class AuthorView extends RelativeLayout { ...@@ -136,7 +135,7 @@ public class AuthorView extends RelativeLayout {
break; break;
// commenter // commenter
case 2: case 2:
ViewGroup.LayoutParams params = avatar.getLayoutParams(); LayoutParams params = (LayoutParams) avatar.getLayoutParams();
int size = getResources().getDimensionPixelSize( int size = getResources().getDimensionPixelSize(
R.dimen.blogs_avatar_comment_size); R.dimen.blogs_avatar_comment_size);
params.height = size; params.height = size;
...@@ -146,6 +145,25 @@ public class AuthorView extends RelativeLayout { ...@@ -146,6 +145,25 @@ public class AuthorView extends RelativeLayout {
.getDimensionPixelSize(R.dimen.text_size_tiny); .getDimensionPixelSize(R.dimen.text_size_tiny);
authorName.setTextSize(COMPLEX_UNIT_PX, textSize); authorName.setTextSize(COMPLEX_UNIT_PX, textSize);
break; break;
// list
case 3:
date.setVisibility(GONE);
params = (LayoutParams) avatar.getLayoutParams();
size = getResources().getDimensionPixelSize(
R.dimen.listitem_picture_size_small);
params.height = size;
params.width = size;
avatar.setLayoutParams(params);
textSize = getResources()
.getDimensionPixelSize(R.dimen.text_size_medium);
authorName.setTextSize(COMPLEX_UNIT_PX, textSize);
params = (LayoutParams) authorName.getLayoutParams();
params.addRule(CENTER_VERTICAL);
authorName.setLayoutParams(params);
params = (LayoutParams) trustIndicator.getLayoutParams();
params.addRule(CENTER_VERTICAL);
trustIndicator.setLayoutParams(params);
break;
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment