Use Inheritence for shared Forum and Blog Sharing Code

This commit is contained in:
Torsten Grote
2016-08-03 13:00:24 -03:00
parent a3b2358164
commit a4cf91fba5
29 changed files with 755 additions and 466 deletions

View File

@@ -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));
}

View File

@@ -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,80 +62,44 @@ public class InvitationsActivity extends BriarActivity
adapter.clear();
}
private void loadShareables(boolean clear) {
if (shareable == FORUM) {
loadForums(clear);
} else if (shareable == BLOG) {
loadBlogs(clear);
@Override
public void eventOccurred(Event e) {
if (e instanceof ContactRemovedEvent) {
LOG.info("Contact removed, reloading...");
loadInvitations(true);
}
}
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);
}
}
});
@Override
public void onItemClick(InvitationItem item, boolean accept) {
respondToInvitation(item, accept);
// show toast
int res = getDeclineRes();
if (accept) res = getAcceptRes();
Toast.makeText(this, res, LENGTH_SHORT).show();
// remove item and finish if it was the last
adapter.remove(item);
if (adapter.getItemCount() == 0) {
supportFinishAfterTransition();
}
}
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);
}
}
});
}
abstract protected InvitationAdapter getAdapter(Context ctx,
AvailableForumClickListener listener);
private void displayInvitations(final Collection<InvitationItem> invitations,
final boolean clear) {
abstract protected void loadInvitations(boolean clear);
abstract protected void respondToInvitation(final InvitationItem item,
final boolean accept);
abstract protected int getAcceptRes();
abstract protected int getDeclineRes();
protected void displayInvitations(
final Collection<InvitationItem> invitations, final boolean clear) {
runOnUiThread(new Runnable() {
@Override
public void run() {
@@ -198,111 +114,4 @@ public class InvitationsActivity extends BriarActivity
});
}
@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);
}
}
}
@Override
public void onItemClick(InvitationItem item, boolean accept) {
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;
}
Toast.makeText(this, res, LENGTH_SHORT).show();
// remove item and finish if it was the last
adapter.remove(item);
if (adapter.getItemCount() == 0) {
supportFinishAfterTransition();
}
}
private void respondToInvitation(final InvitationItem item,
final boolean accept) {
if (shareable == FORUM) {
respondToForumInvitation(item, accept);
} else if (shareable == BLOG) {
respondToBlogInvitation(item, accept);
}
}
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);
}
}
});
}
private void respondToBlogInvitation(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);
}
}
});
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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,

View File

@@ -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);
}
}

View File

@@ -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();
}
});
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
});
}
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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());
}
}

View File

@@ -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());
}
}