Add a new activity that shows sharing status of forum

The new activity shows who you are sharing a forum with and who shares a
forum with you. It is accessible from the overflow menu when in a forum.

Closes #398
parent 8c2fd905
......@@ -273,8 +273,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
assertTrue(forumManager1.getForums().contains(forum0));
// sharer shares forum with invitee
Contact c1 = contactManager0.getContact(contactId1);
assertTrue(forumSharingManager0.getSharedWith(forum0.getId())
.contains(contactId1));
.contains(c1));
// invitee gets forum shared by sharer
Contact contact0 = contactManager1.getContact(contactId1);
assertTrue(forumSharingManager1.getSharedBy(forum0.getId())
......@@ -292,12 +293,11 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
// sharer no longer shares forum with invitee
assertFalse(forumSharingManager0.getSharedWith(forum0.getId())
.contains(contactId1));
.contains(c1));
// invitee no longer gets forum shared by sharer
assertFalse(forumSharingManager1.getSharedBy(forum0.getId())
.contains(contact0));
// forum can be shared again
Contact c1 = contactManager0.getContact(contactId1);
assertTrue(forumSharingManager0.canBeShared(forum0.getId(), c1));
Contact c0 = contactManager1.getContact(contactId0);
assertTrue(forumSharingManager1.canBeShared(forum0.getId(), c0));
......@@ -333,8 +333,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
assertTrue(forumManager1.getForums().contains(forum0));
// sharer shares forum with invitee
Contact c1 = contactManager0.getContact(contactId1);
assertTrue(forumSharingManager0.getSharedWith(forum0.getId())
.contains(contactId1));
.contains(c1));
// invitee gets forum shared by sharer
Contact contact0 = contactManager1.getContact(contactId1);
assertTrue(forumSharingManager1.getSharedBy(forum0.getId())
......@@ -351,13 +352,13 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
assertEquals(1, forumManager1.getForums().size());
// invitee no longer shares forum with sharer
Contact c0 = contactManager1.getContact(contactId0);
assertFalse(forumSharingManager1.getSharedWith(forum0.getId())
.contains(contactId0));
.contains(c0));
// sharer no longer gets forum shared by invitee
assertFalse(forumSharingManager1.getSharedBy(forum0.getId())
.contains(contact0));
// forum can be shared again
Contact c0 = contactManager1.getContact(contactId0);
assertTrue(forumSharingManager1.canBeShared(forum0.getId(), c0));
} finally {
stopLifecycles();
......
......@@ -149,6 +149,16 @@
/>
</activity>
<activity
android:name=".android.forum.ForumSharingStatusActivity"
android:label="@string/forum_sharing_status"
android:parentActivityName=".android.forum.ForumActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.forum.ForumActivity"
/>
</activity>
<activity
android:name=".android.forum.WriteForumPostActivity"
android:label="@string/app_name"
......
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/default_separator_inverted"
android:padding="@dimen/margin_medium"
android:text="@string/forum_shared_by"
android:textSize="@dimen/text_size_large"/>
<View style="@style/Divider.ForumList"/>
<org.briarproject.android.util.BriarRecyclerView
android:id="@+id/sharedByView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/margin_medium"
android:paddingTop="@dimen/margin_medium"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/default_separator_inverted"
android:padding="@dimen/margin_medium"
android:text="@string/forum_shared_with"
android:textSize="@dimen/text_size_large"/>
<View style="@style/Divider.ForumList"/>
<org.briarproject.android.util.BriarRecyclerView
android:id="@+id/sharedWithView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/margin_medium"
android:paddingTop="@dimen/margin_medium"/>
</LinearLayout>
</ScrollView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingBottom="@dimen/margin_small"
android:paddingTop="@dimen/margin_small">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/avatarView"
style="@style/BriarAvatar"
android:layout_width="@dimen/listitem_picture_size_small"
android:layout_height="@dimen/listitem_picture_size_small"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
tools:src="@drawable/ic_launcher"/>
<TextView
android:id="@+id/nameView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:maxLines="2"
android:textColor="@color/briar_text_primary"
android:textSize="@dimen/text_size_medium"
tools:text="This is a name of a contact"/>
</LinearLayout>
\ No newline at end of file
......@@ -15,6 +15,11 @@
android:title="@string/forum_share_button"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_forum_sharing_status"
android:title="@string/forum_sharing_status"
app:showAsAction="never"/>
<item
android:id="@+id/action_forum_delete"
android:icon="@drawable/action_delete_white"
......
......@@ -36,6 +36,7 @@
<!-- this is needed as preference_category_material layout uses this color as the text color -->
<color name="preference_fallback_accent_color">@color/briar_accent</color>
<color name="divider">#c1c1c1</color>
<color name="default_separator">#000000</color>
<color name="default_separator_inverted">#ffffff</color>
<color name="menu_background">#FFFFFF</color>
......
......@@ -26,6 +26,7 @@
<dimen name="listitem_height_one_line_avatar">56dp</dimen>
<dimen name="listitem_height_contact_selector">68dp</dimen>
<dimen name="listitem_picture_size">48dp</dimen>
<dimen name="listitem_picture_size_small">23dp</dimen>
<dimen name="listitem_picture_frame_size">50dp</dimen>
<dimen name="listitem_selectable_picture_size">40dp</dimen>
<dimen name="dropdown_picture_size">32dp</dimen>
......
......@@ -80,6 +80,7 @@
<string name="show_forums">Show</string>
<string name="forum_leave">Leave Forum</string>
<string name="forum_left_toast">Left Forum</string>
<string name="forum_sharing_status">Sharing Status</string>
<string name="no_forum_posts">No posts</string>
<string name="no_unread_posts">no unread posts</string>
<plurals name="unread_posts">
......@@ -109,6 +110,9 @@
<string name="forum_joined_toast">Joined Forum</string>
<string name="forum_declined_toast">Forum Invitation Declined</string>
<string name="shared_by_format">Shared by %s</string>
<string name="forum_shared_by">Shared by</string>
<string name="forum_shared_with">Shared with</string>
<string name="nobody">Nobody</string>
<string name="no_contacts_prompt">You don\'t have any contacts. Add a contact now?</string>
<string name="add_button">Add</string>
<string name="cancel_button">Cancel</string>
......
......@@ -93,7 +93,7 @@
</style>
<style name="Divider">
<item name="android:background">?android:attr/listDivider</item>
<item name="android:background">@color/divider</item>
</style>
<style name="Divider.Horizontal" parent="Divider">
......
......@@ -7,6 +7,7 @@ import org.briarproject.android.forum.AvailableForumsActivity;
import org.briarproject.android.forum.ContactSelectorFragment;
import org.briarproject.android.forum.CreateForumActivity;
import org.briarproject.android.forum.ForumActivity;
import org.briarproject.android.forum.ForumSharingStatusActivity;
import org.briarproject.android.forum.ReadForumPostActivity;
import org.briarproject.android.forum.ShareForumActivity;
import org.briarproject.android.forum.ShareForumMessageFragment;
......@@ -59,6 +60,8 @@ public interface ActivityComponent {
void inject(ShareForumActivity activity);
void inject(ForumSharingStatusActivity activity);
void inject(ReadForumPostActivity activity);
void inject(ForumActivity activity);
......
......@@ -30,7 +30,7 @@ public class ContactListItem {
}
void setMessages(Collection<ConversationItem> messages) {
empty = messages.isEmpty();
empty = messages == null || messages.isEmpty();
timestamp = 0;
unread = 0;
if (!empty) {
......
......@@ -153,6 +153,9 @@ public class ForumActivity extends BriarActivity implements EventListener,
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
ActivityOptionsCompat options = ActivityOptionsCompat
.makeCustomAnimation(this, android.R.anim.slide_in_left,
android.R.anim.slide_out_right);
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_forum_compose_post:
......@@ -166,13 +169,16 @@ public class ForumActivity extends BriarActivity implements EventListener,
Intent i2 = new Intent(this, ShareForumActivity.class);
i2.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP);
i2.putExtra(GROUP_ID, groupId.getBytes());
ActivityOptionsCompat options = ActivityOptionsCompat
.makeCustomAnimation(this, android.R.anim.slide_in_left,
android.R.anim.slide_out_right);
ActivityCompat
.startActivityForResult(this, i2, REQUEST_FORUM_SHARED,
options.toBundle());
return true;
case R.id.action_forum_sharing_status:
Intent i3 = new Intent(this, ForumSharingStatusActivity.class);
i3.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP);
i3.putExtra(GROUP_ID, groupId.getBytes());
ActivityCompat.startActivity(this, i3, options.toBundle());
return true;
case R.id.action_forum_delete:
showUnsubscribeDialog();
return true;
......
package org.briarproject.android.forum;
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.contact.ContactListItem;
import org.briarproject.android.util.BriarRecyclerView;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.db.DbException;
import org.briarproject.api.forum.ForumSharingManager;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.sync.GroupId;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
public class ForumSharingStatusActivity extends BriarActivity {
private GroupId groupId;
private BriarRecyclerView sharedByList, sharedWithList;
private ForumSharingStatusAdapter sharedByAdapter, sharedWithAdapter;
// Fields that are accessed from background threads must be volatile
@Inject
protected volatile ForumSharingManager forumSharingManager;
@Inject
protected volatile IdentityManager identityManager;
public final static String TAG = "ForumSharingStatusActivity";
private static final Logger LOG = Logger.getLogger(TAG);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forum_sharing_status);
Intent i = getIntent();
byte[] b = i.getByteArrayExtra(GROUP_ID);
if (b == null) throw new IllegalStateException("No GroupId");
groupId = new GroupId(b);
sharedByList = (BriarRecyclerView) findViewById(R.id.sharedByView);
sharedByAdapter = new ForumSharingStatusAdapter(this);
sharedByList.setLayoutManager(new LinearLayoutManager(this));
sharedByList.setAdapter(sharedByAdapter);
sharedByList.setEmptyText(getString(R.string.nobody));
sharedWithList = (BriarRecyclerView) findViewById(R.id.sharedWithView);
sharedWithAdapter = new ForumSharingStatusAdapter(this);
sharedWithList.setLayoutManager(new LinearLayoutManager(this));
sharedWithList.setAdapter(sharedWithAdapter);
sharedWithList.setEmptyText(getString(R.string.nobody));
}
@Override
public void onResume() {
super.onResume();
loadSharedBy();
loadSharedWith();
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
}
private void loadSharedBy() {
dbController.runOnDbThread(new Runnable() {
@Override
public void run() {
List<ContactListItem> contactItems = new ArrayList<>();
try {
Collection<Contact> contacts =
forumSharingManager.getSharedBy(groupId);
for (Contact c : contacts) {
LocalAuthor localAuthor = identityManager
.getLocalAuthor(c.getLocalAuthorId());
ContactListItem item =
new ContactListItem(c, localAuthor, false, null,
null);
contactItems.add(item);
}
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
displaySharedBy(contactItems);
}
});
}
private void displaySharedBy(final List<ContactListItem> contacts) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (contacts.isEmpty()) {
sharedByList.showData();
} else {
sharedByAdapter.addAll(contacts);
}
}
});
}
private void loadSharedWith() {
dbController.runOnDbThread(new Runnable() {
@Override
public void run() {
List<ContactListItem> contactItems = new ArrayList<>();
try {
Collection<Contact> contacts =
forumSharingManager.getSharedWith(groupId);
for (Contact c : contacts) {
LocalAuthor localAuthor = identityManager
.getLocalAuthor(c.getLocalAuthorId());
ContactListItem item =
new ContactListItem(c, localAuthor, false, null,
null);
contactItems.add(item);
}
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
displaySharedWith(contactItems);
}
});
}
private void displaySharedWith(final List<ContactListItem> contacts) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (contacts.isEmpty()) {
sharedWithList.showData();
} else {
sharedWithAdapter.addAll(contacts);
}
}
});
}
}
package org.briarproject.android.forum;
import android.content.Context;
import android.support.v4.content.ContextCompat;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import org.briarproject.R;
import org.briarproject.android.contact.BaseContactListAdapter;
import org.briarproject.android.contact.ContactListItem;
public class ForumSharingStatusAdapter
extends BaseContactListAdapter<BaseContactListAdapter.BaseContactHolder> {
public ForumSharingStatusAdapter(Context context) {
super(context, null);
}
@Override
public BaseContactHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(
R.layout.list_item_contact_small, viewGroup, false);
return new BaseContactHolder(v);
}
@Override
public int compareContactListItems(ContactListItem c1, ContactListItem c2) {
return compareByName(c1, c2);
}
}
......@@ -120,10 +120,11 @@ public class BriarRecyclerView extends FrameLayout {
emptyView.setVisibility(VISIBLE);
recyclerView.setVisibility(INVISIBLE);
} else {
emptyView.setVisibility(INVISIBLE);
// use GONE here so empty view doesn't use space on small lists
emptyView.setVisibility(GONE);
recyclerView.setVisibility(VISIBLE);
}
progressBar.setVisibility(INVISIBLE);
progressBar.setVisibility(GONE);
}
}
......
......@@ -41,7 +41,7 @@ public interface ForumSharingManager {
Collection<Contact> getSharedBy(GroupId g) throws DbException;
/** Returns the IDs of all contacts with whom the given forum is shared. */
Collection<ContactId> getSharedWith(GroupId g) throws DbException;
Collection<Contact> getSharedWith(GroupId g) throws DbException;
/** Returns true if the forum not already shared and no invitation is open */
boolean canBeShared(GroupId g, Contact c) throws DbException;
......
......@@ -442,15 +442,15 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook
}
@Override
public Collection<ContactId> getSharedWith(GroupId g) throws DbException {
public Collection<Contact> getSharedWith(GroupId g) throws DbException {
try {
List<ContactId> shared = new ArrayList<ContactId>();
List<Contact> shared = new ArrayList<Contact>();
Transaction txn = db.startTransaction(true);
try {
for (Contact c : db.getContacts(txn)) {
GroupId contactGroup = getContactGroup(c).getId();
if (listContains(txn, contactGroup, g, SHARED_BY_US))
shared.add(c.getId());
shared.add(c);
}
txn.setComplete();
} finally {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment