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

Add visibility and OPTIONS button to private group join notices

parent c4a152b5
No related branches found
No related tags found
No related merge requests found
Showing
with 359 additions and 113 deletions
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_medium"
android:baselineAligned="false"
android:orientation="vertical">
<View
android:id="@+id/top_divider"
style="@style/Divider.ForumList"
android:layout_alignParentTop="true"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/top_divider"
android:layout_marginBottom="@dimen/margin_small"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:layout_marginTop="@dimen/margin_medium"
android:textColor="@color/briar_text_secondary"
android:textSize="@dimen/text_size_medium"
android:textStyle="italic"
tools:text="@string/groups_member_joined"/>
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/text"
android:layout_below="@+id/text"
android:layout_marginRight="@dimen/margin_small"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_visibility"/>
<TextView
android:id="@+id/info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/text"
android:layout_alignRight="@+id/text"
android:layout_below="@+id/text"
android:layout_marginBottom="@dimen/margin_small"
android:layout_toRightOf="@+id/icon"
android:gravity="center_vertical"
android:textColor="@color/briar_text_secondary"
android:textIsSelectable="true"
android:textSize="@dimen/text_size_small"
android:textStyle="italic"
tools:text="@string/groups_reveal_visible_revealed_by_contact"/>
<org.briarproject.android.view.AuthorView
android:id="@+id/author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/text"
android:layout_below="@+id/info"
android:paddingBottom="@dimen/margin_medium"
app:persona="commenter"/>
<Button
android:id="@+id/optionsButton"
style="@style/BriarButtonFlat.Positive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/author"
android:layout_alignEnd="@+id/text"
android:layout_alignRight="@+id/text"
android:layout_toRightOf="@+id/author"
android:gravity="right"
android:text="@string/options"/>
</RelativeLayout>
......@@ -70,16 +70,14 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginBottom="@dimen/margin_medium"
android:layout_weight="1">
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/margin_small"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:layout_marginTop="@dimen/margin_medium"
android:layout_margin="@dimen/margin_medium"
android:textIsSelectable="true"
android:textSize="@dimen/text_size_medium"
android:textColor="@color/briar_text_primary"
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_medium"
android:baselineAligned="false"
android:orientation="vertical">
<View
android:id="@+id/top_divider"
style="@style/Divider.ForumList"
android:layout_width="match_parent"
android:layout_height="@dimen/margin_separator"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/margin_small"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:layout_marginTop="@dimen/margin_medium"
android:orientation="horizontal">
<org.briarproject.android.view.AuthorView
android:id="@+id/author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:persona="commenter"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="@dimen/margin_medium"
android:gravity="center_vertical"
android:textColor="@color/briar_text_secondary"
android:textIsSelectable="true"
android:textSize="@dimen/text_size_medium"
android:textStyle="italic"
tools:text="@string/groups_member_joined"/>
</LinearLayout>
</LinearLayout>
......@@ -74,6 +74,7 @@
<string name="delete">Delete</string>
<string name="accept">Accept</string>
<string name="decline">Decline</string>
<string name="options">Options</string>
<string name="online">Online</string>
<string name="offline">Offline</string>
<string name="send">Send</string>
......@@ -169,7 +170,10 @@
<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_member_created_you">You created the group</string>
<string name="groups_member_created">%s created the group</string>
<string name="groups_member_joined_you">You joined the group</string>
<string name="groups_member_joined">%s 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>
......
......@@ -5,6 +5,7 @@ import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityOptionsCompat;
......@@ -26,6 +27,8 @@ import org.briarproject.android.threaded.ThreadListController;
import org.briarproject.api.db.DbException;
import org.briarproject.api.forum.Forum;
import org.briarproject.api.forum.ForumPostHeader;
import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
import javax.inject.Inject;
......@@ -35,8 +38,10 @@ import static android.support.v4.app.ActivityOptionsCompat.makeCustomAnimation;
import static android.widget.Toast.LENGTH_SHORT;
import static org.briarproject.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class ForumActivity extends
ThreadListActivity<Forum, ForumItem, ForumPostHeader> {
ThreadListActivity<Forum, ThreadItemAdapter<ForumItem>, ForumItem, ForumPostHeader> {
private static final int REQUEST_FORUM_SHARED = 3;
......@@ -54,7 +59,7 @@ public class ForumActivity extends
}
@Override
public void onCreate(Bundle state) {
public void onCreate(@Nullable Bundle state) {
super.onCreate(state);
Intent i = getIntent();
......
package org.briarproject.android.privategroup;
import android.support.annotation.StringRes;
import org.briarproject.R;
import org.briarproject.api.privategroup.Visibility;
public class VisibilityStringProvider {
@StringRes
public static int getVisibilityString(Visibility v) {
switch (v) {
case VISIBLE:
return R.string.groups_reveal_visible;
case REVEALED_BY_US:
return R.string.groups_reveal_visible_revealed_by_us;
case REVEALED_BY_CONTACT:
return R.string.groups_reveal_visible_revealed_by_contact;
case INVISIBLE:
return R.string.groups_reveal_invisible;
default:
throw new IllegalArgumentException("Unknown visibility");
}
}
}
......@@ -5,6 +5,7 @@ import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityOptionsCompat;
......@@ -26,10 +27,13 @@ import org.briarproject.android.privategroup.reveal.RevealContactsActivity;
import org.briarproject.android.threaded.ThreadListActivity;
import org.briarproject.android.threaded.ThreadListController;
import org.briarproject.api.db.DbException;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.api.privategroup.GroupMessageHeader;
import org.briarproject.api.privategroup.PrivateGroup;
import org.briarproject.api.privategroup.Visibility;
import javax.inject.Inject;
......@@ -40,7 +44,7 @@ import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class GroupActivity extends
ThreadListActivity<PrivateGroup, GroupMessageItem, GroupMessageHeader>
ThreadListActivity<PrivateGroup, GroupMessageAdapter<GroupMessageItem>, GroupMessageItem, GroupMessageHeader>
implements GroupListener, OnClickListener {
private final static int REQUEST_INVITE = 2;
......@@ -63,7 +67,7 @@ public class GroupActivity extends
}
@Override
public void onCreate(Bundle state) {
public void onCreate(@Nullable Bundle state) {
super.onCreate(state);
Intent i = getIntent();
......@@ -81,9 +85,9 @@ public class GroupActivity extends
}
@Override
protected GroupMessageAdapter createAdapter(
protected GroupMessageAdapter<GroupMessageItem> createAdapter(
LinearLayoutManager layoutManager) {
return new GroupMessageAdapter(this, layoutManager);
return new GroupMessageAdapter<>(this, layoutManager);
}
@Override
......@@ -105,7 +109,7 @@ public class GroupActivity extends
}
@Override
protected void onNamedGroupLoaded(PrivateGroup group) {
protected void onNamedGroupLoaded(final PrivateGroup group) {
setTitle(group.getName());
// Created by
ActionBar actionBar = getSupportActionBar();
......@@ -113,11 +117,12 @@ public class GroupActivity extends
actionBar.setSubtitle(getString(R.string.groups_created_by,
group.getCreator().getName()));
}
controller.isCreator(group,
new UiResultExceptionHandler<Boolean, DbException>(this) {
controller.loadLocalAuthor(
new UiResultExceptionHandler<LocalAuthor, DbException>(this) {
@Override
public void onResultUi(Boolean isCreator) {
GroupActivity.this.isCreator = isCreator;
public void onResultUi(LocalAuthor author) {
isCreator = group.getCreator().equals(author);
adapter.setPerspective(isCreator);
showMenuItems();
}
......@@ -272,6 +277,11 @@ public class GroupActivity extends
});
}
@Override
public void onContactRelationshipRevealed(AuthorId memberId, Visibility v) {
adapter.updateVisibility(memberId, v);
}
@Override
public void onGroupDissolved() {
setGroupEnabled(false);
......
......@@ -5,20 +5,26 @@ import android.support.annotation.UiThread;
import org.briarproject.android.controller.handler.ResultExceptionHandler;
import org.briarproject.android.threaded.ThreadListController;
import org.briarproject.api.db.DbException;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.privategroup.GroupMessageHeader;
import org.briarproject.api.privategroup.PrivateGroup;
import org.briarproject.api.privategroup.Visibility;
public interface GroupController
extends
ThreadListController<PrivateGroup, GroupMessageItem, GroupMessageHeader> {
void isCreator(PrivateGroup group,
ResultExceptionHandler<Boolean, DbException> handler);
void loadLocalAuthor(
ResultExceptionHandler<LocalAuthor, DbException> handler);
void isDissolved(
ResultExceptionHandler<Boolean, DbException> handler);
interface GroupListener extends ThreadListListener<GroupMessageHeader> {
@UiThread
void onContactRelationshipRevealed(AuthorId memberId, Visibility v);
@UiThread
void onGroupDissolved();
}
......
......@@ -16,6 +16,7 @@ import org.briarproject.api.event.GroupMessageAddedEvent;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.privategroup.ContactRelationshipRevealedEvent;
import org.briarproject.api.privategroup.GroupMessage;
import org.briarproject.api.privategroup.GroupMessageFactory;
import org.briarproject.api.privategroup.GroupMessageHeader;
......@@ -32,7 +33,6 @@ 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
......@@ -80,6 +80,18 @@ public class GroupControllerImpl extends
}
});
}
} else if (e instanceof ContactRelationshipRevealedEvent) {
final ContactRelationshipRevealedEvent c =
(ContactRelationshipRevealedEvent) e;
if (getGroupId().equals(c.getGroupId())) {
listener.runOnUiThreadUnlessDestroyed(new Runnable() {
@Override
public void run() {
listener.onContactRelationshipRevealed(c.getMemberId(),
c.getVisibility());
}
});
}
} else if (e instanceof GroupDissolvedEvent) {
GroupDissolvedEvent g = (GroupDissolvedEvent) e;
if (getGroupId().equals(g.getGroupId())) {
......@@ -182,22 +194,20 @@ public class GroupControllerImpl extends
protected GroupMessageItem buildItem(GroupMessageHeader header,
String body) {
if (header instanceof JoinMessageHeader) {
return new JoinMessageItem(header, body);
return new JoinMessageItem((JoinMessageHeader) header, body);
}
return new GroupMessageItem(header, body);
}
@Override
public void isCreator(final PrivateGroup group,
final ResultExceptionHandler<Boolean, DbException> handler) {
public void loadLocalAuthor(
final ResultExceptionHandler<LocalAuthor, DbException> handler) {
runOnDbThread(new Runnable() {
@Override
public void run() {
try {
LocalAuthor author = identityManager.getLocalAuthor();
boolean isCreator =
author.getId().equals(group.getCreator().getId());
handler.onResult(isCreator);
handler.onResult(author);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
......
......@@ -11,11 +11,20 @@ import org.briarproject.R;
import org.briarproject.android.threaded.BaseThreadItemViewHolder;
import org.briarproject.android.threaded.ThreadItemAdapter;
import org.briarproject.android.threaded.ThreadPostViewHolder;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.privategroup.Visibility;
import static android.support.v7.widget.RecyclerView.NO_POSITION;
@UiThread
public class GroupMessageAdapter extends ThreadItemAdapter<GroupMessageItem> {
@NotNullByDefault
public class GroupMessageAdapter<I extends GroupMessageItem>
extends ThreadItemAdapter<I> {
private boolean isCreator = false;
public GroupMessageAdapter(ThreadItemListener<GroupMessageItem> listener,
public GroupMessageAdapter(ThreadItemListener<I> listener,
LinearLayoutManager layoutManager) {
super(listener, layoutManager);
}
......@@ -29,14 +38,41 @@ public class GroupMessageAdapter extends ThreadItemAdapter<GroupMessageItem> {
}
@Override
public BaseThreadItemViewHolder<GroupMessageItem> onCreateViewHolder(
public BaseThreadItemViewHolder<I> onCreateViewHolder(
ViewGroup parent, int type) {
View v = LayoutInflater.from(parent.getContext())
.inflate(type, parent, false);
if (type == R.layout.list_item_thread_notice) {
return new JoinMessageItemViewHolder(v);
if (type == R.layout.list_item_group_join_notice) {
return (BaseThreadItemViewHolder<I>)
new JoinMessageItemViewHolder(v, isCreator);
}
return new ThreadPostViewHolder<>(v);
}
void setPerspective(boolean isCreator) {
this.isCreator = isCreator;
notifyDataSetChanged();
}
void updateVisibility(AuthorId memberId, Visibility v) {
int position = findItemPosition(memberId);
if (position != NO_POSITION) {
GroupMessageItem item = items.get(position);
if (item instanceof JoinMessageItem) {
((JoinMessageItem) item).setVisibility(v);
notifyItemChanged(position, item);
}
}
}
private int findItemPosition(AuthorId a) {
int count = items.size();
for (int i = 0; i < count; i++) {
I item = items.get(i);
if (item.getAuthor().getId().equals(a))
return i;
}
return NO_POSITION; // Not found
}
}
......@@ -8,6 +8,7 @@ import org.briarproject.android.threaded.ThreadItem;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.Author.Status;
import org.briarproject.api.privategroup.GroupMessageHeader;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import javax.annotation.concurrent.NotThreadSafe;
......@@ -16,15 +17,23 @@ import javax.annotation.concurrent.NotThreadSafe;
@NotThreadSafe
class GroupMessageItem extends ThreadItem {
private GroupMessageItem(MessageId messageId, MessageId parentId,
private final GroupId groupId;
private GroupMessageItem(MessageId messageId, GroupId groupId,
MessageId parentId,
String text, long timestamp, Author author, Status status,
boolean isRead) {
super(messageId, parentId, text, timestamp, author, status, isRead);
this.groupId = groupId;
}
GroupMessageItem(GroupMessageHeader h, String text) {
this(h.getId(), h.getParentId(), text, h.getTimestamp(), h.getAuthor(),
h.getAuthorStatus(), h.isRead());
this(h.getId(), h.getGroupId(), h.getParentId(), text, h.getTimestamp(),
h.getAuthor(), h.getAuthorStatus(), h.isRead());
}
public GroupId getGroupId() {
return groupId;
}
@LayoutRes
......
......@@ -4,7 +4,8 @@ import android.support.annotation.LayoutRes;
import android.support.annotation.UiThread;
import org.briarproject.R;
import org.briarproject.api.privategroup.GroupMessageHeader;
import org.briarproject.api.privategroup.JoinMessageHeader;
import org.briarproject.api.privategroup.Visibility;
import javax.annotation.concurrent.NotThreadSafe;
......@@ -12,9 +13,14 @@ import javax.annotation.concurrent.NotThreadSafe;
@NotThreadSafe
class JoinMessageItem extends GroupMessageItem {
JoinMessageItem(GroupMessageHeader h,
private Visibility visibility;
private final boolean isInitial;
JoinMessageItem(JoinMessageHeader h,
String text) {
super(h, text);
this.visibility = h.getVisibility();
this.isInitial = h.isInitial();
}
@Override
......@@ -29,7 +35,19 @@ class JoinMessageItem extends GroupMessageItem {
@LayoutRes
public int getLayout() {
return R.layout.list_item_thread_notice;
return R.layout.list_item_group_join_notice;
}
public Visibility getVisibility() {
return visibility;
}
public void setVisibility(Visibility visibility) {
this.visibility = visibility;
}
public boolean isInitial() {
return isInitial;
}
}
package org.briarproject.android.privategroup.conversation;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.UiThread;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import org.briarproject.R;
import org.briarproject.android.privategroup.reveal.RevealContactsActivity;
import org.briarproject.android.threaded.BaseThreadItemViewHolder;
import org.briarproject.android.threaded.ThreadItemAdapter;
import org.briarproject.android.threaded.ThreadItemAdapter.ThreadItemListener;
import org.briarproject.api.nullsafety.NotNullByDefault;
import static org.briarproject.android.BriarActivity.GROUP_ID;
import static org.briarproject.android.privategroup.VisibilityStringProvider.getVisibilityString;
import static org.briarproject.api.identity.Author.Status.OURSELVES;
import static org.briarproject.api.identity.Author.Status.UNKNOWN;
import static org.briarproject.api.privategroup.Visibility.INVISIBLE;
@UiThread
@NotNullByDefault
public class JoinMessageItemViewHolder
extends BaseThreadItemViewHolder<GroupMessageItem> {
extends BaseThreadItemViewHolder<JoinMessageItem> {
private final boolean isCreator;
private final ImageView icon;
private final TextView info;
private final Button options;
public JoinMessageItemViewHolder(View v) {
public JoinMessageItemViewHolder(View v, boolean isCreator) {
super(v);
this.isCreator = isCreator;
icon = (ImageView) v.findViewById(R.id.icon);
info = (TextView) v.findViewById(R.id.info);
options = (Button) v.findViewById(R.id.optionsButton);
}
@Override
public void bind(final ThreadItemAdapter<GroupMessageItem> adapter,
final ThreadItemListener<GroupMessageItem> listener,
final GroupMessageItem item, int pos) {
public void bind(ThreadItemAdapter<JoinMessageItem> adapter,
ThreadItemListener<JoinMessageItem> listener, JoinMessageItem item,
int pos) {
super.bind(adapter, listener, item, pos);
textView.setText(getContext().getString(R.string.groups_member_joined));
if (isCreator) bindForCreator(item);
else bind(item);
}
private void bindForCreator(final JoinMessageItem item) {
if (item.isInitial()) {
textView.setText(
getContext().getString(R.string.groups_member_created_you));
} else {
textView.setText(
getContext().getString(R.string.groups_member_joined,
item.getAuthor().getName()));
}
icon.setVisibility(View.GONE);
info.setVisibility(View.GONE);
options.setVisibility(View.GONE);
}
private void bind(final JoinMessageItem item) {
final Context ctx = getContext();
if (item.isInitial()) {
textView.setText(ctx.getString(R.string.groups_member_created,
item.getAuthor().getName()));
} else {
if (item.getStatus() == OURSELVES) {
textView.setText(
ctx.getString(R.string.groups_member_joined_you));
} else {
textView.setText(ctx.getString(R.string.groups_member_joined,
item.getAuthor().getName()));
}
}
if (item.getStatus() == OURSELVES || item.getStatus() == UNKNOWN) {
icon.setVisibility(View.GONE);
info.setVisibility(View.GONE);
options.setVisibility(View.GONE);
} else {
icon.setVisibility(View.VISIBLE);
info.setVisibility(View.VISIBLE);
info.setText(getVisibilityString(item.getVisibility()));
if (item.getVisibility() == INVISIBLE) {
icon.setImageResource(R.drawable.ic_visibility_off);
options.setVisibility(View.VISIBLE);
options.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i =
new Intent(ctx, RevealContactsActivity.class);
i.putExtra(GROUP_ID, item.getGroupId().getBytes());
ctx.startActivity(i);
}
});
} else {
icon.setImageResource(R.drawable.ic_visibility);
options.setVisibility(View.GONE);
}
}
}
}
......@@ -10,6 +10,7 @@ import org.briarproject.android.contactselection.BaseSelectableContactHolder;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.jetbrains.annotations.Nullable;
import static org.briarproject.android.privategroup.VisibilityStringProvider.getVisibilityString;
import static org.briarproject.android.util.AndroidUtils.GREY_OUT;
import static org.briarproject.api.privategroup.Visibility.INVISIBLE;
......@@ -31,21 +32,7 @@ public class RevealableContactViewHolder
OnContactClickListener<RevealableContactItem> listener) {
super.bind(item, listener);
switch (item.getVisibility()) {
case VISIBLE:
info.setText(R.string.groups_reveal_visible);
break;
case REVEALED_BY_US:
info.setText(R.string.groups_reveal_visible_revealed_by_us);
break;
case REVEALED_BY_CONTACT:
info.setText(
R.string.groups_reveal_visible_revealed_by_contact);
break;
case INVISIBLE:
info.setText(R.string.groups_reveal_invisible);
break;
}
info.setText(getVisibilityString(item.getVisibility()));
if (item.getVisibility() == INVISIBLE) {
icon.setImageResource(R.drawable.ic_visibility_off);
......
......@@ -27,7 +27,7 @@ public class ThreadItemAdapter<I extends ThreadItem>
static final int UNDEFINED = -1;
private final NestedTreeList<I> items = new NestedTreeList<>();
protected final NestedTreeList<I> items = new NestedTreeList<>();
private final Map<I, ValueAnimator> animatingItems = new HashMap<>();
private final ThreadItemListener<I> listener;
private final LinearLayoutManager layoutManager;
......@@ -61,6 +61,11 @@ public class ThreadItemAdapter<I extends ThreadItem>
ui.bind(this, listener, item, position);
}
/**
* Contrary to the super class adapter,
* this returns the number of <b>visible</b> items,
* not all items in the dataset.
*/
@Override
public int getItemCount() {
return getVisiblePos(null);
......
......@@ -24,6 +24,8 @@ import org.briarproject.android.view.TextInputView.TextInputListener;
import org.briarproject.api.clients.NamedGroup;
import org.briarproject.api.clients.PostHeader;
import org.briarproject.api.db.DbException;
import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import org.briarproject.util.StringUtils;
......@@ -35,7 +37,9 @@ import static android.support.design.widget.Snackbar.make;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadItem, H extends PostHeader>
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public abstract class ThreadListActivity<G extends NamedGroup, A extends ThreadItemAdapter<I>, I extends ThreadItem, H extends PostHeader>
extends BriarActivity
implements ThreadListListener<H>, TextInputListener,
ThreadItemListener<I> {
......@@ -46,7 +50,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
private static final Logger LOG =
Logger.getLogger(ThreadListActivity.class.getName());
protected ThreadItemAdapter<I> adapter;
protected A adapter;
protected BriarRecyclerView list;
protected TextInputView textInput;
protected GroupId groupId;
......@@ -57,7 +61,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
@CallSuper
@Override
@SuppressWarnings("ConstantConditions")
public void onCreate(final Bundle state) {
public void onCreate(@Nullable Bundle state) {
super.onCreate(state);
setContentView(getLayout());
......@@ -88,8 +92,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
@LayoutRes
protected abstract int getLayout();
protected abstract ThreadItemAdapter<I> createAdapter(
LinearLayoutManager layoutManager);
protected abstract A createAdapter(LinearLayoutManager layoutManager);
protected void loadNamedGroup() {
getController().loadNamedGroup(
......
package org.briarproject.api.privategroup;
import org.briarproject.api.event.Event;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.GroupId;
......@@ -11,11 +12,13 @@ import javax.annotation.concurrent.Immutable;
public class ContactRelationshipRevealedEvent extends Event {
private final GroupId groupId;
private final AuthorId memberId;
private final Visibility visibility;
public ContactRelationshipRevealedEvent(GroupId groupId,
public ContactRelationshipRevealedEvent(GroupId groupId, AuthorId memberId,
Visibility visibility) {
this.groupId = groupId;
this.memberId = memberId;
this.visibility = visibility;
}
......@@ -23,6 +26,10 @@ public class ContactRelationshipRevealedEvent extends Event {
return groupId;
}
public AuthorId getMemberId() {
return memberId;
}
public Visibility getVisibility() {
return visibility;
}
......
......@@ -9,15 +9,21 @@ import javax.annotation.concurrent.Immutable;
public class JoinMessageHeader extends GroupMessageHeader {
private final Visibility visibility;
private final boolean isCreator;
public JoinMessageHeader(GroupMessageHeader h, Visibility visibility) {
public JoinMessageHeader(GroupMessageHeader h, Visibility visibility, boolean isCreator) {
super(h.getGroupId(), h.getId(), h.getParentId(), h.getTimestamp(),
h.getAuthor(), h.getAuthorStatus(), h.isRead());
this.visibility = visibility;
this.isCreator = isCreator;
}
public Visibility getVisibility() {
return visibility;
}
public boolean isInitial() {
return isCreator;
}
}
......@@ -13,6 +13,7 @@ interface GroupConstants {
String KEY_MEMBER_ID = "memberId";
String KEY_MEMBER_NAME = "memberName";
String KEY_MEMBER_PUBLIC_KEY = "memberPublicKey";
String KEY_INITIAL_JOIN_MSG = "initialJoinMsg";
String GROUP_KEY_MEMBERS = "members";
String GROUP_KEY_OUR_GROUP = "ourGroup";
......
......@@ -29,6 +29,7 @@ import static org.briarproject.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH
import static org.briarproject.api.privategroup.MessageType.JOIN;
import static org.briarproject.api.privategroup.MessageType.POST;
import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_POST_BODY_LENGTH;
import static org.briarproject.privategroup.GroupConstants.KEY_INITIAL_JOIN_MSG;
import static org.briarproject.privategroup.GroupConstants.KEY_MEMBER_ID;
import static org.briarproject.privategroup.GroupConstants.KEY_MEMBER_NAME;
import static org.briarproject.privategroup.GroupConstants.KEY_MEMBER_PUBLIC_KEY;
......@@ -99,10 +100,12 @@ class GroupMessageValidator extends BdfMessageValidator {
// invite is null if the member is the creator of the private group
Author creator = pg.getCreator();
boolean isCreator = false;
BdfList invite = body.getOptionalList(3);
if (invite == null) {
if (!member.equals(creator))
throw new InvalidMessageException();
isCreator = true;
} else {
if (member.equals(creator))
throw new InvalidMessageException();
......@@ -149,6 +152,7 @@ class GroupMessageValidator extends BdfMessageValidator {
// Return the metadata and no dependencies
BdfDictionary meta = new BdfDictionary();
meta.put(KEY_INITIAL_JOIN_MSG, isCreator);
return new BdfMessageContext(meta);
}
......
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