mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Controllerize invitation activities
This commit is contained in:
@@ -27,6 +27,10 @@ import org.briarproject.android.privategroup.creation.CreateGroupController;
|
||||
import org.briarproject.android.privategroup.creation.CreateGroupControllerImpl;
|
||||
import org.briarproject.android.privategroup.list.GroupListController;
|
||||
import org.briarproject.android.privategroup.list.GroupListControllerImpl;
|
||||
import org.briarproject.android.sharing.InvitationsBlogController;
|
||||
import org.briarproject.android.sharing.InvitationsBlogControllerImpl;
|
||||
import org.briarproject.android.sharing.InvitationsForumController;
|
||||
import org.briarproject.android.sharing.InvitationsForumControllerImpl;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
@@ -125,6 +129,22 @@ public class ActivityModule {
|
||||
return forumController;
|
||||
}
|
||||
|
||||
@ActivityScope
|
||||
@Provides
|
||||
protected InvitationsForumController provideInvitationsForumController(
|
||||
InvitationsForumControllerImpl invitationsForumController) {
|
||||
activity.addLifecycleController(invitationsForumController);
|
||||
return invitationsForumController;
|
||||
}
|
||||
|
||||
@ActivityScope
|
||||
@Provides
|
||||
protected InvitationsBlogController provideInvitationsBlogController(
|
||||
InvitationsBlogControllerImpl invitationsBlogController) {
|
||||
activity.addLifecycleController(invitationsBlogController);
|
||||
return invitationsBlogController;
|
||||
}
|
||||
|
||||
@ActivityScope
|
||||
@Provides
|
||||
BlogController provideBlogController(BlogControllerImpl blogController) {
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
package org.briarproject.android.sharing;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.briarproject.R;
|
||||
import org.briarproject.api.blogs.Blog;
|
||||
import org.briarproject.api.sharing.InvitationItem;
|
||||
|
||||
class BlogInvitationAdapter extends InvitationAdapter {
|
||||
|
||||
BlogInvitationAdapter(Context ctx, AvailableForumClickListener listener) {
|
||||
super(ctx, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(InvitationsViewHolder ui, int position) {
|
||||
super.onBindViewHolder(ui, position);
|
||||
InvitationItem item = getItemAt(position);
|
||||
if (item == null) return;
|
||||
|
||||
Blog blog = (Blog) item.getShareable();
|
||||
|
||||
ui.avatar.setAuthorAvatar(blog.getAuthor());
|
||||
|
||||
ui.name.setText(ctx.getString(R.string.blogs_personal_blog,
|
||||
blog.getAuthor().getName()));
|
||||
|
||||
if (item.isSubscribed()) {
|
||||
ui.subscribed.setText(ctx.getString(R.string.blogs_sharing_exists));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(InvitationItem o1, InvitationItem o2) {
|
||||
return String.CASE_INSENSITIVE_ORDER
|
||||
.compare(((Blog) o1.getShareable()).getAuthor().getName(),
|
||||
((Blog) o2.getShareable()).getAuthor().getName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package org.briarproject.android.sharing;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.briarproject.api.forum.Forum;
|
||||
import org.briarproject.api.sharing.InvitationItem;
|
||||
|
||||
class ForumInvitationAdapter extends InvitationAdapter {
|
||||
|
||||
ForumInvitationAdapter(Context ctx, AvailableForumClickListener listener) {
|
||||
super(ctx, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(InvitationsViewHolder ui, int position) {
|
||||
super.onBindViewHolder(ui, position);
|
||||
InvitationItem item = getItemAt(position);
|
||||
if (item == null) return;
|
||||
|
||||
Forum forum = (Forum) item.getShareable();
|
||||
|
||||
ui.avatar.setText(forum.getName().substring(0, 1));
|
||||
ui.avatar.setBackgroundBytes(item.getShareable().getId().getBytes());
|
||||
|
||||
ui.name.setText(forum.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(InvitationItem o1, InvitationItem o2) {
|
||||
return String.CASE_INSENSITIVE_ORDER
|
||||
.compare(((Forum) o1.getShareable()).getName(),
|
||||
((Forum) o2.getShareable()).getName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,111 +1,51 @@
|
||||
package org.briarproject.android.sharing;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.briarproject.R;
|
||||
import org.briarproject.android.util.BriarAdapter;
|
||||
import org.briarproject.android.view.TextAvatarView;
|
||||
import org.briarproject.api.contact.Contact;
|
||||
import org.briarproject.api.sharing.InvitationItem;
|
||||
import org.briarproject.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
public abstract class InvitationAdapter<I extends InvitationItem, VH extends InvitationViewHolder<I>>
|
||||
extends BriarAdapter<I, VH> {
|
||||
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.VISIBLE;
|
||||
private final InvitationClickListener<I> listener;
|
||||
|
||||
abstract class InvitationAdapter extends
|
||||
BriarAdapter<InvitationItem, InvitationAdapter.InvitationsViewHolder> {
|
||||
|
||||
private final AvailableForumClickListener listener;
|
||||
|
||||
InvitationAdapter(Context ctx, AvailableForumClickListener listener) {
|
||||
super(ctx, InvitationItem.class);
|
||||
public InvitationAdapter(Context ctx, Class<I> c,
|
||||
InvitationClickListener<I> listener) {
|
||||
super(ctx, c);
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvitationsViewHolder onCreateViewHolder(ViewGroup parent,
|
||||
int viewType) {
|
||||
|
||||
View v = LayoutInflater.from(ctx)
|
||||
.inflate(R.layout.list_item_invitations, parent, false);
|
||||
return new InvitationsViewHolder(v);
|
||||
protected View getView(ViewGroup parent) {
|
||||
return LayoutInflater.from(ctx)
|
||||
.inflate(R.layout.list_item_invitations, parent, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(InvitationsViewHolder ui, int position) {
|
||||
final InvitationItem item = getItemAt(position);
|
||||
public void onBindViewHolder(VH ui, int position) {
|
||||
final I item = getItemAt(position);
|
||||
if (item == null) return;
|
||||
|
||||
Collection<String> names = new ArrayList<>();
|
||||
for (Contact c : item.getNewSharers())
|
||||
names.add(c.getAuthor().getName());
|
||||
ui.sharedBy.setText(ctx.getString(R.string.shared_by_format,
|
||||
StringUtils.join(names, ", ")));
|
||||
|
||||
if (item.isSubscribed()) {
|
||||
ui.subscribed.setVisibility(VISIBLE);
|
||||
} else {
|
||||
ui.subscribed.setVisibility(GONE);
|
||||
}
|
||||
|
||||
ui.accept.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
listener.onItemClick(item, true);
|
||||
}
|
||||
});
|
||||
ui.decline.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
listener.onItemClick(item, false);
|
||||
}
|
||||
});
|
||||
ui.onBind(item, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(InvitationItem oldItem,
|
||||
InvitationItem newItem) {
|
||||
return oldItem.isSubscribed() == newItem.isSubscribed() &&
|
||||
oldItem.getNewSharers().equals(newItem.getNewSharers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areItemsTheSame(InvitationItem oldItem,
|
||||
InvitationItem newItem) {
|
||||
public boolean areItemsTheSame(I oldItem, I newItem) {
|
||||
return oldItem.getShareable().equals(newItem.getShareable());
|
||||
}
|
||||
|
||||
static class InvitationsViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
final TextAvatarView avatar;
|
||||
final TextView name;
|
||||
private final TextView sharedBy;
|
||||
final TextView subscribed;
|
||||
private final Button accept;
|
||||
private final Button decline;
|
||||
|
||||
private InvitationsViewHolder(View v) {
|
||||
super(v);
|
||||
|
||||
avatar = (TextAvatarView) v.findViewById(R.id.avatarView);
|
||||
name = (TextView) v.findViewById(R.id.forumNameView);
|
||||
sharedBy = (TextView) v.findViewById(R.id.sharedByView);
|
||||
subscribed = (TextView) v.findViewById(R.id.forumSubscribedView);
|
||||
accept = (Button) v.findViewById(R.id.acceptButton);
|
||||
decline = (Button) v.findViewById(R.id.declineButton);
|
||||
}
|
||||
@Override
|
||||
public int compare(I o1, I o2) {
|
||||
return String.CASE_INSENSITIVE_ORDER
|
||||
.compare((o1.getShareable()).getName(),
|
||||
(o2.getShareable()).getName());
|
||||
}
|
||||
|
||||
interface AvailableForumClickListener {
|
||||
void onItemClick(InvitationItem item, boolean accept);
|
||||
public interface InvitationClickListener<I> {
|
||||
void onItemClick(I item, boolean accept);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package org.briarproject.android.sharing;
|
||||
|
||||
import android.support.annotation.CallSuper;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.briarproject.R;
|
||||
import org.briarproject.android.sharing.InvitationAdapter.InvitationClickListener;
|
||||
import org.briarproject.android.view.TextAvatarView;
|
||||
import org.briarproject.api.sharing.InvitationItem;
|
||||
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.VISIBLE;
|
||||
|
||||
public class InvitationViewHolder<I extends InvitationItem>
|
||||
extends RecyclerView.ViewHolder {
|
||||
|
||||
private final TextAvatarView avatar;
|
||||
private final TextView name;
|
||||
protected final TextView sharedBy;
|
||||
private final TextView subscribed;
|
||||
private final Button accept;
|
||||
private final Button decline;
|
||||
|
||||
public InvitationViewHolder(View v) {
|
||||
super(v);
|
||||
|
||||
avatar = (TextAvatarView) v.findViewById(R.id.avatarView);
|
||||
name = (TextView) v.findViewById(R.id.forumNameView);
|
||||
sharedBy = (TextView) v.findViewById(R.id.sharedByView);
|
||||
subscribed = (TextView) v.findViewById(R.id.forumSubscribedView);
|
||||
accept = (Button) v.findViewById(R.id.acceptButton);
|
||||
decline = (Button) v.findViewById(R.id.declineButton);
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
public void onBind(@Nullable final I item,
|
||||
final InvitationClickListener<I> listener) {
|
||||
if (item == null) return;
|
||||
|
||||
avatar.setText(item.getShareable().getName().substring(0, 1));
|
||||
avatar.setBackgroundBytes(item.getShareable().getId().getBytes());
|
||||
|
||||
name.setText(item.getShareable().getName());
|
||||
|
||||
if (item.isSubscribed()) {
|
||||
subscribed.setVisibility(VISIBLE);
|
||||
} else {
|
||||
subscribed.setVisibility(GONE);
|
||||
}
|
||||
|
||||
accept.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
listener.onItemClick(item, true);
|
||||
}
|
||||
});
|
||||
decline.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
listener.onItemClick(item, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,39 +2,34 @@ package org.briarproject.android.sharing;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.CallSuper;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.briarproject.R;
|
||||
import org.briarproject.android.BriarActivity;
|
||||
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
||||
import org.briarproject.android.sharing.InvitationsController.InvitationListener;
|
||||
import org.briarproject.android.view.BriarRecyclerView;
|
||||
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.db.DbException;
|
||||
import org.briarproject.api.sharing.InvitationItem;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static android.widget.Toast.LENGTH_SHORT;
|
||||
import static org.briarproject.android.sharing.InvitationAdapter.AvailableForumClickListener;
|
||||
import static org.briarproject.android.sharing.InvitationAdapter.InvitationClickListener;
|
||||
|
||||
abstract class InvitationsActivity extends BriarActivity
|
||||
implements EventListener, AvailableForumClickListener {
|
||||
public abstract class InvitationsActivity<I extends InvitationItem>
|
||||
extends BriarActivity
|
||||
implements InvitationListener, InvitationClickListener<I> {
|
||||
|
||||
protected static final Logger LOG =
|
||||
Logger.getLogger(InvitationsActivity.class.getName());
|
||||
|
||||
protected InvitationAdapter adapter;
|
||||
private InvitationAdapter<I, ?> adapter;
|
||||
private BriarRecyclerView list;
|
||||
|
||||
@Inject
|
||||
EventBus eventBus;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle state) {
|
||||
super.onCreate(state);
|
||||
@@ -42,7 +37,6 @@ abstract class InvitationsActivity extends BriarActivity
|
||||
setContentView(R.layout.list);
|
||||
|
||||
adapter = getAdapter(this, this);
|
||||
|
||||
list = (BriarRecyclerView) findViewById(R.id.list);
|
||||
if (list != null) {
|
||||
list.setLayoutManager(new LinearLayoutManager(this));
|
||||
@@ -50,32 +44,24 @@ abstract class InvitationsActivity extends BriarActivity
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected InvitationAdapter<I, ?> getAdapter(Context ctx,
|
||||
InvitationClickListener listener);
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
eventBus.addListener(this);
|
||||
loadInvitations(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
eventBus.removeListener(this);
|
||||
adapter.clear();
|
||||
list.showProgressBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CallSuper
|
||||
public void eventOccurred(Event e) {
|
||||
if (e instanceof ContactRemovedEvent) {
|
||||
LOG.info("Contact removed, reloading...");
|
||||
loadInvitations(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(InvitationItem item, boolean accept) {
|
||||
public void onItemClick(I item, boolean accept) {
|
||||
respondToInvitation(item, accept);
|
||||
|
||||
// show toast
|
||||
@@ -91,26 +77,58 @@ abstract class InvitationsActivity extends BriarActivity
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected InvitationAdapter getAdapter(Context ctx,
|
||||
AvailableForumClickListener listener);
|
||||
@Override
|
||||
public void loadInvitations(final boolean clear) {
|
||||
final int revision = adapter.getRevision();
|
||||
getController().loadInvitations(clear,
|
||||
new UiResultExceptionHandler<Collection<I>, DbException>(
|
||||
this) {
|
||||
@Override
|
||||
public void onResultUi(Collection<I> items) {
|
||||
displayInvitations(revision, items, clear);
|
||||
}
|
||||
|
||||
abstract protected void loadInvitations(boolean clear);
|
||||
@Override
|
||||
public void onExceptionUi(DbException exception) {
|
||||
// TODO proper error handling
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
abstract protected void respondToInvitation(final InvitationItem item,
|
||||
final boolean accept);
|
||||
abstract protected InvitationsController<I> getController();
|
||||
|
||||
protected void respondToInvitation(final I item,
|
||||
final boolean accept) {
|
||||
getController().respondToInvitation(item, accept,
|
||||
new UiResultExceptionHandler<Void, DbException>(this) {
|
||||
@Override
|
||||
public void onResultUi(Void result) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExceptionUi(DbException exception) {
|
||||
// TODO proper error handling
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@StringRes
|
||||
abstract protected int getAcceptRes();
|
||||
|
||||
@StringRes
|
||||
abstract protected int getDeclineRes();
|
||||
|
||||
protected void displayInvitations(final int revision,
|
||||
final Collection<InvitationItem> invitations, final boolean clear) {
|
||||
final Collection<I> invitations, final boolean clear) {
|
||||
runOnUiThreadUnlessDestroyed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (invitations.isEmpty()) {
|
||||
LOG.info("No more invitations available, finishing");
|
||||
finish();
|
||||
supportFinishAfterTransition();
|
||||
} else if (revision == adapter.getRevision()) {
|
||||
adapter.incrementRevision();
|
||||
if (clear) adapter.setItems(invitations);
|
||||
|
||||
@@ -4,34 +4,17 @@ 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.event.BlogInvitationReceivedEvent;
|
||||
import org.briarproject.api.event.Event;
|
||||
import org.briarproject.api.event.GroupAddedEvent;
|
||||
import org.briarproject.api.event.GroupRemovedEvent;
|
||||
import org.briarproject.api.sharing.InvitationItem;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import org.briarproject.api.sharing.SharingInvitationItem;
|
||||
|
||||
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;
|
||||
import static org.briarproject.android.sharing.InvitationAdapter.InvitationClickListener;
|
||||
|
||||
public class InvitationsBlogActivity extends InvitationsActivity {
|
||||
public class InvitationsBlogActivity
|
||||
extends InvitationsActivity<SharingInvitationItem> {
|
||||
|
||||
// Fields that are accessed from background threads must be volatile
|
||||
@Inject
|
||||
volatile BlogManager blogManager;
|
||||
@Inject
|
||||
volatile BlogSharingManager blogSharingManager;
|
||||
InvitationsBlogController controller;
|
||||
|
||||
@Override
|
||||
public void injectActivity(ActivityComponent component) {
|
||||
@@ -39,75 +22,14 @@ public class InvitationsBlogActivity extends InvitationsActivity {
|
||||
}
|
||||
|
||||
@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 InvitationsController<SharingInvitationItem> getController() {
|
||||
return controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InvitationAdapter getAdapter(Context ctx,
|
||||
AvailableForumClickListener listener) {
|
||||
return new BlogInvitationAdapter(ctx, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadInvitations(final boolean clear) {
|
||||
final int revision = adapter.getRevision();
|
||||
runOnDbThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Collection<InvitationItem> invitations = new ArrayList<>();
|
||||
long now = System.currentTimeMillis();
|
||||
invitations.addAll(blogSharingManager.getInvitations());
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Load took " + duration + " ms");
|
||||
displayInvitations(revision, invitations, clear);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
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.getNewSharers()) {
|
||||
// TODO: What happens if a contact has been removed?
|
||||
blogSharingManager.respondToInvitation(b, c, accept);
|
||||
}
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
protected InvitationAdapter<SharingInvitationItem, ?> getAdapter(
|
||||
Context ctx, InvitationClickListener listener) {
|
||||
return new SharingInvitationAdapter(ctx, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -119,4 +41,5 @@ public class InvitationsBlogActivity extends InvitationsActivity {
|
||||
protected int getDeclineRes() {
|
||||
return R.string.blogs_sharing_declined_toast;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.briarproject.android.sharing;
|
||||
|
||||
import org.briarproject.api.sharing.SharingInvitationItem;
|
||||
|
||||
public interface InvitationsBlogController
|
||||
extends InvitationsController<SharingInvitationItem> {
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package org.briarproject.android.sharing;
|
||||
|
||||
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
||||
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.DatabaseExecutor;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.event.BlogInvitationReceivedEvent;
|
||||
import org.briarproject.api.event.Event;
|
||||
import org.briarproject.api.event.EventBus;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.sharing.SharingInvitationItem;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.logging.Level.WARNING;
|
||||
|
||||
public class InvitationsBlogControllerImpl
|
||||
extends InvitationsControllerImpl<SharingInvitationItem>
|
||||
implements InvitationsBlogController {
|
||||
|
||||
private final BlogManager blogManager;
|
||||
private final BlogSharingManager blogSharingManager;
|
||||
|
||||
@Inject
|
||||
InvitationsBlogControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
||||
LifecycleManager lifecycleManager, EventBus eventBus,
|
||||
BlogManager blogManager, BlogSharingManager blogSharingManager) {
|
||||
super(dbExecutor, lifecycleManager, eventBus);
|
||||
this.blogManager = blogManager;
|
||||
this.blogSharingManager = blogSharingManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eventOccurred(Event e) {
|
||||
super.eventOccurred(e);
|
||||
|
||||
if (e instanceof BlogInvitationReceivedEvent) {
|
||||
LOG.info("Blog invitation received, reloading");
|
||||
listener.loadInvitations(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClientId getClientId() {
|
||||
return blogManager.getClientId();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<SharingInvitationItem> getInvitations() throws DbException {
|
||||
return blogSharingManager.getInvitations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void respondToInvitation(final SharingInvitationItem item,
|
||||
final boolean accept,
|
||||
final ResultExceptionHandler<Void, DbException> handler) {
|
||||
runOnDbThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Blog f = (Blog) item.getShareable();
|
||||
for (Contact c : item.getNewSharers()) {
|
||||
// TODO: What happens if a contact has been removed?
|
||||
blogSharingManager.respondToInvitation(f, c, accept);
|
||||
}
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
handler.onException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.briarproject.android.sharing;
|
||||
|
||||
import org.briarproject.android.controller.ActivityLifecycleController;
|
||||
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.sharing.InvitationItem;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface InvitationsController<I extends InvitationItem>
|
||||
extends ActivityLifecycleController {
|
||||
|
||||
void loadInvitations(boolean clear,
|
||||
ResultExceptionHandler<Collection<I>, DbException> handler);
|
||||
|
||||
void respondToInvitation(I item, boolean accept,
|
||||
ResultExceptionHandler<Void, DbException> handler);
|
||||
|
||||
interface InvitationListener {
|
||||
|
||||
void loadInvitations(boolean clear);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package org.briarproject.android.sharing;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.annotation.CallSuper;
|
||||
|
||||
import org.briarproject.android.controller.DbControllerImpl;
|
||||
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
||||
import org.briarproject.api.db.DatabaseExecutor;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.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.GroupAddedEvent;
|
||||
import org.briarproject.api.event.GroupRemovedEvent;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.sharing.InvitationItem;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
|
||||
public abstract class InvitationsControllerImpl<I extends InvitationItem>
|
||||
extends DbControllerImpl
|
||||
implements InvitationsController<I>, EventListener {
|
||||
|
||||
protected static final Logger LOG =
|
||||
Logger.getLogger(InvitationsControllerImpl.class.getName());
|
||||
|
||||
private final EventBus eventBus;
|
||||
protected InvitationListener listener;
|
||||
|
||||
public InvitationsControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
||||
LifecycleManager lifecycleManager, EventBus eventBus) {
|
||||
super(dbExecutor, lifecycleManager);
|
||||
this.eventBus = eventBus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreate(Activity activity) {
|
||||
listener = (InvitationListener) activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStart() {
|
||||
eventBus.addListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStop() {
|
||||
eventBus.removeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityDestroy() {
|
||||
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
@Override
|
||||
public void eventOccurred(Event e) {
|
||||
if (e instanceof ContactRemovedEvent) {
|
||||
LOG.info("Contact removed, reloading...");
|
||||
listener.loadInvitations(true);
|
||||
} else if (e instanceof GroupAddedEvent) {
|
||||
GroupAddedEvent g = (GroupAddedEvent) e;
|
||||
ClientId cId = g.getGroup().getClientId();
|
||||
if (cId.equals(getClientId())) {
|
||||
LOG.info("Group added, reloading");
|
||||
listener.loadInvitations(false);
|
||||
}
|
||||
} else if (e instanceof GroupRemovedEvent) {
|
||||
GroupRemovedEvent g = (GroupRemovedEvent) e;
|
||||
ClientId cId = g.getGroup().getClientId();
|
||||
if (cId.equals(getClientId())) {
|
||||
LOG.info("Group removed, reloading");
|
||||
listener.loadInvitations(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract ClientId getClientId();
|
||||
|
||||
@Override
|
||||
public void loadInvitations(final boolean clear,
|
||||
final ResultExceptionHandler<Collection<I>, DbException> handler) {
|
||||
runOnDbThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Collection<I> invitations = new ArrayList<>();
|
||||
try {
|
||||
long now = System.currentTimeMillis();
|
||||
invitations.addAll(getInvitations());
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(
|
||||
"Loading invitations took " + duration + " ms");
|
||||
handler.onResult(invitations);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
handler.onException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@DatabaseExecutor
|
||||
protected abstract Collection<I> getInvitations() throws DbException;
|
||||
|
||||
}
|
||||
@@ -4,34 +4,17 @@ 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.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.sharing.InvitationItem;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import org.briarproject.api.sharing.SharingInvitationItem;
|
||||
|
||||
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;
|
||||
import static org.briarproject.android.sharing.InvitationAdapter.InvitationClickListener;
|
||||
|
||||
public class InvitationsForumActivity extends InvitationsActivity {
|
||||
public class InvitationsForumActivity
|
||||
extends InvitationsActivity<SharingInvitationItem> {
|
||||
|
||||
// Fields that are accessed from background threads must be volatile
|
||||
@Inject
|
||||
volatile ForumManager forumManager;
|
||||
@Inject
|
||||
volatile ForumSharingManager forumSharingManager;
|
||||
InvitationsForumController controller;
|
||||
|
||||
@Override
|
||||
public void injectActivity(ActivityComponent component) {
|
||||
@@ -39,75 +22,14 @@ public class InvitationsForumActivity extends InvitationsActivity {
|
||||
}
|
||||
|
||||
@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 InvitationsController<SharingInvitationItem> getController() {
|
||||
return controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InvitationAdapter getAdapter(Context ctx,
|
||||
AvailableForumClickListener listener) {
|
||||
return new ForumInvitationAdapter(ctx, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadInvitations(final boolean clear) {
|
||||
final int revision = adapter.getRevision();
|
||||
runOnDbThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Collection<InvitationItem> invitations = new ArrayList<>();
|
||||
long now = System.currentTimeMillis();
|
||||
invitations.addAll(forumSharingManager.getInvitations());
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Load took " + duration + " ms");
|
||||
displayInvitations(revision, invitations, clear);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
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.getNewSharers()) {
|
||||
// TODO: What happens if a contact has been removed?
|
||||
forumSharingManager.respondToInvitation(f, c, accept);
|
||||
}
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
protected InvitationAdapter<SharingInvitationItem, ?> getAdapter(
|
||||
Context ctx, InvitationClickListener listener) {
|
||||
return new SharingInvitationAdapter(ctx, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -119,4 +41,5 @@ public class InvitationsForumActivity extends InvitationsActivity {
|
||||
protected int getDeclineRes() {
|
||||
return R.string.forum_declined_toast;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.briarproject.android.sharing;
|
||||
|
||||
import org.briarproject.api.sharing.SharingInvitationItem;
|
||||
|
||||
public interface InvitationsForumController
|
||||
extends InvitationsController<SharingInvitationItem> {
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package org.briarproject.android.sharing;
|
||||
|
||||
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
||||
import org.briarproject.api.contact.Contact;
|
||||
import org.briarproject.api.db.DatabaseExecutor;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.event.Event;
|
||||
import org.briarproject.api.event.EventBus;
|
||||
import org.briarproject.api.event.ForumInvitationReceivedEvent;
|
||||
import org.briarproject.api.forum.Forum;
|
||||
import org.briarproject.api.forum.ForumManager;
|
||||
import org.briarproject.api.forum.ForumSharingManager;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.sharing.SharingInvitationItem;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.logging.Level.WARNING;
|
||||
|
||||
public class InvitationsForumControllerImpl
|
||||
extends InvitationsControllerImpl<SharingInvitationItem>
|
||||
implements InvitationsForumController {
|
||||
|
||||
private final ForumManager forumManager;
|
||||
private final ForumSharingManager forumSharingManager;
|
||||
|
||||
@Inject
|
||||
InvitationsForumControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
||||
LifecycleManager lifecycleManager, EventBus eventBus,
|
||||
ForumManager forumManager,
|
||||
ForumSharingManager forumSharingManager) {
|
||||
super(dbExecutor, lifecycleManager, eventBus);
|
||||
this.forumManager = forumManager;
|
||||
this.forumSharingManager = forumSharingManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eventOccurred(Event e) {
|
||||
super.eventOccurred(e);
|
||||
|
||||
if (e instanceof ForumInvitationReceivedEvent) {
|
||||
LOG.info("Forum invitation received, reloading");
|
||||
listener.loadInvitations(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClientId getClientId() {
|
||||
return forumManager.getClientId();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<SharingInvitationItem> getInvitations() throws DbException {
|
||||
return forumSharingManager.getInvitations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void respondToInvitation(final SharingInvitationItem item,
|
||||
final boolean accept,
|
||||
final ResultExceptionHandler<Void, DbException> handler) {
|
||||
runOnDbThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Forum f = (Forum) item.getShareable();
|
||||
for (Contact c : item.getNewSharers()) {
|
||||
// TODO: What happens if a contact has been removed?
|
||||
forumSharingManager.respondToInvitation(f, c, accept);
|
||||
}
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
handler.onException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.briarproject.android.sharing;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.briarproject.api.sharing.SharingInvitationItem;
|
||||
|
||||
class SharingInvitationAdapter extends
|
||||
InvitationAdapter<SharingInvitationItem, SharingInvitationViewHolder> {
|
||||
|
||||
SharingInvitationAdapter(Context ctx, InvitationClickListener listener) {
|
||||
super(ctx, SharingInvitationItem.class, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SharingInvitationViewHolder onCreateViewHolder(
|
||||
ViewGroup parent,
|
||||
int viewType) {
|
||||
return new SharingInvitationViewHolder(getView(parent));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(SharingInvitationItem oldItem,
|
||||
SharingInvitationItem newItem) {
|
||||
return oldItem.isSubscribed() == newItem.isSubscribed() &&
|
||||
oldItem.getNewSharers().equals(newItem.getNewSharers());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.briarproject.android.sharing;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
|
||||
import org.briarproject.R;
|
||||
import org.briarproject.api.contact.Contact;
|
||||
import org.briarproject.api.sharing.SharingInvitationItem;
|
||||
import org.briarproject.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
public class SharingInvitationViewHolder
|
||||
extends InvitationViewHolder<SharingInvitationItem> {
|
||||
|
||||
public SharingInvitationViewHolder(View v) {
|
||||
super(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(@Nullable final SharingInvitationItem item,
|
||||
final InvitationAdapter.InvitationClickListener<SharingInvitationItem> listener) {
|
||||
super.onBind(item, listener);
|
||||
if (item == null) return;
|
||||
|
||||
Collection<String> names = new ArrayList<>();
|
||||
for (Contact c : item.getNewSharers())
|
||||
names.add(c.getAuthor().getName());
|
||||
sharedBy.setText(
|
||||
sharedBy.getContext().getString(R.string.shared_by_format,
|
||||
StringUtils.join(names, ", ")));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user