From a4cf91fba540187e2f361724c7f2b671ec319986 Mon Sep 17 00:00:00 2001 From: Torsten Grote <t@grobox.de> Date: Wed, 3 Aug 2016 13:00:24 -0300 Subject: [PATCH] Use Inheritence for shared Forum and Blog Sharing Code --- briar-android/AndroidManifest.xml | 40 ++- ...ity_share_forum.xml => activity_share.xml} | 0 ...status.xml => activity_sharing_status.xml} | 0 ...n_out.xml => list_item_msg_notice_out.xml} | 0 .../list_item_shareable_invitation_in.xml | 6 +- briar-android/res/menu/blogs_blog_actions.xml | 2 +- briar-android/res/menu/forum_actions.xml | 2 +- briar-android/res/values-pt-rBR/strings.xml | 2 +- briar-android/res/values/strings.xml | 7 +- .../android/ActivityComponent.java | 29 +- .../android/blogs/BlogFragment.java | 14 +- .../android/contact/ContactListFragment.java | 16 +- .../android/contact/ConversationActivity.java | 11 +- .../android/contact/ConversationAdapter.java | 21 +- .../android/forum/ForumActivity.java | 12 +- .../android/forum/ForumListFragment.java | 7 +- .../sharing/ContactSelectorFragment.java | 30 +-- .../android/sharing/InvitationsActivity.java | 249 ++---------------- .../sharing/InvitationsBlogActivity.java | 127 +++++++++ .../sharing/InvitationsForumActivity.java | 127 +++++++++ .../android/sharing/ShareActivity.java | 30 +-- .../android/sharing/ShareBlogActivity.java | 35 +++ .../sharing/ShareBlogMessageFragment.java | 81 ++++++ .../android/sharing/ShareForumActivity.java | 34 +++ .../sharing/ShareForumMessageFragment.java | 79 ++++++ .../android/sharing/ShareMessageFragment.java | 104 ++------ .../sharing/SharingStatusActivity.java | 64 ++--- .../sharing/SharingStatusBlogActivity.java | 37 +++ .../sharing/SharingStatusForumActivity.java | 37 +++ 29 files changed, 746 insertions(+), 457 deletions(-) rename briar-android/res/layout/{activity_share_forum.xml => activity_share.xml} (100%) rename briar-android/res/layout/{activity_forum_sharing_status.xml => activity_sharing_status.xml} (100%) rename briar-android/res/layout/{list_item_introduction_out.xml => list_item_msg_notice_out.xml} (100%) create mode 100644 briar-android/src/org/briarproject/android/sharing/InvitationsBlogActivity.java create mode 100644 briar-android/src/org/briarproject/android/sharing/InvitationsForumActivity.java create mode 100644 briar-android/src/org/briarproject/android/sharing/ShareBlogActivity.java create mode 100644 briar-android/src/org/briarproject/android/sharing/ShareBlogMessageFragment.java create mode 100644 briar-android/src/org/briarproject/android/sharing/ShareForumActivity.java create mode 100644 briar-android/src/org/briarproject/android/sharing/ShareForumMessageFragment.java create mode 100644 briar-android/src/org/briarproject/android/sharing/SharingStatusBlogActivity.java create mode 100644 briar-android/src/org/briarproject/android/sharing/SharingStatusForumActivity.java diff --git a/briar-android/AndroidManifest.xml b/briar-android/AndroidManifest.xml index 7b2c1ceacf..df2a916d3d 100644 --- a/briar-android/AndroidManifest.xml +++ b/briar-android/AndroidManifest.xml @@ -102,7 +102,7 @@ </activity> <activity - android:name=".android.sharing.InvitationsActivity" + android:name=".android.sharing.InvitationsForumActivity" android:label="@string/forum_invitations_title" android:parentActivityName=".android.NavDrawerActivity"> <meta-data @@ -111,6 +111,16 @@ /> </activity> + <activity + android:name=".android.sharing.InvitationsBlogActivity" + android:label="@string/blogs_sharing_invitations_title" + android:parentActivityName=".android.contact.ConversationActivity"> + <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value=".android.contact.ConversationActivity" + /> + </activity> + <activity android:name=".android.forum.CreateForumActivity" android:label="@string/create_forum_title" @@ -133,8 +143,8 @@ </activity> <activity - android:name=".android.sharing.ShareActivity" - android:label="@string/forums_share_toolbar_header" + android:name=".android.sharing.ShareForumActivity" + android:label="@string/activity_share_toolbar_header" android:parentActivityName=".android.forum.ForumActivity"> <meta-data android:name="android.support.PARENT_ACTIVITY" @@ -143,8 +153,18 @@ </activity> <activity - android:name=".android.sharing.SharingStatusActivity" - android:label="@string/forum_sharing_status" + android:name=".android.sharing.ShareBlogActivity" + android:label="@string/activity_share_toolbar_header" + android:parentActivityName=".android.blogs.BlogActivity"> + <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value=".android.blogs.BlogActivity" + /> + </activity> + + <activity + android:name=".android.sharing.SharingStatusForumActivity" + android:label="@string/sharing_status" android:parentActivityName=".android.forum.ForumActivity"> <meta-data android:name="android.support.PARENT_ACTIVITY" @@ -152,6 +172,16 @@ /> </activity> + <activity + android:name=".android.sharing.SharingStatusBlogActivity" + android:label="@string/sharing_status" + android:parentActivityName=".android.blogs.BlogActivity"> + <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value=".android.blogs.BlogActivity" + /> + </activity> + <activity android:name=".android.blogs.CreateBlogActivity" android:label="@string/blogs_my_blogs_label" diff --git a/briar-android/res/layout/activity_share_forum.xml b/briar-android/res/layout/activity_share.xml similarity index 100% rename from briar-android/res/layout/activity_share_forum.xml rename to briar-android/res/layout/activity_share.xml diff --git a/briar-android/res/layout/activity_forum_sharing_status.xml b/briar-android/res/layout/activity_sharing_status.xml similarity index 100% rename from briar-android/res/layout/activity_forum_sharing_status.xml rename to briar-android/res/layout/activity_sharing_status.xml diff --git a/briar-android/res/layout/list_item_introduction_out.xml b/briar-android/res/layout/list_item_msg_notice_out.xml similarity index 100% rename from briar-android/res/layout/list_item_introduction_out.xml rename to briar-android/res/layout/list_item_msg_notice_out.xml diff --git a/briar-android/res/layout/list_item_shareable_invitation_in.xml b/briar-android/res/layout/list_item_shareable_invitation_in.xml index 33f95059ba..2903e4646b 100644 --- a/briar-android/res/layout/list_item_shareable_invitation_in.xml +++ b/briar-android/res/layout/list_item_shareable_invitation_in.xml @@ -37,13 +37,13 @@ android:layout_marginTop="@dimen/message_bubble_timestamp_margin" android:layout_alignEnd="@+id/introductionText" android:layout_alignRight="@+id/introductionText" - android:layout_below="@+id/showForumsButton" + android:layout_below="@+id/showInvitationsButton" android:textColor="@color/private_message_date" android:textSize="@dimen/text_size_tiny" tools:text="Dec 24, 13:37"/> <Button - android:id="@+id/showForumsButton" + android:id="@+id/showInvitationsButton" style="@style/BriarButtonFlat.Positive" android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -51,7 +51,7 @@ android:layout_alignEnd="@+id/introductionText" android:layout_alignRight="@+id/introductionText" android:layout_below="@+id/introductionText" - android:text="@string/forum_show_invitations"/> + tools:text="@string/forum_show_invitations"/> </RelativeLayout> diff --git a/briar-android/res/menu/blogs_blog_actions.xml b/briar-android/res/menu/blogs_blog_actions.xml index ef84cfb201..e8f680a7c3 100644 --- a/briar-android/res/menu/blogs_blog_actions.xml +++ b/briar-android/res/menu/blogs_blog_actions.xml @@ -11,7 +11,7 @@ <item android:id="@+id/action_blog_sharing_status" - android:title="@string/forum_sharing_status" + android:title="@string/sharing_status" app:showAsAction="never"/> </menu> \ No newline at end of file diff --git a/briar-android/res/menu/forum_actions.xml b/briar-android/res/menu/forum_actions.xml index 599529b50b..2a262cbfa3 100644 --- a/briar-android/res/menu/forum_actions.xml +++ b/briar-android/res/menu/forum_actions.xml @@ -17,7 +17,7 @@ <item android:id="@+id/action_forum_sharing_status" - android:title="@string/forum_sharing_status" + android:title="@string/sharing_status" app:showAsAction="never"/> <item diff --git a/briar-android/res/values-pt-rBR/strings.xml b/briar-android/res/values-pt-rBR/strings.xml index d5332cc645..52ec3c9026 100644 --- a/briar-android/res/values-pt-rBR/strings.xml +++ b/briar-android/res/values-pt-rBR/strings.xml @@ -79,7 +79,7 @@ <string name="show_forums">Mostrar</string> <string name="forum_leave">Sair do fórum</string> <string name="forum_left_toast">Saiu do fórum</string> - <string name="forum_sharing_status">Status de compartilhamento</string> + <string name="sharing_status">Status de compartilhamento</string> <string name="no_posts">Sem Posts</string> <plurals name="unread_posts"> <item quantity="one">%d post não lido</item> diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml index 54c7316a6b..d6c5807fc4 100644 --- a/briar-android/res/values/strings.xml +++ b/briar-android/res/values/strings.xml @@ -53,6 +53,7 @@ <string name="now">now</string> <string name="contact_list_title">Contacts</string> <string name="no_contacts">It seems that you are new here and have no contacts yet.\n\nTap the + icon at the top and follow the instructions to add some friends to your list.\n\nPlease remember: You can only add new contacts face-to-face to prevent anyone from impersonating you or reading your messages in the future.</string> + <string name="no_contacts_selector">It seems that you are new here and have no contacts yet.\n\nPlease come back here after you added your first contact.</string> <string name="add_contact_title">Add a Contact</string> <string name="your_nickname">Choose the identity you want to use:</string> <string name="face_to_face">You must be face-to-face with the person you want to add as a contact. This will prevent anyone from impersonating you or reading your messages in future.</string> @@ -95,7 +96,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="sharing_status">Sharing Status</string> <string name="no_posts">No posts</string> <plurals name="unread_posts"> <item quantity="one">%d unread post</item> @@ -266,7 +267,7 @@ <string name="settings_toolbar_header">Settings</string> <string name="contacts_toolbar_header">Contacts</string> <string name="forums_toolbar_header">Forums</string> - <string name="forums_share_toolbar_header">Choose Contacts</string> + <string name="activity_share_toolbar_header">Choose Contacts</string> <!-- Progress titles --> <string name="progress_title_logout">Signing out of Briar..</string> <string name="progress_title_please_wait">Please wait..</string> @@ -317,7 +318,7 @@ <string name="blogs_sharing_invitation_sent">You have shared the personal blog of %1$s with %2$s.</string> <string name="blogs_sharing_show_invitations">Show Blog Invitations</string> <string name="blogs_sharing_invitations_title">Blog Invitations</string> - <string name="blogs_sharing_exists">You are subscribed to this blog already.\nWarning: Accepting again might reveal that %s is your contact.</string> + <string name="blogs_sharing_exists">You are subscribed to this blog already. Accepting again can lead to faster blog post delivery.</string> <string name="blogs_sharing_joined_toast">Subscribed to Blog</string> <string name="blogs_sharing_declined_toast">Blog Invitation Declined</string> diff --git a/briar-android/src/org/briarproject/android/ActivityComponent.java b/briar-android/src/org/briarproject/android/ActivityComponent.java index 81ef8bd57e..74fcd472ce 100644 --- a/briar-android/src/org/briarproject/android/ActivityComponent.java +++ b/briar-android/src/org/briarproject/android/ActivityComponent.java @@ -15,14 +15,9 @@ import org.briarproject.android.blogs.RssFeedManageActivity; import org.briarproject.android.blogs.WriteBlogPostActivity; import org.briarproject.android.contact.ContactListFragment; import org.briarproject.android.contact.ConversationActivity; -import org.briarproject.android.sharing.InvitationsActivity; -import org.briarproject.android.sharing.ContactSelectorFragment; import org.briarproject.android.forum.CreateForumActivity; import org.briarproject.android.forum.ForumActivity; import org.briarproject.android.forum.ForumListFragment; -import org.briarproject.android.sharing.SharingStatusActivity; -import org.briarproject.android.sharing.ShareActivity; -import org.briarproject.android.sharing.ShareMessageFragment; import org.briarproject.android.identity.CreateIdentityActivity; import org.briarproject.android.introduction.ContactChooserFragment; import org.briarproject.android.introduction.IntroductionActivity; @@ -33,6 +28,15 @@ import org.briarproject.android.keyagreement.KeyAgreementActivity; import org.briarproject.android.keyagreement.ShowQrCodeFragment; import org.briarproject.android.panic.PanicPreferencesActivity; import org.briarproject.android.panic.PanicResponderActivity; +import org.briarproject.android.sharing.ContactSelectorFragment; +import org.briarproject.android.sharing.InvitationsBlogActivity; +import org.briarproject.android.sharing.InvitationsForumActivity; +import org.briarproject.android.sharing.ShareBlogActivity; +import org.briarproject.android.sharing.ShareBlogMessageFragment; +import org.briarproject.android.sharing.ShareForumActivity; +import org.briarproject.android.sharing.ShareForumMessageFragment; +import org.briarproject.android.sharing.SharingStatusBlogActivity; +import org.briarproject.android.sharing.SharingStatusForumActivity; import dagger.Component; @@ -63,13 +67,19 @@ public interface ActivityComponent { void inject(CreateIdentityActivity activity); - void inject(InvitationsActivity activity); + void inject(InvitationsForumActivity activity); + + void inject(InvitationsBlogActivity activity); void inject(CreateForumActivity activity); - void inject(ShareActivity activity); + void inject(ShareForumActivity activity); + + void inject(ShareBlogActivity activity); + + void inject(SharingStatusForumActivity activity); - void inject(SharingStatusActivity activity); + void inject(SharingStatusBlogActivity activity); void inject(ForumActivity activity); @@ -104,7 +114,8 @@ public interface ActivityComponent { void inject(ShowQrCodeFragment fragment); void inject(ContactChooserFragment fragment); void inject(ContactSelectorFragment fragment); - void inject(ShareMessageFragment fragment); + void inject(ShareForumMessageFragment fragment); + void inject(ShareBlogMessageFragment fragment); void inject(IntroductionMessageFragment fragment); } diff --git a/briar-android/src/org/briarproject/android/blogs/BlogFragment.java b/briar-android/src/org/briarproject/android/blogs/BlogFragment.java index e588777081..9b9cf4f090 100644 --- a/briar-android/src/org/briarproject/android/blogs/BlogFragment.java +++ b/briar-android/src/org/briarproject/android/blogs/BlogFragment.java @@ -23,8 +23,8 @@ import org.briarproject.android.blogs.BlogController.BlogPostListener; import org.briarproject.android.blogs.BlogPostAdapter.OnBlogPostClickListener; import org.briarproject.android.controller.handler.UiResultHandler; import org.briarproject.android.fragment.BaseFragment; -import org.briarproject.android.sharing.ShareActivity; -import org.briarproject.android.sharing.SharingStatusActivity; +import org.briarproject.android.sharing.ShareBlogActivity; +import org.briarproject.android.sharing.SharingStatusBlogActivity; import org.briarproject.android.util.BriarRecyclerView; import org.briarproject.api.sync.GroupId; @@ -44,8 +44,6 @@ import static org.briarproject.android.blogs.BlogActivity.IS_MY_BLOG; import static org.briarproject.android.blogs.BlogActivity.IS_NEW_BLOG; import static org.briarproject.android.blogs.BlogActivity.REQUEST_SHARE; import static org.briarproject.android.blogs.BlogActivity.REQUEST_WRITE_POST; -import static org.briarproject.android.sharing.ShareActivity.BLOG; -import static org.briarproject.android.sharing.ShareActivity.SHAREABLE; public class BlogFragment extends BaseFragment implements BlogPostListener { @@ -169,18 +167,16 @@ public class BlogFragment extends BaseFragment implements BlogPostListener { REQUEST_WRITE_POST, options.toBundle()); return true; case R.id.action_blog_share: - Intent i2 = new Intent(getActivity(), ShareActivity.class); + Intent i2 = new Intent(getActivity(), ShareBlogActivity.class); i2.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); i2.putExtra(GROUP_ID, groupId.getBytes()); - i2.putExtra(SHAREABLE, BLOG); startActivityForResult(i2, REQUEST_SHARE, options.toBundle()); return true; case R.id.action_blog_sharing_status: - Intent i3 = - new Intent(getActivity(), SharingStatusActivity.class); + Intent i3 = new Intent(getActivity(), + SharingStatusBlogActivity.class); i3.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); i3.putExtra(GROUP_ID, groupId.getBytes()); - i3.putExtra(SHAREABLE, BLOG); startActivity(i3, options.toBundle()); return true; default: diff --git a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java index c9df74031e..2f7dd90681 100644 --- a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java +++ b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java @@ -34,15 +34,11 @@ import org.briarproject.api.event.ContactStatusChangedEvent; import org.briarproject.api.event.Event; import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventListener; -import org.briarproject.api.event.ForumInvitationReceivedEvent; -import org.briarproject.api.event.ForumInvitationResponseReceivedEvent; import org.briarproject.api.event.IntroductionRequestReceivedEvent; import org.briarproject.api.event.IntroductionResponseReceivedEvent; import org.briarproject.api.event.InvitationReceivedEvent; import org.briarproject.api.event.InvitationResponseReceivedEvent; import org.briarproject.api.event.PrivateMessageReceivedEvent; -import org.briarproject.api.forum.ForumInvitationRequest; -import org.briarproject.api.forum.ForumInvitationResponse; import org.briarproject.api.forum.ForumSharingManager; import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.identity.LocalAuthor; @@ -409,15 +405,19 @@ public class ContactListFragment extends BaseFragment implements EventListener { LOG.info("Loading introduction messages took " + duration + " ms"); now = System.currentTimeMillis(); - Collection<InvitationMessage> invitations = + Collection<InvitationMessage> forumInvitations = forumSharingManager.getInvitationMessages(id); - invitations.addAll(blogSharingManager.getInvitationMessages(id)); - for (InvitationMessage i : invitations) { + for (InvitationMessage i : forumInvitations) { + messages.add(ConversationItem.from(i)); + } + Collection<InvitationMessage> blogInvitations = + blogSharingManager.getInvitationMessages(id); + for (InvitationMessage i : blogInvitations) { messages.add(ConversationItem.from(i)); } duration = System.currentTimeMillis() - now; if (LOG.isLoggable(INFO)) - LOG.info("Loading forum invitations took " + duration + " ms"); + LOG.info("Loading invitations took " + duration + " ms"); return messages; } diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java index b1cd0292d1..a85723601f 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java @@ -337,11 +337,16 @@ public class ConversationActivity extends BriarActivity Collection<IntroductionMessage> introductions = introductionManager .getIntroductionMessages(contactId); - Collection<InvitationMessage> invitations = + Collection<InvitationMessage> forumInvitations = forumSharingManager .getInvitationMessages(contactId); - invitations.addAll(blogSharingManager - .getInvitationMessages(contactId)); + Collection<InvitationMessage> blogInvitations = + blogSharingManager + .getInvitationMessages(contactId); + List<InvitationMessage> invitations = new ArrayList<>( + forumInvitations.size() + blogInvitations.size()); + invitations.addAll(forumInvitations); + invitations.addAll(blogInvitations); long duration = System.currentTimeMillis() - now; if (LOG.isLoggable(INFO)) LOG.info("Loading headers took " + duration + " ms"); diff --git a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java index 353a7e1ce2..c2fc1c026e 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java @@ -13,7 +13,8 @@ import android.widget.ImageView; import android.widget.TextView; import org.briarproject.R; -import org.briarproject.android.sharing.InvitationsActivity; +import org.briarproject.android.sharing.InvitationsBlogActivity; +import org.briarproject.android.sharing.InvitationsForumActivity; import org.briarproject.android.util.AndroidUtils; import org.briarproject.api.blogs.BlogInvitationRequest; import org.briarproject.api.clients.SessionId; @@ -42,9 +43,6 @@ import static org.briarproject.android.contact.ConversationItem.MSG_OUT; import static org.briarproject.android.contact.ConversationItem.NOTICE_IN; import static org.briarproject.android.contact.ConversationItem.NOTICE_OUT; import static org.briarproject.android.contact.ConversationItem.OutgoingItem; -import static org.briarproject.android.sharing.ShareActivity.BLOG; -import static org.briarproject.android.sharing.ShareActivity.FORUM; -import static org.briarproject.android.sharing.ShareActivity.SHAREABLE; class ConversationAdapter extends RecyclerView.Adapter { @@ -86,7 +84,7 @@ class ConversationAdapter extends RecyclerView.Adapter { return new IntroductionHolder(v, type); } else if (type == INTRODUCTION_OUT) { v = LayoutInflater.from(viewGroup.getContext()).inflate( - R.layout.list_item_introduction_out, viewGroup, false); + R.layout.list_item_msg_notice_out, viewGroup, false); return new IntroductionHolder(v, type); } else if (type == NOTICE_IN) { v = LayoutInflater.from(viewGroup.getContext()).inflate( @@ -104,7 +102,7 @@ class ConversationAdapter extends RecyclerView.Adapter { } else if (type == FORUM_INVITATION_OUT || type == BLOG_INVITATION_OUT) { v = LayoutInflater.from(viewGroup.getContext()).inflate( - R.layout.list_item_introduction_out, viewGroup, false); + R.layout.list_item_msg_notice_out, viewGroup, false); return new InvitationHolder(v, type); } // incoming message (non-local) @@ -338,17 +336,16 @@ class ConversationAdapter extends RecyclerView.Adapter { ui.text.setText(ctx.getString(receivedRes, contactName, name)); if (ir.isAvailable()) { - final int type = - ir instanceof ForumInvitationRequest ? FORUM : BLOG; + final Class c = ir instanceof ForumInvitationRequest ? + InvitationsForumActivity.class : + InvitationsBlogActivity.class; ui.showInvitationsButton.setText(ctx.getString(buttonRes)); ui.showInvitationsButton.setVisibility(VISIBLE); ui.showInvitationsButton .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent i = new Intent(ctx, - InvitationsActivity.class); - i.putExtra(SHAREABLE, type); + Intent i = new Intent(ctx, c); ctx.startActivity(i); } }); @@ -513,7 +510,7 @@ class ConversationAdapter extends RecyclerView.Adapter { message = new MessageHolder(messageLayout, type == FORUM_INVITATION_IN ? MSG_IN : MSG_OUT); text = (TextView) v.findViewById(R.id.introductionText); - showInvitationsButton = (Button) v.findViewById(R.id.showForumsButton); + showInvitationsButton = (Button) v.findViewById(R.id.showInvitationsButton); date = (TextView) v.findViewById(R.id.introductionTime); if (type == FORUM_INVITATION_OUT || type == BLOG_INVITATION_OUT) { diff --git a/briar-android/src/org/briarproject/android/forum/ForumActivity.java b/briar-android/src/org/briarproject/android/forum/ForumActivity.java index 77d3a713a0..610c2b3e62 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumActivity.java +++ b/briar-android/src/org/briarproject/android/forum/ForumActivity.java @@ -33,8 +33,8 @@ import org.briarproject.android.ActivityComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.api.AndroidNotificationManager; import org.briarproject.android.controller.handler.UiResultHandler; -import org.briarproject.android.sharing.ShareActivity; -import org.briarproject.android.sharing.SharingStatusActivity; +import org.briarproject.android.sharing.ShareForumActivity; +import org.briarproject.android.sharing.SharingStatusForumActivity; import org.briarproject.android.util.AndroidUtils; import org.briarproject.android.util.BriarRecyclerView; import org.briarproject.android.util.TrustIndicatorView; @@ -59,8 +59,6 @@ import static android.view.View.GONE; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; import static android.widget.Toast.LENGTH_SHORT; -import static org.briarproject.android.sharing.ShareActivity.FORUM; -import static org.briarproject.android.sharing.ShareActivity.SHAREABLE; public class ForumActivity extends BriarActivity implements ForumController.ForumPostListener { @@ -224,19 +222,17 @@ public class ForumActivity extends BriarActivity implements showTextInput(null); return true; case R.id.action_forum_share: - Intent i2 = new Intent(this, ShareActivity.class); + Intent i2 = new Intent(this, ShareForumActivity.class); i2.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); i2.putExtra(GROUP_ID, groupId.getBytes()); - i2.putExtra(SHAREABLE, FORUM); ActivityCompat .startActivityForResult(this, i2, REQUEST_FORUM_SHARED, options.toBundle()); return true; case R.id.action_forum_sharing_status: - Intent i3 = new Intent(this, SharingStatusActivity.class); + Intent i3 = new Intent(this, SharingStatusForumActivity.class); i3.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); i3.putExtra(GROUP_ID, groupId.getBytes()); - i3.putExtra(SHAREABLE, FORUM); ActivityCompat.startActivity(this, i3, options.toBundle()); return true; case R.id.action_forum_delete: diff --git a/briar-android/src/org/briarproject/android/forum/ForumListFragment.java b/briar-android/src/org/briarproject/android/forum/ForumListFragment.java index 26721db36d..93fece1089 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumListFragment.java +++ b/briar-android/src/org/briarproject/android/forum/ForumListFragment.java @@ -16,7 +16,7 @@ import android.view.ViewGroup; import org.briarproject.R; import org.briarproject.android.ActivityComponent; import org.briarproject.android.fragment.BaseEventFragment; -import org.briarproject.android.sharing.InvitationsActivity; +import org.briarproject.android.sharing.InvitationsForumActivity; import org.briarproject.android.util.BriarRecyclerView; import org.briarproject.api.db.DbException; import org.briarproject.api.db.NoSuchGroupException; @@ -41,8 +41,6 @@ import javax.inject.Inject; import static android.support.design.widget.Snackbar.LENGTH_INDEFINITE; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -import static org.briarproject.android.sharing.ShareActivity.FORUM; -import static org.briarproject.android.sharing.ShareActivity.SHAREABLE; public class ForumListFragment extends BaseEventFragment implements View.OnClickListener { @@ -288,8 +286,7 @@ public class ForumListFragment extends BaseEventFragment implements @Override public void onClick(View view) { // snackbar click - Intent i = new Intent(getContext(), InvitationsActivity.class); - i.putExtra(SHAREABLE, FORUM); + Intent i = new Intent(getContext(), InvitationsForumActivity.class); startActivity(i); } } diff --git a/briar-android/src/org/briarproject/android/sharing/ContactSelectorFragment.java b/briar-android/src/org/briarproject/android/sharing/ContactSelectorFragment.java index 6ace473db2..a1671e2e24 100644 --- a/briar-android/src/org/briarproject/android/sharing/ContactSelectorFragment.java +++ b/briar-android/src/org/briarproject/android/sharing/ContactSelectorFragment.java @@ -18,7 +18,6 @@ import org.briarproject.android.contact.BaseContactListAdapter; import org.briarproject.android.contact.ContactListItem; import org.briarproject.android.fragment.BaseFragment; import org.briarproject.android.util.BriarRecyclerView; -import org.briarproject.api.blogs.BlogSharingManager; import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactManager; @@ -38,10 +37,7 @@ import javax.inject.Inject; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -import static org.briarproject.android.sharing.ShareActivity.BLOG; import static org.briarproject.android.sharing.ShareActivity.CONTACTS; -import static org.briarproject.android.sharing.ShareActivity.FORUM; -import static org.briarproject.android.sharing.ShareActivity.SHAREABLE; import static org.briarproject.android.sharing.ShareActivity.getContactsFromIds; import static org.briarproject.api.sharing.SharingConstants.GROUP_ID; @@ -66,18 +62,13 @@ public class ContactSelectorFragment extends BaseFragment implements protected volatile IdentityManager identityManager; @Inject protected volatile ForumSharingManager forumSharingManager; - @Inject - volatile BlogSharingManager blogSharingManager; private volatile GroupId groupId; - private volatile int shareable; - public static ContactSelectorFragment newInstance(int shareable, - GroupId groupId) { + public static ContactSelectorFragment newInstance(GroupId groupId) { Bundle args = new Bundle(); args.putByteArray(GROUP_ID, groupId.getBytes()); - args.putInt(SHAREABLE, shareable); ContactSelectorFragment fragment = new ContactSelectorFragment(); fragment.setArguments(args); return fragment; @@ -95,7 +86,7 @@ public class ContactSelectorFragment extends BaseFragment implements shareActivity = (ShareActivity) context; } catch (ClassCastException e) { throw new InstantiationError( - "This fragment is only meant to be attached to the ShareForumActivity"); + "This fragment is only meant to be attached to a subclass of ShareActivity"); } } @@ -104,9 +95,9 @@ public class ContactSelectorFragment extends BaseFragment implements super.onCreate(savedInstanceState); setHasOptionsMenu(true); - groupId = new GroupId(getArguments().getByteArray(GROUP_ID)); + Bundle args = getArguments(); + groupId = new GroupId(args.getByteArray(GROUP_ID)); if (groupId == null) throw new IllegalStateException("No GroupId"); - shareable = getArguments().getInt(SHAREABLE); } @Override @@ -125,7 +116,7 @@ public class ContactSelectorFragment extends BaseFragment implements list = (BriarRecyclerView) contentView.findViewById(R.id.contactList); list.setLayoutManager(new LinearLayoutManager(getActivity())); list.setAdapter(adapter); - list.setEmptyText(getString(R.string.no_contacts)); + list.setEmptyText(getString(R.string.no_contacts_selector)); // restore selected contacts if available if (savedInstanceState != null) { @@ -195,7 +186,7 @@ public class ContactSelectorFragment extends BaseFragment implements } private void loadContacts(final Collection<ContactId> selection) { - listener.runOnDbThread(new Runnable() { + shareActivity.runOnDbThread(new Runnable() { @Override public void run() { try { @@ -209,14 +200,7 @@ public class ContactSelectorFragment extends BaseFragment implements boolean selected = selection != null && selection.contains(c.getId()); // do we have already some sharing with that contact? - boolean disabled = true; - if (shareable == FORUM) { - disabled = !forumSharingManager - .canBeShared(groupId, c); - } else if (shareable == BLOG) { - disabled = !blogSharingManager - .canBeShared(groupId, c); - } + boolean disabled = shareActivity.isDisabled(groupId, c); contacts.add(new SelectableContactListItem(c, localAuthor, groupId, selected, disabled)); } diff --git a/briar-android/src/org/briarproject/android/sharing/InvitationsActivity.java b/briar-android/src/org/briarproject/android/sharing/InvitationsActivity.java index 614f54cbf3..985b73bdd2 100644 --- a/briar-android/src/org/briarproject/android/sharing/InvitationsActivity.java +++ b/briar-android/src/org/briarproject/android/sharing/InvitationsActivity.java @@ -1,68 +1,36 @@ package org.briarproject.android.sharing; -import android.content.Intent; +import android.content.Context; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.widget.Toast; import org.briarproject.R; -import org.briarproject.android.ActivityComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.util.BriarRecyclerView; -import org.briarproject.api.blogs.Blog; -import org.briarproject.api.blogs.BlogManager; -import org.briarproject.api.blogs.BlogSharingManager; -import org.briarproject.api.contact.Contact; -import org.briarproject.api.db.DbException; -import org.briarproject.api.db.NoSuchGroupException; -import org.briarproject.api.event.BlogInvitationReceivedEvent; import org.briarproject.api.event.ContactRemovedEvent; import org.briarproject.api.event.Event; import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventListener; -import org.briarproject.api.event.ForumInvitationReceivedEvent; -import org.briarproject.api.event.GroupAddedEvent; -import org.briarproject.api.event.GroupRemovedEvent; -import org.briarproject.api.event.InvitationReceivedEvent; -import org.briarproject.api.forum.Forum; -import org.briarproject.api.forum.ForumManager; -import org.briarproject.api.forum.ForumSharingManager; -import org.briarproject.api.sync.ClientId; -import java.util.ArrayList; import java.util.Collection; import java.util.logging.Logger; import javax.inject.Inject; import static android.widget.Toast.LENGTH_SHORT; -import static java.util.logging.Level.INFO; -import static java.util.logging.Level.WARNING; import static org.briarproject.android.sharing.InvitationAdapter.AvailableForumClickListener; -import static org.briarproject.android.sharing.ShareActivity.BLOG; -import static org.briarproject.android.sharing.ShareActivity.FORUM; -import static org.briarproject.android.sharing.ShareActivity.SHAREABLE; -public class InvitationsActivity extends BriarActivity +abstract class InvitationsActivity extends BriarActivity implements EventListener, AvailableForumClickListener { - private static final Logger LOG = + protected static final Logger LOG = Logger.getLogger(InvitationsActivity.class.getName()); - private int shareable; private InvitationAdapter adapter; - // Fields that are accessed from background threads must be volatile @Inject - protected volatile ForumManager forumManager; - @Inject - protected volatile ForumSharingManager forumSharingManager; - @Inject - protected volatile BlogManager blogManager; - @Inject - protected volatile BlogSharingManager blogSharingManager; - @Inject - protected volatile EventBus eventBus; + protected EventBus eventBus; @Override public void onCreate(Bundle state) { @@ -70,18 +38,7 @@ public class InvitationsActivity extends BriarActivity setContentView(R.layout.activity_invitations); - Intent i = getIntent(); - shareable = i.getIntExtra(SHAREABLE, 0); - if (shareable == 0) throw new IllegalStateException("No Shareable"); - - if (shareable == FORUM) { - adapter = new ForumInvitationAdapter(this, this); - } else if (shareable == BLOG) { - adapter = new BlogInvitationAdapter(this, this); - setTitle(getString(R.string.blogs_sharing_invitations_title)); - } else { - throw new IllegalArgumentException("Unknown Shareable Type"); - } + adapter = getAdapter(this, this); BriarRecyclerView list = (BriarRecyclerView) findViewById(R.id.invitationsView); @@ -91,16 +48,11 @@ public class InvitationsActivity extends BriarActivity } } - @Override - public void injectActivity(ActivityComponent component) { - component.inject(this); - } - @Override public void onResume() { super.onResume(); eventBus.addListener(this); - loadShareables(false); + loadInvitations(false); } @Override @@ -110,131 +62,11 @@ public class InvitationsActivity extends BriarActivity adapter.clear(); } - private void loadShareables(boolean clear) { - if (shareable == FORUM) { - loadForums(clear); - } else if (shareable == BLOG) { - loadBlogs(clear); - } - } - - private void loadForums(final boolean clear) { - runOnDbThread(new Runnable() { - @Override - public void run() { - try { - Collection<InvitationItem> forums = new ArrayList<>(); - long now = System.currentTimeMillis(); - for (Forum f : forumSharingManager.getInvited()) { - boolean subscribed; - try { - forumManager.getForum(f.getId()); - subscribed = true; - } catch (NoSuchGroupException e) { - subscribed = false; - } - Collection<Contact> c = - forumSharingManager.getSharedBy(f.getId()); - forums.add( - new InvitationItem(f, subscribed, c)); - } - long duration = System.currentTimeMillis() - now; - if (LOG.isLoggable(INFO)) - LOG.info("Load took " + duration + " ms"); - displayInvitations(forums, clear); - } catch (DbException e) { - if (LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - } - } - }); - } - - private void loadBlogs(final boolean clear) { - runOnDbThread(new Runnable() { - @Override - public void run() { - try { - Collection<InvitationItem> invitations = new ArrayList<>(); - long now = System.currentTimeMillis(); - for (Blog b : blogSharingManager.getInvited()) { - boolean subscribed; - try { - blogManager.getBlog(b.getId()); - subscribed = true; - } catch (NoSuchGroupException e) { - subscribed = false; - } - Collection<Contact> c = - blogSharingManager.getSharedBy(b.getId()); - invitations.add( - new InvitationItem(b, subscribed, c)); - } - long duration = System.currentTimeMillis() - now; - if (LOG.isLoggable(INFO)) - LOG.info("Load took " + duration + " ms"); - displayInvitations(invitations, clear); - } catch (DbException e) { - if (LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - } - } - }); - } - - private void displayInvitations(final Collection<InvitationItem> invitations, - final boolean clear) { - runOnUiThread(new Runnable() { - @Override - public void run() { - if (invitations.isEmpty()) { - LOG.info("No more invitations available, finishing"); - finish(); - } else { - if (clear) adapter.clear(); - adapter.addAll(invitations); - } - } - }); - } - @Override public void eventOccurred(Event e) { if (e instanceof ContactRemovedEvent) { - LOG.info("Contact removed, reloading"); - loadShareables(true); - } else if (e instanceof GroupAddedEvent) { - GroupAddedEvent g = (GroupAddedEvent) e; - ClientId cId = g.getGroup().getClientId(); - if (cId.equals(forumManager.getClientId()) && shareable == FORUM) { - LOG.info("Forum added, reloading"); - loadShareables(false); - } else if (cId.equals(blogManager.getClientId()) && - shareable == BLOG) { - LOG.info("Blog added, reloading"); - loadShareables(true); - } - } else if (e instanceof GroupRemovedEvent) { - GroupRemovedEvent g = (GroupRemovedEvent) e; - ClientId cId = g.getGroup().getClientId(); - if (cId.equals(forumManager.getClientId()) && shareable == FORUM) { - LOG.info("Forum removed, reloading"); - loadShareables(true); - } else if (cId.equals(blogManager.getClientId()) && - shareable == BLOG) { - LOG.info("Blog removed, reloading"); - loadShareables(true); - } - } else if (e instanceof InvitationReceivedEvent) { - if (e instanceof ForumInvitationReceivedEvent && - shareable == FORUM) { - LOG.info("Forum invitation received, reloading"); - loadShareables(false); - } else if (e instanceof BlogInvitationReceivedEvent && - shareable == BLOG) { - LOG.info("Blog invitation received, reloading"); - loadShareables(false); - } + LOG.info("Contact removed, reloading..."); + loadInvitations(true); } } @@ -243,14 +75,8 @@ public class InvitationsActivity extends BriarActivity respondToInvitation(item, accept); // show toast - int res; - if (shareable == FORUM) { - res = R.string.forum_declined_toast; - if (accept) res = R.string.forum_joined_toast; - } else { - res = R.string.blogs_sharing_declined_toast; - if (accept) res = R.string.blogs_sharing_joined_toast; - } + int res = getDeclineRes(); + if (accept) res = getAcceptRes(); Toast.makeText(this, res, LENGTH_SHORT).show(); // remove item and finish if it was the last @@ -260,49 +86,32 @@ public class InvitationsActivity extends BriarActivity } } - private void respondToInvitation(final InvitationItem item, - final boolean accept) { + abstract protected InvitationAdapter getAdapter(Context ctx, + AvailableForumClickListener listener); - if (shareable == FORUM) { - respondToForumInvitation(item, accept); - } else if (shareable == BLOG) { - respondToBlogInvitation(item, accept); - } - } + abstract protected void loadInvitations(boolean clear); - private void respondToForumInvitation(final InvitationItem item, - final boolean accept) { - runOnDbThread(new Runnable() { - @Override - public void run() { - try { - Forum f = (Forum) item.getShareable(); - for (Contact c : item.getContacts()) { - forumSharingManager.respondToInvitation(f, c, accept); - } - } catch (DbException e) { - if (LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - } - } - }); - } + abstract protected void respondToInvitation(final InvitationItem item, + final boolean accept); + + abstract protected int getAcceptRes(); - private void respondToBlogInvitation(final InvitationItem item, - final boolean accept) { - runOnDbThread(new Runnable() { + abstract protected int getDeclineRes(); + + protected void displayInvitations( + final Collection<InvitationItem> invitations, final boolean clear) { + runOnUiThread(new Runnable() { @Override public void run() { - try { - Blog b = (Blog) item.getShareable(); - for (Contact c : item.getContacts()) { - blogSharingManager.respondToInvitation(b, c, accept); - } - } catch (DbException e) { - if (LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); + if (invitations.isEmpty()) { + LOG.info("No more invitations available, finishing"); + finish(); + } else { + if (clear) adapter.clear(); + adapter.addAll(invitations); } } }); } + } diff --git a/briar-android/src/org/briarproject/android/sharing/InvitationsBlogActivity.java b/briar-android/src/org/briarproject/android/sharing/InvitationsBlogActivity.java new file mode 100644 index 0000000000..a289ac2268 --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/InvitationsBlogActivity.java @@ -0,0 +1,127 @@ +package org.briarproject.android.sharing; + +import android.content.Context; + +import org.briarproject.R; +import org.briarproject.android.ActivityComponent; +import org.briarproject.api.blogs.Blog; +import org.briarproject.api.blogs.BlogManager; +import org.briarproject.api.blogs.BlogSharingManager; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.db.DbException; +import org.briarproject.api.db.NoSuchGroupException; +import org.briarproject.api.event.BlogInvitationReceivedEvent; +import org.briarproject.api.event.Event; +import org.briarproject.api.event.GroupAddedEvent; +import org.briarproject.api.event.GroupRemovedEvent; +import org.briarproject.api.sync.ClientId; + +import java.util.ArrayList; +import java.util.Collection; + +import javax.inject.Inject; + +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; +import static org.briarproject.android.sharing.InvitationAdapter.AvailableForumClickListener; + +public class InvitationsBlogActivity extends InvitationsActivity { + + // Fields that are accessed from background threads must be volatile + @Inject + protected volatile BlogManager blogManager; + @Inject + protected volatile BlogSharingManager blogSharingManager; + + @Override + public void injectActivity(ActivityComponent component) { + component.inject(this); + } + + @Override + public void eventOccurred(Event e) { + super.eventOccurred(e); + + if (e instanceof GroupAddedEvent) { + GroupAddedEvent g = (GroupAddedEvent) e; + ClientId cId = g.getGroup().getClientId(); + if (cId.equals(blogManager.getClientId())) { + LOG.info("Blog added, reloading"); + loadInvitations(false); + } + } else if (e instanceof GroupRemovedEvent) { + GroupRemovedEvent g = (GroupRemovedEvent) e; + ClientId cId = g.getGroup().getClientId(); + if (cId.equals(blogManager.getClientId())) { + LOG.info("Blog removed, reloading"); + loadInvitations(false); + } + } else if (e instanceof BlogInvitationReceivedEvent) { + LOG.info("Blog invitation received, reloading"); + loadInvitations(false); + } + } + + protected InvitationAdapter getAdapter(Context ctx, + AvailableForumClickListener listener) { + return new BlogInvitationAdapter(ctx, listener); + } + + protected void loadInvitations(final boolean clear) { + runOnDbThread(new Runnable() { + @Override + public void run() { + try { + Collection<InvitationItem> invitations = new ArrayList<>(); + long now = System.currentTimeMillis(); + for (Blog b : blogSharingManager.getInvited()) { + boolean subscribed; + try { + blogManager.getBlog(b.getId()); + subscribed = true; + } catch (NoSuchGroupException e) { + subscribed = false; + } + Collection<Contact> c = + blogSharingManager.getSharedBy(b.getId()); + invitations.add( + new InvitationItem(b, subscribed, c)); + } + long duration = System.currentTimeMillis() - now; + if (LOG.isLoggable(INFO)) + LOG.info("Load took " + duration + " ms"); + displayInvitations(invitations, clear); + } catch (DbException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } + } + }); + } + + protected void respondToInvitation(final InvitationItem item, + final boolean accept) { + runOnDbThread(new Runnable() { + @Override + public void run() { + try { + Blog b = (Blog) item.getShareable(); + for (Contact c : item.getContacts()) { + blogSharingManager.respondToInvitation(b, c, accept); + } + } catch (DbException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } + } + }); + } + + protected int getAcceptRes() { + return R.string.blogs_sharing_joined_toast; + } + + protected int getDeclineRes() { + return R.string.blogs_sharing_declined_toast; + } +} diff --git a/briar-android/src/org/briarproject/android/sharing/InvitationsForumActivity.java b/briar-android/src/org/briarproject/android/sharing/InvitationsForumActivity.java new file mode 100644 index 0000000000..a994f9faa2 --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/InvitationsForumActivity.java @@ -0,0 +1,127 @@ +package org.briarproject.android.sharing; + +import android.content.Context; + +import org.briarproject.R; +import org.briarproject.android.ActivityComponent; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.db.DbException; +import org.briarproject.api.db.NoSuchGroupException; +import org.briarproject.api.event.Event; +import org.briarproject.api.event.ForumInvitationReceivedEvent; +import org.briarproject.api.event.GroupAddedEvent; +import org.briarproject.api.event.GroupRemovedEvent; +import org.briarproject.api.forum.Forum; +import org.briarproject.api.forum.ForumManager; +import org.briarproject.api.forum.ForumSharingManager; +import org.briarproject.api.sync.ClientId; + +import java.util.ArrayList; +import java.util.Collection; + +import javax.inject.Inject; + +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; +import static org.briarproject.android.sharing.InvitationAdapter.AvailableForumClickListener; + +public class InvitationsForumActivity extends InvitationsActivity { + + // Fields that are accessed from background threads must be volatile + @Inject + protected volatile ForumManager forumManager; + @Inject + protected volatile ForumSharingManager forumSharingManager; + + @Override + public void injectActivity(ActivityComponent component) { + component.inject(this); + } + + @Override + public void eventOccurred(Event e) { + super.eventOccurred(e); + + if (e instanceof GroupAddedEvent) { + GroupAddedEvent g = (GroupAddedEvent) e; + ClientId cId = g.getGroup().getClientId(); + if (cId.equals(forumManager.getClientId())) { + LOG.info("Forum added, reloading"); + loadInvitations(false); + } + } else if (e instanceof GroupRemovedEvent) { + GroupRemovedEvent g = (GroupRemovedEvent) e; + ClientId cId = g.getGroup().getClientId(); + if (cId.equals(forumManager.getClientId())) { + LOG.info("Forum removed, reloading"); + loadInvitations(false); + } + } else if (e instanceof ForumInvitationReceivedEvent) { + LOG.info("Forum invitation received, reloading"); + loadInvitations(false); + } + } + + protected InvitationAdapter getAdapter(Context ctx, + AvailableForumClickListener listener) { + return new ForumInvitationAdapter(ctx, listener); + } + + protected void loadInvitations(final boolean clear) { + runOnDbThread(new Runnable() { + @Override + public void run() { + try { + Collection<InvitationItem> forums = new ArrayList<>(); + long now = System.currentTimeMillis(); + for (Forum f : forumSharingManager.getInvited()) { + boolean subscribed; + try { + forumManager.getForum(f.getId()); + subscribed = true; + } catch (NoSuchGroupException e) { + subscribed = false; + } + Collection<Contact> c = + forumSharingManager.getSharedBy(f.getId()); + forums.add( + new InvitationItem(f, subscribed, c)); + } + long duration = System.currentTimeMillis() - now; + if (LOG.isLoggable(INFO)) + LOG.info("Load took " + duration + " ms"); + displayInvitations(forums, clear); + } catch (DbException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } + } + }); + } + + protected void respondToInvitation(final InvitationItem item, + final boolean accept) { + runOnDbThread(new Runnable() { + @Override + public void run() { + try { + Forum f = (Forum) item.getShareable(); + for (Contact c : item.getContacts()) { + forumSharingManager.respondToInvitation(f, c, accept); + } + } catch (DbException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } + } + }); + } + + protected int getAcceptRes() { + return R.string.forum_joined_toast; + } + + protected int getDeclineRes() { + return R.string.forum_declined_toast; + } +} diff --git a/briar-android/src/org/briarproject/android/sharing/ShareActivity.java b/briar-android/src/org/briarproject/android/sharing/ShareActivity.java index be0a6e8db6..a5e59ce895 100644 --- a/briar-android/src/org/briarproject/android/sharing/ShareActivity.java +++ b/briar-android/src/org/briarproject/android/sharing/ShareActivity.java @@ -5,60 +5,50 @@ import android.os.Bundle; import android.view.View; import org.briarproject.R; -import org.briarproject.android.ActivityComponent; import org.briarproject.android.BriarActivity; import org.briarproject.android.fragment.BaseFragment; +import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.ContactId; +import org.briarproject.api.db.DbException; import org.briarproject.api.sync.GroupId; import java.util.ArrayList; import java.util.Collection; import java.util.List; -public class ShareActivity extends BriarActivity implements +public abstract class ShareActivity extends BriarActivity implements BaseFragment.BaseFragmentListener { - public final static String SHAREABLE = "shareable"; - public final static int FORUM = 1; - public final static int BLOG = 2; - final static String CONTACTS = "contacts"; - private int shareable; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_share_forum); + setContentView(R.layout.activity_share); Intent i = getIntent(); byte[] b = i.getByteArrayExtra(GROUP_ID); if (b == null) throw new IllegalStateException("No GroupId"); GroupId groupId = new GroupId(b); - shareable = i.getIntExtra(SHAREABLE, 0); - if (shareable == 0) throw new IllegalStateException("No Shareable"); - if (savedInstanceState == null) { ContactSelectorFragment contactSelectorFragment = - ContactSelectorFragment.newInstance(shareable, groupId); + ContactSelectorFragment.newInstance(groupId); getSupportFragmentManager().beginTransaction() .add(R.id.shareContainer, contactSelectorFragment) .commit(); } } - @Override - public void injectActivity(ActivityComponent component) { - component.inject(this); - } + abstract ShareMessageFragment getMessageFragment(GroupId groupId, + Collection<ContactId> contacts); - void showMessageScreen(GroupId groupId, - Collection<ContactId> contacts) { + abstract boolean isDisabled(GroupId groupId, Contact c) throws DbException; + void showMessageScreen(GroupId groupId, Collection<ContactId> contacts) { ShareMessageFragment messageFragment = - ShareMessageFragment.newInstance(shareable, groupId, contacts); + getMessageFragment(groupId, contacts); getSupportFragmentManager().beginTransaction() .setCustomAnimations(android.R.anim.fade_in, diff --git a/briar-android/src/org/briarproject/android/sharing/ShareBlogActivity.java b/briar-android/src/org/briarproject/android/sharing/ShareBlogActivity.java new file mode 100644 index 0000000000..696ea14522 --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/ShareBlogActivity.java @@ -0,0 +1,35 @@ +package org.briarproject.android.sharing; + +import org.briarproject.android.ActivityComponent; +import org.briarproject.api.blogs.BlogSharingManager; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.db.DbException; +import org.briarproject.api.sync.GroupId; + +import java.util.Collection; + +import javax.inject.Inject; + +public class ShareBlogActivity extends ShareActivity { + + @Inject + volatile BlogSharingManager blogSharingManager; + + ShareMessageFragment getMessageFragment(GroupId groupId, + Collection<ContactId> contacts) { + return ShareBlogMessageFragment.newInstance(groupId, contacts); + } + + @Override + public void injectActivity(ActivityComponent component) { + component.inject(this); + } + + /** + * This must only be called from a DbThread + */ + boolean isDisabled(GroupId groupId, Contact c) throws DbException { + return !blogSharingManager.canBeShared(groupId, c); + } +} diff --git a/briar-android/src/org/briarproject/android/sharing/ShareBlogMessageFragment.java b/briar-android/src/org/briarproject/android/sharing/ShareBlogMessageFragment.java new file mode 100644 index 0000000000..9b562424c0 --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/ShareBlogMessageFragment.java @@ -0,0 +1,81 @@ +package org.briarproject.android.sharing; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import org.briarproject.R; +import org.briarproject.android.ActivityComponent; +import org.briarproject.api.blogs.BlogSharingManager; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.db.DbException; +import org.briarproject.api.sync.GroupId; + +import java.util.Collection; + +import javax.inject.Inject; + +import static android.widget.Toast.LENGTH_SHORT; +import static java.util.logging.Level.WARNING; + +public class ShareBlogMessageFragment extends ShareMessageFragment { + + public final static String TAG = ShareBlogMessageFragment.class.getName(); + + // Fields that are accessed from background threads must be volatile + @Inject + protected volatile BlogSharingManager blogSharingManager; + + public static ShareBlogMessageFragment newInstance(GroupId groupId, + Collection<ContactId> contacts) { + + ShareBlogMessageFragment fragment = new ShareBlogMessageFragment(); + fragment.setArguments(getArguments(groupId, contacts)); + return fragment; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + setTitle(R.string.blogs_sharing_share); + + View v = super.onCreateView(inflater, container, savedInstanceState); + ui.button.setText(getString(R.string.blogs_sharing_button)); + return v; + } + + @Override + public void injectFragment(ActivityComponent component) { + component.inject(this); + } + + protected void share(final String msg) { + listener.runOnDbThread(new Runnable() { + @Override + public void run() { + try { + for (ContactId c : getContacts()) { + blogSharingManager.sendInvitation(getGroupId(), c, msg); + } + } catch (DbException e) { + sharingError(); + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } + } + }); + } + + protected void sharingError() { + runOnUiThread(new Runnable() { + @Override + public void run() { + int res = R.string.blogs_sharing_error; + Toast.makeText(getContext(), res, LENGTH_SHORT).show(); + } + }); + } +} diff --git a/briar-android/src/org/briarproject/android/sharing/ShareForumActivity.java b/briar-android/src/org/briarproject/android/sharing/ShareForumActivity.java new file mode 100644 index 0000000000..51a5d5a22a --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/ShareForumActivity.java @@ -0,0 +1,34 @@ +package org.briarproject.android.sharing; + +import org.briarproject.android.ActivityComponent; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.db.DbException; +import org.briarproject.api.forum.ForumSharingManager; +import org.briarproject.api.sync.GroupId; + +import java.util.Collection; + +import javax.inject.Inject; + +public class ShareForumActivity extends ShareActivity { + @Inject + volatile ForumSharingManager forumSharingManager; + + ShareMessageFragment getMessageFragment(GroupId groupId, + Collection<ContactId> contacts) { + return ShareForumMessageFragment.newInstance(groupId, contacts); + } + + @Override + public void injectActivity(ActivityComponent component) { + component.inject(this); + } + + /** + * This must only be called from a DbThread + */ + boolean isDisabled(GroupId groupId, Contact c) throws DbException { + return !forumSharingManager.canBeShared(groupId, c); + } +} diff --git a/briar-android/src/org/briarproject/android/sharing/ShareForumMessageFragment.java b/briar-android/src/org/briarproject/android/sharing/ShareForumMessageFragment.java new file mode 100644 index 0000000000..f24869467a --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/ShareForumMessageFragment.java @@ -0,0 +1,79 @@ +package org.briarproject.android.sharing; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import org.briarproject.R; +import org.briarproject.android.ActivityComponent; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.db.DbException; +import org.briarproject.api.forum.ForumSharingManager; +import org.briarproject.api.sync.GroupId; + +import java.util.Collection; + +import javax.inject.Inject; + +import static android.widget.Toast.LENGTH_SHORT; +import static java.util.logging.Level.WARNING; + +public class ShareForumMessageFragment extends ShareMessageFragment { + + public final static String TAG = ShareForumMessageFragment.class.getName(); + + // Fields that are accessed from background threads must be volatile + @Inject + protected volatile ForumSharingManager forumSharingManager; + + public static ShareForumMessageFragment newInstance(GroupId groupId, + Collection<ContactId> contacts) { + + ShareForumMessageFragment fragment = new ShareForumMessageFragment(); + fragment.setArguments(getArguments(groupId, contacts)); + return fragment; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + setTitle(R.string.forum_share_button); + return super.onCreateView(inflater, container, savedInstanceState); + } + + @Override + public void injectFragment(ActivityComponent component) { + component.inject(this); + } + + protected void share(final String msg) { + listener.runOnDbThread(new Runnable() { + @Override + public void run() { + try { + for (ContactId c : getContacts()) { + forumSharingManager. + sendInvitation(getGroupId(), c, msg); + } + } catch (DbException e) { + sharingError(); + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } + } + }); + } + + protected void sharingError() { + runOnUiThread(new Runnable() { + @Override + public void run() { + int res = R.string.forum_share_error; + Toast.makeText(getContext(), res, LENGTH_SHORT).show(); + } + }); + } +} diff --git a/briar-android/src/org/briarproject/android/sharing/ShareMessageFragment.java b/briar-android/src/org/briarproject/android/sharing/ShareMessageFragment.java index 9e9fcac391..3d87df3785 100644 --- a/briar-android/src/org/briarproject/android/sharing/ShareMessageFragment.java +++ b/briar-android/src/org/briarproject/android/sharing/ShareMessageFragment.java @@ -2,22 +2,17 @@ package org.briarproject.android.sharing; import android.content.Context; import android.os.Bundle; -import android.support.v7.app.ActionBar; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.EditText; -import android.widget.Toast; import org.briarproject.R; -import org.briarproject.android.ActivityComponent; import org.briarproject.android.fragment.BaseFragment; -import org.briarproject.api.blogs.BlogManager; import org.briarproject.api.blogs.BlogSharingManager; import org.briarproject.api.contact.ContactId; -import org.briarproject.api.db.DbException; import org.briarproject.api.forum.ForumSharingManager; import org.briarproject.api.sync.GroupId; @@ -27,24 +22,18 @@ import java.util.logging.Logger; import javax.inject.Inject; -import static android.widget.Toast.LENGTH_SHORT; -import static java.util.logging.Level.WARNING; -import static org.briarproject.android.sharing.ShareActivity.BLOG; import static org.briarproject.android.sharing.ShareActivity.CONTACTS; -import static org.briarproject.android.sharing.ShareActivity.FORUM; -import static org.briarproject.android.sharing.ShareActivity.SHAREABLE; import static org.briarproject.android.sharing.ShareActivity.getContactsFromIds; import static org.briarproject.api.sharing.SharingConstants.GROUP_ID; -public class ShareMessageFragment extends BaseFragment { +abstract class ShareMessageFragment extends BaseFragment { - public final static String TAG = "IntroductionMessageFragment"; + public final static String TAG = ShareMessageFragment.class.getName(); - private static final Logger LOG = - Logger.getLogger(ShareMessageFragment.class.getName()); + protected static final Logger LOG = Logger.getLogger(TAG); + protected ViewHolder ui; private ShareActivity shareActivity; - private ViewHolder ui; // Fields that are accessed from background threads must be volatile @Inject @@ -52,19 +41,15 @@ public class ShareMessageFragment extends BaseFragment { @Inject protected volatile BlogSharingManager blogSharingManager; private volatile GroupId groupId; - private volatile int shareable; private volatile Collection<ContactId> contacts; - public static ShareMessageFragment newInstance(int shareable, - GroupId groupId, Collection<ContactId> contacts) { + protected static Bundle getArguments(GroupId groupId, + Collection<ContactId> contacts) { Bundle args = new Bundle(); args.putByteArray(GROUP_ID, groupId.getBytes()); - args.putInt(SHAREABLE, shareable); args.putIntegerArrayList(CONTACTS, getContactsFromIds(contacts)); - ShareMessageFragment fragment = new ShareMessageFragment(); - fragment.setArguments(args); - return fragment; + return args; } @Override @@ -82,29 +67,16 @@ public class ShareMessageFragment extends BaseFragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - // allow for home button to act as back button + // allow for "up" button to act as back button setHasOptionsMenu(true); - // get groupID, shareable type and contactIDs from fragment arguments + // get groupID and contactIDs from fragment arguments groupId = new GroupId(getArguments().getByteArray(GROUP_ID)); - shareable = getArguments().getInt(SHAREABLE); ArrayList<Integer> intContacts = getArguments().getIntegerArrayList(CONTACTS); if (intContacts == null) throw new IllegalArgumentException(); contacts = ShareActivity.getContactsFromIntegers(intContacts); - // change toolbar text - ActionBar actionBar = shareActivity.getSupportActionBar(); - if (actionBar != null) { - if (shareable == FORUM) { - actionBar.setTitle(R.string.forum_share_button); - } else if (shareable == BLOG) { - actionBar.setTitle(R.string.blogs_sharing_button); - } else { - throw new IllegalArgumentException("Invalid Shareable Type!"); - } - } - // inflate view View v = inflater.inflate(R.layout.fragment_share_message, container, false); @@ -115,9 +87,6 @@ public class ShareMessageFragment extends BaseFragment { onButtonClick(); } }); - if (shareable == BLOG) { - ui.button.setText(getString(R.string.blogs_sharing_button)); - } return v; } @@ -138,9 +107,8 @@ public class ShareMessageFragment extends BaseFragment { return TAG; } - @Override - public void injectFragment(ActivityComponent component) { - component.inject(this); + protected void setTitle(int res) { + shareActivity.setTitle(res); } private void onButtonClick() { @@ -148,49 +116,31 @@ public class ShareMessageFragment extends BaseFragment { ui.button.setEnabled(false); String msg = ui.message.getText().toString(); - shareForum(msg); + share(msg); - // don't wait for the introduction to be made before finishing activity + // don't wait for the invitation to be made before finishing activity shareActivity.sharingSuccessful(ui.message); } - private void shareForum(final String msg) { - listener.runOnDbThread(new Runnable() { - @Override - public void run() { - try { - for (ContactId c : contacts) { - if (shareable == FORUM) { - forumSharingManager.sendInvitation(groupId, c, - msg); - } else if (shareable == BLOG) { - blogSharingManager.sendInvitation(groupId, c, msg); - } - } - } catch (DbException e) { - sharingError(); - if (LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - } - } - }); + abstract void share(final String msg); + + abstract void sharingError(); + + protected Collection<ContactId> getContacts() { + return contacts; } - private void sharingError() { - shareActivity.runOnUiThread(new Runnable() { - @Override - public void run() { - int res = R.string.forum_share_error; - if (shareable == BLOG) res = R.string.blogs_sharing_error; - Toast.makeText(shareActivity, res, LENGTH_SHORT).show(); - } - }); + protected GroupId getGroupId() { + return groupId; } - private static class ViewHolder { + protected void runOnUiThread(Runnable runnable) { + listener.runOnUiThread(runnable); + } - private final EditText message; - private final Button button; + protected static class ViewHolder { + protected final EditText message; + protected final Button button; ViewHolder(View v) { message = (EditText) v.findViewById(R.id.invitationMessageView); diff --git a/briar-android/src/org/briarproject/android/sharing/SharingStatusActivity.java b/briar-android/src/org/briarproject/android/sharing/SharingStatusActivity.java index 7d8bf5b31e..6a67448c9e 100644 --- a/briar-android/src/org/briarproject/android/sharing/SharingStatusActivity.java +++ b/briar-android/src/org/briarproject/android/sharing/SharingStatusActivity.java @@ -6,14 +6,11 @@ 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.blogs.BlogSharingManager; 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; @@ -26,11 +23,8 @@ import java.util.logging.Logger; import javax.inject.Inject; import static java.util.logging.Level.WARNING; -import static org.briarproject.android.sharing.ShareActivity.BLOG; -import static org.briarproject.android.sharing.ShareActivity.FORUM; -import static org.briarproject.android.sharing.ShareActivity.SHAREABLE; -public class SharingStatusActivity extends BriarActivity { +abstract class SharingStatusActivity extends BriarActivity { private GroupId groupId; private BriarRecyclerView sharedByList, sharedWithList; @@ -38,28 +32,21 @@ public class SharingStatusActivity extends BriarActivity { // Fields that are accessed from background threads must be volatile @Inject - protected volatile ForumSharingManager forumSharingManager; - @Inject - protected volatile BlogSharingManager blogSharingManager; - @Inject protected volatile IdentityManager identityManager; - public final static String TAG = "ForumSharingStatusActivity"; + public final static String TAG = SharingStatusActivity.class.getName(); private static final Logger LOG = Logger.getLogger(TAG); - private int shareable; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_forum_sharing_status); + setContentView(R.layout.activity_sharing_status); Intent i = getIntent(); byte[] b = i.getByteArrayExtra(GROUP_ID); if (b == null) throw new IllegalStateException("No GroupId"); groupId = new GroupId(b); - shareable = i.getIntExtra(SHAREABLE, 0); - if (shareable == 0) throw new IllegalStateException("No Shareable"); sharedByList = (BriarRecyclerView) findViewById(R.id.sharedByView); sharedByAdapter = new SharingStatusAdapter(this); @@ -94,9 +81,18 @@ public class SharingStatusActivity extends BriarActivity { } } - @Override - public void injectActivity(ActivityComponent component) { - component.inject(this); + /** + * This must only be called from the DbThread + */ + abstract protected Collection<Contact> getSharedWith() throws DbException; + + /** + * This must only be called from the DbThread + */ + abstract protected Collection<Contact> getSharedBy() throws DbException; + + protected GroupId getGroupId() { + return groupId; } private void loadSharedBy() { @@ -158,36 +154,6 @@ public class SharingStatusActivity extends BriarActivity { }); } - /** - * This must only be called from the DbThread - */ - private Collection<Contact> getSharedWith() throws DbException { - Collection<Contact> contacts; - if (shareable == FORUM) { - contacts = forumSharingManager.getSharedWith(groupId); - } else if (shareable == BLOG) { - contacts = blogSharingManager.getSharedWith(groupId); - } else { - throw new IllegalArgumentException("Unknown Shareable"); - } - return contacts; - } - - /** - * This must only be called from the DbThread - */ - private Collection<Contact> getSharedBy() throws DbException { - Collection<Contact> contacts; - if (shareable == FORUM) { - contacts = forumSharingManager.getSharedBy(groupId); - } else if (shareable == BLOG) { - contacts = blogSharingManager.getSharedBy(groupId); - } else { - throw new IllegalArgumentException("Unknown Shareable"); - } - return contacts; - } - private void displaySharedWith(final List<ContactListItem> contacts) { runOnUiThread(new Runnable() { @Override diff --git a/briar-android/src/org/briarproject/android/sharing/SharingStatusBlogActivity.java b/briar-android/src/org/briarproject/android/sharing/SharingStatusBlogActivity.java new file mode 100644 index 0000000000..5c7be6deea --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/SharingStatusBlogActivity.java @@ -0,0 +1,37 @@ +package org.briarproject.android.sharing; + +import org.briarproject.android.ActivityComponent; +import org.briarproject.api.blogs.BlogSharingManager; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.db.DbException; + +import java.util.Collection; + +import javax.inject.Inject; + +public class SharingStatusBlogActivity extends SharingStatusActivity { + + // Fields that are accessed from background threads must be volatile + @Inject + protected volatile BlogSharingManager blogSharingManager; + + @Override + public void injectActivity(ActivityComponent component) { + component.inject(this); + } + + /** + * This must only be called from the DbThread + */ + protected Collection<Contact> getSharedWith() throws DbException { + return blogSharingManager.getSharedWith(getGroupId()); + } + + /** + * This must only be called from the DbThread + */ + protected Collection<Contact> getSharedBy() throws DbException { + return blogSharingManager.getSharedBy(getGroupId()); + } + +} diff --git a/briar-android/src/org/briarproject/android/sharing/SharingStatusForumActivity.java b/briar-android/src/org/briarproject/android/sharing/SharingStatusForumActivity.java new file mode 100644 index 0000000000..ef3b333a0a --- /dev/null +++ b/briar-android/src/org/briarproject/android/sharing/SharingStatusForumActivity.java @@ -0,0 +1,37 @@ +package org.briarproject.android.sharing; + +import org.briarproject.android.ActivityComponent; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.db.DbException; +import org.briarproject.api.forum.ForumSharingManager; + +import java.util.Collection; + +import javax.inject.Inject; + +public class SharingStatusForumActivity extends SharingStatusActivity { + + // Fields that are accessed from background threads must be volatile + @Inject + protected volatile ForumSharingManager forumSharingManager; + + @Override + public void injectActivity(ActivityComponent component) { + component.inject(this); + } + + /** + * This must only be called from the DbThread + */ + protected Collection<Contact> getSharedWith() throws DbException { + return forumSharingManager.getSharedWith(getGroupId()); + } + + /** + * This must only be called from the DbThread + */ + protected Collection<Contact> getSharedBy() throws DbException { + return forumSharingManager.getSharedBy(getGroupId()); + } + +} -- GitLab