mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 13:49:53 +01:00
Merge branch 'contact-selector-controller' into 'master'
Add a controller for contact selection lists See merge request !401
This commit is contained in:
@@ -33,17 +33,19 @@ import org.briarproject.android.privategroup.creation.CreateGroupActivity;
|
|||||||
import org.briarproject.android.privategroup.creation.CreateGroupFragment;
|
import org.briarproject.android.privategroup.creation.CreateGroupFragment;
|
||||||
import org.briarproject.android.privategroup.creation.CreateGroupMessageFragment;
|
import org.briarproject.android.privategroup.creation.CreateGroupMessageFragment;
|
||||||
import org.briarproject.android.privategroup.creation.GroupInviteActivity;
|
import org.briarproject.android.privategroup.creation.GroupInviteActivity;
|
||||||
|
import org.briarproject.android.privategroup.creation.GroupInviteFragment;
|
||||||
import org.briarproject.android.privategroup.invitation.GroupInvitationActivity;
|
import org.briarproject.android.privategroup.invitation.GroupInvitationActivity;
|
||||||
import org.briarproject.android.privategroup.list.GroupListFragment;
|
import org.briarproject.android.privategroup.list.GroupListFragment;
|
||||||
import org.briarproject.android.privategroup.memberlist.GroupMemberListActivity;
|
import org.briarproject.android.privategroup.memberlist.GroupMemberListActivity;
|
||||||
import org.briarproject.android.sharing.BlogInvitationActivity;
|
import org.briarproject.android.sharing.BlogInvitationActivity;
|
||||||
import org.briarproject.android.sharing.BlogSharingStatusActivity;
|
import org.briarproject.android.sharing.BlogSharingStatusActivity;
|
||||||
import org.briarproject.android.sharing.ContactSelectorFragment;
|
|
||||||
import org.briarproject.android.sharing.ForumInvitationActivity;
|
import org.briarproject.android.sharing.ForumInvitationActivity;
|
||||||
import org.briarproject.android.sharing.ForumSharingStatusActivity;
|
import org.briarproject.android.sharing.ForumSharingStatusActivity;
|
||||||
import org.briarproject.android.sharing.ShareBlogActivity;
|
import org.briarproject.android.sharing.ShareBlogActivity;
|
||||||
|
import org.briarproject.android.sharing.ShareBlogFragment;
|
||||||
import org.briarproject.android.sharing.ShareBlogMessageFragment;
|
import org.briarproject.android.sharing.ShareBlogMessageFragment;
|
||||||
import org.briarproject.android.sharing.ShareForumActivity;
|
import org.briarproject.android.sharing.ShareForumActivity;
|
||||||
|
import org.briarproject.android.sharing.ShareForumFragment;
|
||||||
import org.briarproject.android.sharing.ShareForumMessageFragment;
|
import org.briarproject.android.sharing.ShareForumMessageFragment;
|
||||||
import org.thoughtcrime.securesms.components.emoji.EmojiProvider;
|
import org.thoughtcrime.securesms.components.emoji.EmojiProvider;
|
||||||
import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel;
|
import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel;
|
||||||
@@ -142,6 +144,8 @@ public interface ActivityComponent {
|
|||||||
|
|
||||||
void inject(GroupListFragment fragment);
|
void inject(GroupListFragment fragment);
|
||||||
|
|
||||||
|
void inject(GroupInviteFragment fragment);
|
||||||
|
|
||||||
void inject(ForumListFragment fragment);
|
void inject(ForumListFragment fragment);
|
||||||
|
|
||||||
void inject(FeedFragment fragment);
|
void inject(FeedFragment fragment);
|
||||||
@@ -152,10 +156,12 @@ public interface ActivityComponent {
|
|||||||
|
|
||||||
void inject(ContactChooserFragment fragment);
|
void inject(ContactChooserFragment fragment);
|
||||||
|
|
||||||
void inject(ContactSelectorFragment fragment);
|
void inject(ShareForumFragment fragment);
|
||||||
|
|
||||||
void inject(ShareForumMessageFragment fragment);
|
void inject(ShareForumMessageFragment fragment);
|
||||||
|
|
||||||
|
void inject(ShareBlogFragment fragment);
|
||||||
|
|
||||||
void inject(ShareBlogMessageFragment fragment);
|
void inject(ShareBlogMessageFragment fragment);
|
||||||
|
|
||||||
void inject(IntroductionMessageFragment fragment);
|
void inject(IntroductionMessageFragment fragment);
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ import org.briarproject.android.sharing.BlogInvitationController;
|
|||||||
import org.briarproject.android.sharing.BlogInvitationControllerImpl;
|
import org.briarproject.android.sharing.BlogInvitationControllerImpl;
|
||||||
import org.briarproject.android.sharing.ForumInvitationController;
|
import org.briarproject.android.sharing.ForumInvitationController;
|
||||||
import org.briarproject.android.sharing.ForumInvitationControllerImpl;
|
import org.briarproject.android.sharing.ForumInvitationControllerImpl;
|
||||||
|
import org.briarproject.android.sharing.ShareBlogController;
|
||||||
|
import org.briarproject.android.sharing.ShareBlogControllerImpl;
|
||||||
|
import org.briarproject.android.sharing.ShareForumController;
|
||||||
|
import org.briarproject.android.sharing.ShareForumControllerImpl;
|
||||||
|
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
@@ -148,6 +152,13 @@ public class ActivityModule {
|
|||||||
return forumController;
|
return forumController;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ActivityScope
|
||||||
|
@Provides
|
||||||
|
ShareForumController provideShareForumController(
|
||||||
|
ShareForumControllerImpl shareForumController) {
|
||||||
|
return shareForumController;
|
||||||
|
}
|
||||||
|
|
||||||
@ActivityScope
|
@ActivityScope
|
||||||
@Provides
|
@Provides
|
||||||
protected ForumInvitationController provideInvitationForumController(
|
protected ForumInvitationController provideInvitationForumController(
|
||||||
@@ -171,6 +182,13 @@ public class ActivityModule {
|
|||||||
return blogController;
|
return blogController;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ActivityScope
|
||||||
|
@Provides
|
||||||
|
ShareBlogController provideShareBlogController(
|
||||||
|
ShareBlogControllerImpl shareBlogController) {
|
||||||
|
return shareBlogController;
|
||||||
|
}
|
||||||
|
|
||||||
@ActivityScope
|
@ActivityScope
|
||||||
@Provides
|
@Provides
|
||||||
FeedController provideFeedController(FeedControllerImpl feedController) {
|
FeedController provideFeedController(FeedControllerImpl feedController) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.briarproject.android;
|
|||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
@@ -31,7 +32,7 @@ public abstract class BaseActivity extends AppCompatActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE);
|
if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE);
|
||||||
|
|||||||
@@ -39,10 +39,8 @@ public abstract class BaseContactListAdapter<I extends ContactItem, VH extends C
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean areContentsTheSame(I c1, I c2) {
|
public boolean areContentsTheSame(ContactItem c1, ContactItem c2) {
|
||||||
// check for all properties that influence visual
|
return true;
|
||||||
// representation of contact
|
|
||||||
return c1.isConnected() == c2.isConnected();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int findItemPosition(ContactId c) {
|
int findItemPosition(ContactId c) {
|
||||||
|
|||||||
@@ -11,23 +11,12 @@ public class ContactItem {
|
|||||||
|
|
||||||
private final Contact contact;
|
private final Contact contact;
|
||||||
|
|
||||||
private boolean connected;
|
public ContactItem(Contact contact) {
|
||||||
|
|
||||||
public ContactItem(Contact contact, boolean connected) {
|
|
||||||
this.contact = contact;
|
this.contact = contact;
|
||||||
this.connected = connected;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Contact getContact() {
|
public Contact getContact() {
|
||||||
return contact;
|
return contact;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isConnected() {
|
|
||||||
return connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setConnected(boolean connected) {
|
|
||||||
this.connected = connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class ContactListAdapter extends
|
|||||||
if (c1.getTimestamp() != c2.getTimestamp()) {
|
if (c1.getTimestamp() != c2.getTimestamp()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return super.areContentsTheSame(c1, c2);
|
return c1.isConnected() == c2.isConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -10,13 +10,14 @@ import javax.annotation.concurrent.NotThreadSafe;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class ContactListItem extends ContactItem {
|
public class ContactListItem extends ContactItem {
|
||||||
|
|
||||||
private boolean empty;
|
private boolean connected, empty;
|
||||||
private long timestamp;
|
private long timestamp;
|
||||||
private int unread;
|
private int unread;
|
||||||
|
|
||||||
public ContactListItem(Contact contact, boolean connected,
|
public ContactListItem(Contact contact, boolean connected,
|
||||||
GroupCount count) {
|
GroupCount count) {
|
||||||
super(contact, connected);
|
super(contact);
|
||||||
|
this.connected = connected;
|
||||||
this.empty = count.getMsgCount() == 0;
|
this.empty = count.getMsgCount() == 0;
|
||||||
this.unread = count.getUnreadCount();
|
this.unread = count.getUnreadCount();
|
||||||
this.timestamp = count.getLatestMsgTime();
|
this.timestamp = count.getLatestMsgTime();
|
||||||
@@ -29,6 +30,14 @@ public class ContactListItem extends ContactItem {
|
|||||||
unread++;
|
unread++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isConnected() {
|
||||||
|
return connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setConnected(boolean connected) {
|
||||||
|
this.connected = connected;
|
||||||
|
}
|
||||||
|
|
||||||
boolean isEmpty() {
|
boolean isEmpty() {
|
||||||
return empty;
|
return empty;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package org.briarproject.android.contactselection;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import org.briarproject.android.contact.BaseContactListAdapter;
|
||||||
|
import org.briarproject.android.contact.ContactItemViewHolder;
|
||||||
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
public abstract class BaseContactSelectorAdapter<I extends SelectableContactItem, H extends ContactItemViewHolder<I>>
|
||||||
|
extends BaseContactListAdapter<I, H> {
|
||||||
|
|
||||||
|
BaseContactSelectorAdapter(Context context, Class<I> c,
|
||||||
|
OnContactClickListener<I> listener) {
|
||||||
|
super(context, c, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<ContactId> getSelectedContactIds() {
|
||||||
|
Collection<ContactId> selected = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < items.size(); i++) {
|
||||||
|
SelectableContactItem item = items.get(i);
|
||||||
|
if (item.isSelected()) selected.add(item.getContact().getId());
|
||||||
|
}
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
package org.briarproject.android.contactselection;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.CallSuper;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.transition.Fade;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import org.briarproject.R;
|
||||||
|
import org.briarproject.android.contact.BaseContactListAdapter.OnContactClickListener;
|
||||||
|
import org.briarproject.android.contact.ContactItemViewHolder;
|
||||||
|
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
||||||
|
import org.briarproject.android.fragment.BaseFragment;
|
||||||
|
import org.briarproject.android.view.BriarRecyclerView;
|
||||||
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.db.DbException;
|
||||||
|
import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
|
||||||
|
import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import static org.briarproject.android.contactselection.ContactSelectorActivity.CONTACTS;
|
||||||
|
import static org.briarproject.android.contactselection.ContactSelectorActivity.getContactsFromIds;
|
||||||
|
import static org.briarproject.android.contactselection.ContactSelectorActivity.getContactsFromIntegers;
|
||||||
|
import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
|
||||||
|
|
||||||
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
|
public abstract class BaseContactSelectorFragment<I extends SelectableContactItem, H extends ContactItemViewHolder<I>>
|
||||||
|
extends BaseFragment
|
||||||
|
implements OnContactClickListener<I> {
|
||||||
|
|
||||||
|
protected BriarRecyclerView list;
|
||||||
|
protected BaseContactSelectorAdapter<I, H> adapter;
|
||||||
|
protected Collection<ContactId> selectedContacts = new ArrayList<>();
|
||||||
|
protected ContactSelectorListener<I> listener;
|
||||||
|
|
||||||
|
private GroupId groupId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
listener = (ContactSelectorListener<I>) context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
Bundle args = getArguments();
|
||||||
|
byte[] b = args.getByteArray(GROUP_ID);
|
||||||
|
if (b == null) throw new IllegalStateException("No GroupId");
|
||||||
|
groupId = new GroupId(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@CallSuper
|
||||||
|
public View onCreateView(LayoutInflater inflater,
|
||||||
|
@Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
|
||||||
|
View contentView = inflater.inflate(R.layout.list, container, false);
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= 21) {
|
||||||
|
setExitTransition(new Fade());
|
||||||
|
}
|
||||||
|
|
||||||
|
list = (BriarRecyclerView) contentView.findViewById(R.id.list);
|
||||||
|
list.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||||
|
list.setEmptyText(getString(R.string.no_contacts_selector));
|
||||||
|
|
||||||
|
// restore selected contacts if available
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
ArrayList<Integer> intContacts =
|
||||||
|
savedInstanceState.getIntegerArrayList(CONTACTS);
|
||||||
|
if (intContacts != null) {
|
||||||
|
selectedContacts = getContactsFromIntegers(intContacts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contentView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
loadContacts(selectedContacts);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
adapter.clear();
|
||||||
|
list.showProgressBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
if (adapter != null) {
|
||||||
|
selectedContacts = adapter.getSelectedContactIds();
|
||||||
|
outState.putIntegerArrayList(CONTACTS,
|
||||||
|
getContactsFromIds(selectedContacts));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemClick(View view, I item) {
|
||||||
|
item.toggleSelected();
|
||||||
|
adapter.notifyItemChanged(adapter.findItemPosition(item), item);
|
||||||
|
onSelectionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadContacts(final Collection<ContactId> selection) {
|
||||||
|
getController().loadContacts(groupId, selection,
|
||||||
|
new UiResultExceptionHandler<Collection<I>, DbException>(
|
||||||
|
this) {
|
||||||
|
@Override
|
||||||
|
public void onResultUi(Collection<I> contacts) {
|
||||||
|
if (contacts.isEmpty()) list.showData();
|
||||||
|
else adapter.addAll(contacts);
|
||||||
|
onSelectionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onExceptionUi(DbException exception) {
|
||||||
|
// TODO error handling
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void onSelectionChanged();
|
||||||
|
|
||||||
|
protected abstract ContactSelectorController<I> getController();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,34 +1,45 @@
|
|||||||
package org.briarproject.android.sharing;
|
package org.briarproject.android.contactselection;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.CallSuper;
|
import android.support.annotation.CallSuper;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.BriarActivity;
|
import org.briarproject.android.BriarActivity;
|
||||||
import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener;
|
import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
|
||||||
|
import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class ContactSelectorActivity extends BriarActivity implements
|
@MethodsNotNullByDefault
|
||||||
BaseFragmentListener, ContactSelectorListener {
|
@ParametersNotNullByDefault
|
||||||
|
public abstract class ContactSelectorActivity<I extends SelectableContactItem>
|
||||||
|
extends BriarActivity
|
||||||
|
implements BaseFragmentListener, ContactSelectorListener<I> {
|
||||||
|
|
||||||
final static String CONTACTS = "contacts";
|
final static String CONTACTS = "contacts";
|
||||||
|
|
||||||
|
// Subclasses may initialise the group ID in different places
|
||||||
protected GroupId groupId;
|
protected GroupId groupId;
|
||||||
protected Collection<ContactId> contacts;
|
protected Collection<ContactId> contacts;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle bundle) {
|
public void onCreate(@Nullable Bundle bundle) {
|
||||||
super.onCreate(bundle);
|
super.onCreate(bundle);
|
||||||
|
|
||||||
setContentView(R.layout.activity_fragment_container);
|
setContentView(R.layout.activity_fragment_container);
|
||||||
|
|
||||||
if (bundle != null) {
|
if (bundle != null) {
|
||||||
|
// restore group ID if it was saved
|
||||||
|
byte[] groupBytes = bundle.getByteArray(GROUP_ID);
|
||||||
|
if (groupBytes != null) groupId = new GroupId(groupBytes);
|
||||||
|
// restore selected contacts if a selection was saved
|
||||||
ArrayList<Integer> intContacts =
|
ArrayList<Integer> intContacts =
|
||||||
bundle.getIntegerArrayList(CONTACTS);
|
bundle.getIntegerArrayList(CONTACTS);
|
||||||
if (intContacts != null) {
|
if (intContacts != null) {
|
||||||
@@ -40,6 +51,10 @@ public abstract class ContactSelectorActivity extends BriarActivity implements
|
|||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
|
if (groupId != null) {
|
||||||
|
// save the group ID here regardless of how subclasses initialize it
|
||||||
|
outState.putByteArray(GROUP_ID, groupId.getBytes());
|
||||||
|
}
|
||||||
if (contacts != null) {
|
if (contacts != null) {
|
||||||
outState.putIntegerArrayList(CONTACTS,
|
outState.putIntegerArrayList(CONTACTS,
|
||||||
getContactsFromIds(contacts));
|
getContactsFromIds(contacts));
|
||||||
@@ -49,9 +64,7 @@ public abstract class ContactSelectorActivity extends BriarActivity implements
|
|||||||
@CallSuper
|
@CallSuper
|
||||||
@UiThread
|
@UiThread
|
||||||
@Override
|
@Override
|
||||||
public void contactsSelected(GroupId groupId,
|
public void contactsSelected(Collection<ContactId> contacts) {
|
||||||
Collection<ContactId> contacts) {
|
|
||||||
this.groupId = groupId;
|
|
||||||
this.contacts = contacts;
|
this.contacts = contacts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package org.briarproject.android.contactselection;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import org.briarproject.R;
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
public class ContactSelectorAdapter extends
|
||||||
|
BaseContactSelectorAdapter<SelectableContactItem, SelectableContactHolder> {
|
||||||
|
|
||||||
|
ContactSelectorAdapter(Context context,
|
||||||
|
OnContactClickListener<SelectableContactItem> listener) {
|
||||||
|
super(context, SelectableContactItem.class, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SelectableContactHolder onCreateViewHolder(ViewGroup viewGroup,
|
||||||
|
int i) {
|
||||||
|
View v = LayoutInflater.from(ctx).inflate(
|
||||||
|
R.layout.list_item_selectable_contact, viewGroup, false);
|
||||||
|
return new SelectableContactHolder(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package org.briarproject.android.contactselection;
|
||||||
|
|
||||||
|
import org.briarproject.android.controller.DbController;
|
||||||
|
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
||||||
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.db.DbException;
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
public interface ContactSelectorController<I extends SelectableContactItem>
|
||||||
|
extends DbController {
|
||||||
|
|
||||||
|
void loadContacts(GroupId g, Collection<ContactId> selection,
|
||||||
|
ResultExceptionHandler<Collection<I>, DbException> handler);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package org.briarproject.android.contactselection;
|
||||||
|
|
||||||
|
import org.briarproject.android.controller.DbControllerImpl;
|
||||||
|
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
||||||
|
import org.briarproject.api.contact.Contact;
|
||||||
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.contact.ContactManager;
|
||||||
|
import org.briarproject.api.db.DatabaseExecutor;
|
||||||
|
import org.briarproject.api.db.DbException;
|
||||||
|
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@NotNullByDefault
|
||||||
|
public abstract class ContactSelectorControllerImpl<I extends SelectableContactItem>
|
||||||
|
extends DbControllerImpl
|
||||||
|
implements ContactSelectorController<I> {
|
||||||
|
|
||||||
|
private static final Logger LOG =
|
||||||
|
Logger.getLogger(ContactSelectorControllerImpl.class.getName());
|
||||||
|
|
||||||
|
private final ContactManager contactManager;
|
||||||
|
|
||||||
|
public ContactSelectorControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
||||||
|
LifecycleManager lifecycleManager, ContactManager contactManager) {
|
||||||
|
super(dbExecutor, lifecycleManager);
|
||||||
|
this.contactManager = contactManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadContacts(final GroupId g,
|
||||||
|
final Collection<ContactId> selection,
|
||||||
|
final ResultExceptionHandler<Collection<I>, DbException> handler) {
|
||||||
|
runOnDbThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
Collection<I> contacts = new ArrayList<>();
|
||||||
|
for (Contact c : contactManager.getActiveContacts()) {
|
||||||
|
// was this contact already selected?
|
||||||
|
boolean selected =
|
||||||
|
isSelected(c, selection.contains(c.getId()));
|
||||||
|
// can this contact be selected?
|
||||||
|
boolean disabled = isDisabled(g, c);
|
||||||
|
contacts.add(getItem(c, selected, disabled));
|
||||||
|
}
|
||||||
|
handler.onResult(contacts);
|
||||||
|
} catch (DbException e) {
|
||||||
|
if (LOG.isLoggable(WARNING))
|
||||||
|
LOG.log(WARNING, e.toString(), e);
|
||||||
|
handler.onException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@DatabaseExecutor
|
||||||
|
protected abstract boolean isSelected(Contact c, boolean wasSelected)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
|
@DatabaseExecutor
|
||||||
|
protected abstract boolean isDisabled(GroupId g, Contact c)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
|
protected abstract I getItem(Contact c, boolean selected, boolean disabled);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package org.briarproject.android.contactselection;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import org.briarproject.R;
|
||||||
|
import org.briarproject.android.contact.BaseContactListAdapter.OnContactClickListener;
|
||||||
|
import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
|
||||||
|
import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
|
public abstract class ContactSelectorFragment extends
|
||||||
|
BaseContactSelectorFragment<SelectableContactItem, SelectableContactHolder>
|
||||||
|
implements OnContactClickListener<SelectableContactItem> {
|
||||||
|
|
||||||
|
public static final String TAG = ContactSelectorFragment.class.getName();
|
||||||
|
|
||||||
|
private Menu menu;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater,
|
||||||
|
@Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
View contentView =
|
||||||
|
super.onCreateView(inflater, container, savedInstanceState);
|
||||||
|
adapter = new ContactSelectorAdapter(getActivity(), this);
|
||||||
|
list.setAdapter(adapter);
|
||||||
|
return contentView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
|
inflater.inflate(R.menu.contact_selection_actions, menu);
|
||||||
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
|
this.menu = menu;
|
||||||
|
// hide sharing action initially, if no contact is selected
|
||||||
|
onSelectionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.action_contacts_selected:
|
||||||
|
selectedContacts = adapter.getSelectedContactIds();
|
||||||
|
listener.contactsSelected(selectedContacts);
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSelectionChanged() {
|
||||||
|
if (menu == null) return;
|
||||||
|
MenuItem item = menu.findItem(R.id.action_contacts_selected);
|
||||||
|
if (item == null) return;
|
||||||
|
|
||||||
|
selectedContacts = adapter.getSelectedContactIds();
|
||||||
|
if (selectedContacts.size() > 0) {
|
||||||
|
item.setVisible(true);
|
||||||
|
} else {
|
||||||
|
item.setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package org.briarproject.android.contactselection;
|
||||||
|
|
||||||
|
import android.support.annotation.UiThread;
|
||||||
|
|
||||||
|
import org.briarproject.android.DestroyableContext;
|
||||||
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
interface ContactSelectorListener<I extends SelectableContactItem>
|
||||||
|
extends DestroyableContext {
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
void contactsSelected(Collection<ContactId> contacts);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.android.sharing;
|
package org.briarproject.android.contactselection;
|
||||||
|
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -16,7 +16,7 @@ import static android.view.View.VISIBLE;
|
|||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class SelectableContactHolder
|
public class SelectableContactHolder
|
||||||
extends ContactItemViewHolder<SelectableContactItem> {
|
extends ContactItemViewHolder<SelectableContactItem> {
|
||||||
|
|
||||||
private final CheckBox checkBox;
|
private final CheckBox checkBox;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.android.sharing;
|
package org.briarproject.android.contactselection;
|
||||||
|
|
||||||
import org.briarproject.android.contact.ContactItem;
|
import org.briarproject.android.contact.ContactItem;
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
@@ -8,13 +8,13 @@ import javax.annotation.concurrent.NotThreadSafe;
|
|||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class SelectableContactItem extends ContactItem {
|
public class SelectableContactItem extends ContactItem {
|
||||||
|
|
||||||
private boolean selected, disabled;
|
private boolean selected, disabled;
|
||||||
|
|
||||||
SelectableContactItem(Contact contact, boolean connected,
|
public SelectableContactItem(Contact contact, boolean selected,
|
||||||
boolean selected, boolean disabled) {
|
boolean disabled) {
|
||||||
super(contact, connected);
|
super(contact);
|
||||||
this.selected = selected;
|
this.selected = selected;
|
||||||
this.disabled = disabled;
|
this.disabled = disabled;
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,15 @@
|
|||||||
package org.briarproject.android.privategroup.creation;
|
package org.briarproject.android.privategroup.creation;
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
|
import org.briarproject.android.contactselection.ContactSelectorActivity;
|
||||||
|
import org.briarproject.android.contactselection.ContactSelectorController;
|
||||||
|
import org.briarproject.android.contactselection.SelectableContactItem;
|
||||||
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
||||||
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
|
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
|
||||||
import org.briarproject.android.sharing.ContactSelectorActivity;
|
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
|
||||||
|
import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -17,37 +18,18 @@ import javax.inject.Inject;
|
|||||||
|
|
||||||
import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_INVITATION_MSG_LENGTH;
|
import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_INVITATION_MSG_LENGTH;
|
||||||
|
|
||||||
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
public abstract class BaseGroupInviteActivity
|
public abstract class BaseGroupInviteActivity
|
||||||
extends ContactSelectorActivity
|
extends ContactSelectorActivity<SelectableContactItem>
|
||||||
implements MessageFragmentListener {
|
implements MessageFragmentListener {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
CreateGroupController controller;
|
CreateGroupController controller;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle bundle) {
|
public void contactsSelected(Collection<ContactId> contacts) {
|
||||||
super.onCreate(bundle);
|
super.contactsSelected(contacts);
|
||||||
|
|
||||||
// Subclasses may initialise the group ID in different places,
|
|
||||||
// restore it if it was saved
|
|
||||||
if (bundle != null) {
|
|
||||||
byte[] groupBytes = bundle.getByteArray(GROUP_ID);
|
|
||||||
if (groupBytes != null) groupId = new GroupId(groupBytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
if (groupId != null) {
|
|
||||||
outState.putByteArray(GROUP_ID, groupId.getBytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void contactsSelected(GroupId groupId,
|
|
||||||
Collection<ContactId> contacts) {
|
|
||||||
super.contactsSelected(groupId, contacts);
|
|
||||||
|
|
||||||
CreateGroupMessageFragment fragment = new CreateGroupMessageFragment();
|
CreateGroupMessageFragment fragment = new CreateGroupMessageFragment();
|
||||||
getSupportFragmentManager().beginTransaction()
|
getSupportFragmentManager().beginTransaction()
|
||||||
@@ -62,6 +44,8 @@ public abstract class BaseGroupInviteActivity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onButtonClick(@NotNull String message) {
|
public boolean onButtonClick(@NotNull String message) {
|
||||||
|
if (groupId == null)
|
||||||
|
throw new IllegalStateException("GroupId was not initialized");
|
||||||
controller.sendInvitation(groupId, contacts, message,
|
controller.sendInvitation(groupId, contacts, message,
|
||||||
new UiResultExceptionHandler<Void, DbException>(this) {
|
new UiResultExceptionHandler<Void, DbException>(this) {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -7,12 +7,10 @@ import android.support.v4.app.ActivityOptionsCompat;
|
|||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.ActivityComponent;
|
import org.briarproject.android.ActivityComponent;
|
||||||
|
import org.briarproject.android.contactselection.ContactSelectorFragment;
|
||||||
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
||||||
import org.briarproject.android.privategroup.conversation.GroupActivity;
|
import org.briarproject.android.privategroup.conversation.GroupActivity;
|
||||||
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
|
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
|
||||||
import org.briarproject.android.sharing.ContactSelectorFragment;
|
|
||||||
import org.briarproject.api.contact.Contact;
|
|
||||||
import org.briarproject.api.db.DatabaseExecutor;
|
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
@@ -38,13 +36,6 @@ public class CreateGroupActivity extends BaseGroupInviteActivity implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@DatabaseExecutor
|
|
||||||
public boolean isDisabled(GroupId groupId, Contact c) throws DbException {
|
|
||||||
// contacts can always be invited into a new group
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
|
if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
|
||||||
@@ -76,8 +67,8 @@ public class CreateGroupActivity extends BaseGroupInviteActivity implements
|
|||||||
|
|
||||||
private void switchToContactSelectorFragment(GroupId g) {
|
private void switchToContactSelectorFragment(GroupId g) {
|
||||||
setTitle(R.string.groups_invite_members);
|
setTitle(R.string.groups_invite_members);
|
||||||
ContactSelectorFragment fragment =
|
GroupInviteFragment fragment =
|
||||||
ContactSelectorFragment.newInstance(g);
|
GroupInviteFragment.newInstance(g);
|
||||||
getSupportFragmentManager().beginTransaction()
|
getSupportFragmentManager().beginTransaction()
|
||||||
.setCustomAnimations(android.R.anim.fade_in,
|
.setCustomAnimations(android.R.anim.fade_in,
|
||||||
android.R.anim.fade_out,
|
android.R.anim.fade_out,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.android.privategroup.creation;
|
package org.briarproject.android.privategroup.creation;
|
||||||
|
|
||||||
import org.briarproject.android.controller.DbController;
|
import org.briarproject.android.contactselection.ContactSelectorController;
|
||||||
|
import org.briarproject.android.contactselection.SelectableContactItem;
|
||||||
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
@@ -10,12 +11,13 @@ import org.briarproject.api.sync.GroupId;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public interface CreateGroupController extends DbController {
|
public interface CreateGroupController
|
||||||
|
extends ContactSelectorController<SelectableContactItem> {
|
||||||
|
|
||||||
void createGroup(String name,
|
void createGroup(String name,
|
||||||
ResultExceptionHandler<GroupId, DbException> result);
|
ResultExceptionHandler<GroupId, DbException> result);
|
||||||
|
|
||||||
void sendInvitation(GroupId groupId, Collection<ContactId> contacts,
|
void sendInvitation(GroupId g, Collection<ContactId> contacts,
|
||||||
String message, ResultExceptionHandler<Void, DbException> result);
|
String message, ResultExceptionHandler<Void, DbException> result);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.android.privategroup.creation;
|
package org.briarproject.android.privategroup.creation;
|
||||||
|
|
||||||
import org.briarproject.android.controller.DbControllerImpl;
|
import org.briarproject.android.contactselection.ContactSelectorControllerImpl;
|
||||||
|
import org.briarproject.android.contactselection.SelectableContactItem;
|
||||||
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
@@ -36,7 +37,8 @@ import static java.util.logging.Level.WARNING;
|
|||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class CreateGroupControllerImpl extends DbControllerImpl
|
public class CreateGroupControllerImpl
|
||||||
|
extends ContactSelectorControllerImpl<SelectableContactItem>
|
||||||
implements CreateGroupController {
|
implements CreateGroupController {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
@@ -61,7 +63,7 @@ public class CreateGroupControllerImpl extends DbControllerImpl
|
|||||||
PrivateGroupManager groupManager,
|
PrivateGroupManager groupManager,
|
||||||
GroupInvitationFactory groupInvitationFactory,
|
GroupInvitationFactory groupInvitationFactory,
|
||||||
GroupInvitationManager groupInvitationManager, Clock clock) {
|
GroupInvitationManager groupInvitationManager, Clock clock) {
|
||||||
super(dbExecutor, lifecycleManager);
|
super(dbExecutor, lifecycleManager, contactManager);
|
||||||
this.cryptoExecutor = cryptoExecutor;
|
this.cryptoExecutor = cryptoExecutor;
|
||||||
this.contactManager = contactManager;
|
this.contactManager = contactManager;
|
||||||
this.identityManager = identityManager;
|
this.identityManager = identityManager;
|
||||||
@@ -128,6 +130,23 @@ public class CreateGroupControllerImpl extends DbControllerImpl
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isSelected(Contact c, boolean wasSelected)
|
||||||
|
throws DbException {
|
||||||
|
return wasSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isDisabled(GroupId g, Contact c) throws DbException {
|
||||||
|
return !groupInvitationManager.isInvitationAllowed(c, g);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SelectableContactItem getItem(Contact c, boolean selected,
|
||||||
|
boolean disabled) {
|
||||||
|
return new SelectableContactItem(c, selected, disabled);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendInvitation(final GroupId g,
|
public void sendInvitation(final GroupId g,
|
||||||
final Collection<ContactId> contactIds, final String message,
|
final Collection<ContactId> contactIds, final String message,
|
||||||
@@ -191,6 +210,7 @@ public class CreateGroupControllerImpl extends DbControllerImpl
|
|||||||
// Continue
|
// Continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//noinspection ConstantConditions
|
||||||
handler.onResult(null);
|
handler.onResult(null);
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
if (LOG.isLoggable(WARNING))
|
if (LOG.isLoggable(WARNING))
|
||||||
|
|||||||
@@ -5,22 +5,13 @@ import android.os.Bundle;
|
|||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.ActivityComponent;
|
import org.briarproject.android.ActivityComponent;
|
||||||
|
import org.briarproject.android.contactselection.ContactSelectorFragment;
|
||||||
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
|
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
|
||||||
import org.briarproject.android.sharing.ContactSelectorFragment;
|
|
||||||
import org.briarproject.api.contact.Contact;
|
|
||||||
import org.briarproject.api.db.DatabaseExecutor;
|
|
||||||
import org.briarproject.api.db.DbException;
|
|
||||||
import org.briarproject.api.privategroup.invitation.GroupInvitationManager;
|
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
public class GroupInviteActivity extends BaseGroupInviteActivity
|
public class GroupInviteActivity extends BaseGroupInviteActivity
|
||||||
implements MessageFragmentListener {
|
implements MessageFragmentListener {
|
||||||
|
|
||||||
@Inject
|
|
||||||
GroupInvitationManager groupInvitationManager;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectActivity(ActivityComponent component) {
|
public void injectActivity(ActivityComponent component) {
|
||||||
component.inject(this);
|
component.inject(this);
|
||||||
@@ -30,26 +21,18 @@ public class GroupInviteActivity extends BaseGroupInviteActivity
|
|||||||
public void onCreate(Bundle bundle) {
|
public void onCreate(Bundle bundle) {
|
||||||
super.onCreate(bundle);
|
super.onCreate(bundle);
|
||||||
|
|
||||||
// Initialise the group ID,
|
|
||||||
// it will be saved and restored by the superclass
|
|
||||||
Intent i = getIntent();
|
Intent i = getIntent();
|
||||||
byte[] g = i.getByteArrayExtra(GROUP_ID);
|
byte[] g = i.getByteArrayExtra(GROUP_ID);
|
||||||
if (g == null) throw new IllegalStateException("No GroupId in intent.");
|
if (g == null) throw new IllegalStateException("No GroupId in intent.");
|
||||||
groupId = new GroupId(g);
|
groupId = new GroupId(g);
|
||||||
|
|
||||||
if (bundle == null) {
|
if (bundle == null) {
|
||||||
ContactSelectorFragment fragment =
|
GroupInviteFragment fragment =
|
||||||
ContactSelectorFragment.newInstance(groupId);
|
GroupInviteFragment.newInstance(groupId);
|
||||||
getSupportFragmentManager().beginTransaction()
|
getSupportFragmentManager().beginTransaction()
|
||||||
.replace(R.id.fragmentContainer, fragment)
|
.replace(R.id.fragmentContainer, fragment)
|
||||||
.commit();
|
.commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@DatabaseExecutor
|
|
||||||
public boolean isDisabled(GroupId g, Contact c) throws DbException {
|
|
||||||
return !groupInvitationManager.isInvitationAllowed(c, g);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package org.briarproject.android.privategroup.creation;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import org.briarproject.android.ActivityComponent;
|
||||||
|
import org.briarproject.android.contactselection.ContactSelectorController;
|
||||||
|
import org.briarproject.android.contactselection.ContactSelectorFragment;
|
||||||
|
import org.briarproject.android.contactselection.SelectableContactItem;
|
||||||
|
import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
|
||||||
|
import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
|
||||||
|
|
||||||
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
|
public class GroupInviteFragment extends ContactSelectorFragment {
|
||||||
|
|
||||||
|
public static final String TAG = GroupInviteFragment.class.getName();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CreateGroupController controller;
|
||||||
|
|
||||||
|
public static GroupInviteFragment newInstance(GroupId groupId) {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putByteArray(GROUP_ID, groupId.getBytes());
|
||||||
|
GroupInviteFragment fragment = new GroupInviteFragment();
|
||||||
|
fragment.setArguments(args);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void injectFragment(ActivityComponent component) {
|
||||||
|
component.inject(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ContactSelectorController<SelectableContactItem> getController() {
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUniqueTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@ package org.briarproject.android.sharing;
|
|||||||
|
|
||||||
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
||||||
import org.briarproject.api.blogs.Blog;
|
import org.briarproject.api.blogs.Blog;
|
||||||
import org.briarproject.api.blogs.BlogManager;
|
|
||||||
import org.briarproject.api.blogs.BlogSharingManager;
|
import org.briarproject.api.blogs.BlogSharingManager;
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
import org.briarproject.api.db.DatabaseExecutor;
|
import org.briarproject.api.db.DatabaseExecutor;
|
||||||
@@ -22,19 +21,18 @@ import javax.inject.Inject;
|
|||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static org.briarproject.api.blogs.BlogManager.CLIENT_ID;
|
import static org.briarproject.api.blogs.BlogManager.CLIENT_ID;
|
||||||
|
|
||||||
|
|
||||||
public class BlogInvitationControllerImpl
|
public class BlogInvitationControllerImpl
|
||||||
extends InvitationControllerImpl<SharingInvitationItem>
|
extends InvitationControllerImpl<SharingInvitationItem>
|
||||||
implements BlogInvitationController {
|
implements BlogInvitationController {
|
||||||
|
|
||||||
private final BlogManager blogManager;
|
|
||||||
private final BlogSharingManager blogSharingManager;
|
private final BlogSharingManager blogSharingManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
BlogInvitationControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
BlogInvitationControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
||||||
LifecycleManager lifecycleManager, EventBus eventBus,
|
LifecycleManager lifecycleManager, EventBus eventBus,
|
||||||
BlogManager blogManager, BlogSharingManager blogSharingManager) {
|
BlogSharingManager blogSharingManager) {
|
||||||
super(dbExecutor, lifecycleManager, eventBus);
|
super(dbExecutor, lifecycleManager, eventBus);
|
||||||
this.blogManager = blogManager;
|
|
||||||
this.blogSharingManager = blogSharingManager;
|
this.blogSharingManager = blogSharingManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
package org.briarproject.android.sharing;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import org.briarproject.R;
|
|
||||||
import org.briarproject.android.contact.BaseContactListAdapter;
|
|
||||||
import org.briarproject.api.contact.ContactId;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
class ContactSelectorAdapter extends
|
|
||||||
BaseContactListAdapter<SelectableContactItem, SelectableContactHolder> {
|
|
||||||
|
|
||||||
ContactSelectorAdapter(Context context,
|
|
||||||
OnContactClickListener<SelectableContactItem> listener) {
|
|
||||||
super(context, SelectableContactItem.class, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SelectableContactHolder onCreateViewHolder(ViewGroup viewGroup,
|
|
||||||
int i) {
|
|
||||||
View v = LayoutInflater.from(ctx).inflate(
|
|
||||||
R.layout.list_item_selectable_contact, viewGroup, false);
|
|
||||||
return new SelectableContactHolder(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
Collection<ContactId> getSelectedContactIds() {
|
|
||||||
Collection<ContactId> selected = new ArrayList<>();
|
|
||||||
|
|
||||||
for (int i = 0; i < items.size(); i++) {
|
|
||||||
SelectableContactItem item = items.get(i);
|
|
||||||
if (item.isSelected()) selected.add(item.getContact().getId());
|
|
||||||
}
|
|
||||||
return selected;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,233 +0,0 @@
|
|||||||
package org.briarproject.android.sharing;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
|
||||||
import android.transition.Fade;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import org.briarproject.R;
|
|
||||||
import org.briarproject.android.ActivityComponent;
|
|
||||||
import org.briarproject.android.contact.BaseContactListAdapter.OnContactClickListener;
|
|
||||||
import org.briarproject.android.fragment.BaseFragment;
|
|
||||||
import org.briarproject.android.view.BriarRecyclerView;
|
|
||||||
import org.briarproject.api.contact.Contact;
|
|
||||||
import org.briarproject.api.contact.ContactId;
|
|
||||||
import org.briarproject.api.contact.ContactManager;
|
|
||||||
import org.briarproject.api.db.DbException;
|
|
||||||
import org.briarproject.api.plugins.ConnectionRegistry;
|
|
||||||
import org.briarproject.api.sync.GroupId;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import static java.util.logging.Level.INFO;
|
|
||||||
import static java.util.logging.Level.WARNING;
|
|
||||||
import static org.briarproject.android.sharing.ShareActivity.CONTACTS;
|
|
||||||
import static org.briarproject.android.sharing.ShareActivity.getContactsFromIds;
|
|
||||||
import static org.briarproject.android.sharing.ShareActivity.getContactsFromIntegers;
|
|
||||||
import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
|
|
||||||
|
|
||||||
public class ContactSelectorFragment extends BaseFragment
|
|
||||||
implements OnContactClickListener<SelectableContactItem> {
|
|
||||||
|
|
||||||
public static final String TAG = ContactSelectorFragment.class.getName();
|
|
||||||
private static final Logger LOG = Logger.getLogger(TAG);
|
|
||||||
|
|
||||||
private Menu menu;
|
|
||||||
private BriarRecyclerView list;
|
|
||||||
private ContactSelectorAdapter adapter;
|
|
||||||
private Collection<ContactId> selectedContacts;
|
|
||||||
|
|
||||||
// Fields that are accessed from background threads must be volatile
|
|
||||||
@Inject
|
|
||||||
volatile ContactManager contactManager;
|
|
||||||
@Inject
|
|
||||||
volatile ConnectionRegistry connectionRegistry;
|
|
||||||
|
|
||||||
private volatile GroupId groupId;
|
|
||||||
private volatile ContactSelectorListener listener;
|
|
||||||
|
|
||||||
public static ContactSelectorFragment newInstance(GroupId groupId) {
|
|
||||||
Bundle args = new Bundle();
|
|
||||||
args.putByteArray(GROUP_ID, groupId.getBytes());
|
|
||||||
ContactSelectorFragment fragment = new ContactSelectorFragment();
|
|
||||||
fragment.setArguments(args);
|
|
||||||
return fragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void injectFragment(ActivityComponent component) {
|
|
||||||
component.inject(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttach(Context context) {
|
|
||||||
super.onAttach(context);
|
|
||||||
listener = (ContactSelectorListener) context;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
Bundle args = getArguments();
|
|
||||||
byte[] b = args.getByteArray(GROUP_ID);
|
|
||||||
if (b == null) throw new IllegalStateException("No GroupId");
|
|
||||||
groupId = new GroupId(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
|
||||||
Bundle savedInstanceState) {
|
|
||||||
|
|
||||||
View contentView = inflater.inflate(R.layout.list, container, false);
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= 21) {
|
|
||||||
setExitTransition(new Fade());
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter = new ContactSelectorAdapter(getActivity(), this);
|
|
||||||
|
|
||||||
list = (BriarRecyclerView) contentView.findViewById(R.id.list);
|
|
||||||
list.setLayoutManager(new LinearLayoutManager(getActivity()));
|
|
||||||
list.setAdapter(adapter);
|
|
||||||
list.setEmptyText(getString(R.string.no_contacts_selector));
|
|
||||||
|
|
||||||
// restore selected contacts if available
|
|
||||||
if (savedInstanceState != null) {
|
|
||||||
ArrayList<Integer> intContacts =
|
|
||||||
savedInstanceState.getIntegerArrayList(CONTACTS);
|
|
||||||
if (intContacts != null) {
|
|
||||||
selectedContacts = getContactsFromIntegers(intContacts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return contentView;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
loadContacts(selectedContacts);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
adapter.clear();
|
|
||||||
list.showProgressBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
if (adapter != null) {
|
|
||||||
selectedContacts = adapter.getSelectedContactIds();
|
|
||||||
outState.putIntegerArrayList(CONTACTS,
|
|
||||||
getContactsFromIds(selectedContacts));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
|
||||||
inflater.inflate(R.menu.contact_selection_actions, menu);
|
|
||||||
super.onCreateOptionsMenu(menu, inflater);
|
|
||||||
this.menu = menu;
|
|
||||||
// hide sharing action initially, if no contact is selected
|
|
||||||
updateMenuItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
|
||||||
// Handle presses on the action bar items
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case R.id.action_contacts_selected:
|
|
||||||
selectedContacts = adapter.getSelectedContactIds();
|
|
||||||
listener.contactsSelected(groupId, selectedContacts);
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUniqueTag() {
|
|
||||||
return TAG;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemClick(View view, SelectableContactItem item) {
|
|
||||||
item.toggleSelected();
|
|
||||||
adapter.notifyItemChanged(adapter.findItemPosition(item), item);
|
|
||||||
|
|
||||||
updateMenuItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadContacts(@Nullable final Collection<ContactId> selection) {
|
|
||||||
listener.runOnDbThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
List<SelectableContactItem> contacts =
|
|
||||||
new ArrayList<>();
|
|
||||||
for (Contact c : contactManager.getActiveContacts()) {
|
|
||||||
// is this contact online?
|
|
||||||
boolean connected =
|
|
||||||
connectionRegistry.isConnected(c.getId());
|
|
||||||
// was this contact already selected?
|
|
||||||
boolean selected = selection != null &&
|
|
||||||
selection.contains(c.getId());
|
|
||||||
// do we have already some sharing with that contact?
|
|
||||||
boolean disabled = listener.isDisabled(groupId, c);
|
|
||||||
contacts.add(new SelectableContactItem(c, connected,
|
|
||||||
selected, disabled));
|
|
||||||
}
|
|
||||||
long duration = System.currentTimeMillis() - now;
|
|
||||||
if (LOG.isLoggable(INFO))
|
|
||||||
LOG.info("Load took " + duration + " ms");
|
|
||||||
displayContacts(contacts);
|
|
||||||
} catch (DbException e) {
|
|
||||||
if (LOG.isLoggable(WARNING))
|
|
||||||
LOG.log(WARNING, e.toString(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void displayContacts(
|
|
||||||
final List<SelectableContactItem> contacts) {
|
|
||||||
listener.runOnUiThreadUnlessDestroyed(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (contacts.isEmpty()) list.showData();
|
|
||||||
else adapter.addAll(contacts);
|
|
||||||
updateMenuItem();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateMenuItem() {
|
|
||||||
if (menu == null) return;
|
|
||||||
MenuItem item = menu.findItem(R.id.action_contacts_selected);
|
|
||||||
if (item == null) return;
|
|
||||||
|
|
||||||
selectedContacts = adapter.getSelectedContactIds();
|
|
||||||
if (selectedContacts.size() > 0) {
|
|
||||||
item.setVisible(true);
|
|
||||||
} else {
|
|
||||||
item.setVisible(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
package org.briarproject.android.sharing;
|
|
||||||
|
|
||||||
import android.support.annotation.UiThread;
|
|
||||||
|
|
||||||
import org.briarproject.android.DestroyableContext;
|
|
||||||
import org.briarproject.api.contact.Contact;
|
|
||||||
import org.briarproject.api.contact.ContactId;
|
|
||||||
import org.briarproject.api.db.DatabaseExecutor;
|
|
||||||
import org.briarproject.api.db.DbException;
|
|
||||||
import org.briarproject.api.sync.GroupId;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
interface ContactSelectorListener extends DestroyableContext {
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
void runOnDbThread(Runnable runnable);
|
|
||||||
|
|
||||||
@DatabaseExecutor
|
|
||||||
boolean isDisabled(GroupId groupId, Contact c) throws DbException;
|
|
||||||
|
|
||||||
@UiThread
|
|
||||||
void contactsSelected(GroupId groupId, Collection<ContactId> contacts);
|
|
||||||
|
|
||||||
@UiThread
|
|
||||||
void onBackPressed();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,6 @@ import org.briarproject.api.event.Event;
|
|||||||
import org.briarproject.api.event.EventBus;
|
import org.briarproject.api.event.EventBus;
|
||||||
import org.briarproject.api.event.ForumInvitationReceivedEvent;
|
import org.briarproject.api.event.ForumInvitationReceivedEvent;
|
||||||
import org.briarproject.api.forum.Forum;
|
import org.briarproject.api.forum.Forum;
|
||||||
import org.briarproject.api.forum.ForumManager;
|
|
||||||
import org.briarproject.api.forum.ForumSharingManager;
|
import org.briarproject.api.forum.ForumSharingManager;
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.api.sharing.SharingInvitationItem;
|
import org.briarproject.api.sharing.SharingInvitationItem;
|
||||||
@@ -26,16 +25,13 @@ public class ForumInvitationControllerImpl
|
|||||||
extends InvitationControllerImpl<SharingInvitationItem>
|
extends InvitationControllerImpl<SharingInvitationItem>
|
||||||
implements ForumInvitationController {
|
implements ForumInvitationController {
|
||||||
|
|
||||||
private final ForumManager forumManager;
|
|
||||||
private final ForumSharingManager forumSharingManager;
|
private final ForumSharingManager forumSharingManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ForumInvitationControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
ForumInvitationControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
||||||
LifecycleManager lifecycleManager, EventBus eventBus,
|
LifecycleManager lifecycleManager, EventBus eventBus,
|
||||||
ForumManager forumManager,
|
|
||||||
ForumSharingManager forumSharingManager) {
|
ForumSharingManager forumSharingManager) {
|
||||||
super(dbExecutor, lifecycleManager, eventBus);
|
super(dbExecutor, lifecycleManager, eventBus);
|
||||||
this.forumManager = forumManager;
|
|
||||||
this.forumSharingManager = forumSharingManager;
|
this.forumSharingManager = forumSharingManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,53 +2,42 @@ package org.briarproject.android.sharing;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.StringRes;
|
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
|
import org.briarproject.android.contactselection.ContactSelectorActivity;
|
||||||
|
import org.briarproject.android.contactselection.ContactSelectorFragment;
|
||||||
|
import org.briarproject.android.contactselection.SelectableContactItem;
|
||||||
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
|
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.db.DatabaseExecutor;
|
import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import static android.widget.Toast.LENGTH_SHORT;
|
@MethodsNotNullByDefault
|
||||||
import static java.util.logging.Level.WARNING;
|
@ParametersNotNullByDefault
|
||||||
|
public abstract class ShareActivity
|
||||||
public abstract class ShareActivity extends ContactSelectorActivity implements
|
extends ContactSelectorActivity<SelectableContactItem>
|
||||||
MessageFragmentListener {
|
implements MessageFragmentListener {
|
||||||
|
|
||||||
private final static Logger LOG =
|
|
||||||
Logger.getLogger(ShareActivity.class.getName());
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle bundle) {
|
public void onCreate(@Nullable Bundle bundle) {
|
||||||
super.onCreate(bundle);
|
super.onCreate(bundle);
|
||||||
|
|
||||||
Intent i = getIntent();
|
Intent i = getIntent();
|
||||||
byte[] b = i.getByteArrayExtra(GROUP_ID);
|
byte[] b = i.getByteArrayExtra(GROUP_ID);
|
||||||
if (b == null) throw new IllegalStateException("No GroupId");
|
if (b == null) throw new IllegalStateException("No GroupId");
|
||||||
groupId = new GroupId(b);
|
groupId = new GroupId(b);
|
||||||
|
|
||||||
if (bundle == null) {
|
|
||||||
ContactSelectorFragment contactSelectorFragment =
|
|
||||||
ContactSelectorFragment.newInstance(groupId);
|
|
||||||
getSupportFragmentManager().beginTransaction()
|
|
||||||
.add(R.id.fragmentContainer, contactSelectorFragment)
|
|
||||||
.commit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
@Override
|
@Override
|
||||||
public void contactsSelected(GroupId groupId,
|
public void contactsSelected(Collection<ContactId> contacts) {
|
||||||
Collection<ContactId> contacts) {
|
super.contactsSelected(contacts);
|
||||||
super.contactsSelected(groupId, contacts);
|
|
||||||
|
|
||||||
BaseMessageFragment messageFragment = getMessageFragment();
|
BaseMessageFragment messageFragment = getMessageFragment();
|
||||||
getSupportFragmentManager().beginTransaction()
|
getSupportFragmentManager().beginTransaction()
|
||||||
@@ -67,45 +56,12 @@ public abstract class ShareActivity extends ContactSelectorActivity implements
|
|||||||
@UiThread
|
@UiThread
|
||||||
@Override
|
@Override
|
||||||
public boolean onButtonClick(@NotNull String message) {
|
public boolean onButtonClick(@NotNull String message) {
|
||||||
share(groupId, contacts, message);
|
share(contacts, message);
|
||||||
setResult(RESULT_OK);
|
setResult(RESULT_OK);
|
||||||
supportFinishAfterTransition();
|
supportFinishAfterTransition();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void share(final GroupId g, final Collection<ContactId> contacts,
|
abstract void share(Collection<ContactId> contacts, String msg);
|
||||||
final String msg) {
|
|
||||||
runOnDbThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
for (ContactId c : contacts) {
|
|
||||||
share(g, c, msg);
|
|
||||||
}
|
|
||||||
} catch (DbException e) {
|
|
||||||
// TODO proper error handling
|
|
||||||
sharingError();
|
|
||||||
if (LOG.isLoggable(WARNING))
|
|
||||||
LOG.log(WARNING, e.toString(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@DatabaseExecutor
|
|
||||||
protected abstract void share(GroupId g, ContactId c, String msg)
|
|
||||||
throws DbException;
|
|
||||||
|
|
||||||
private void sharingError() {
|
|
||||||
runOnUiThreadUnlessDestroyed(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
int res = getSharingError();
|
|
||||||
Toast.makeText(ShareActivity.this, res, LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract @StringRes int getSharingError();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,30 @@
|
|||||||
package org.briarproject.android.sharing;
|
package org.briarproject.android.sharing;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.ActivityComponent;
|
import org.briarproject.android.ActivityComponent;
|
||||||
import org.briarproject.api.blogs.BlogSharingManager;
|
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
||||||
import org.briarproject.api.contact.Contact;
|
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
|
||||||
|
import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static android.widget.Toast.LENGTH_SHORT;
|
||||||
import static org.briarproject.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
import static org.briarproject.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
||||||
|
|
||||||
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
public class ShareBlogActivity extends ShareActivity {
|
public class ShareBlogActivity extends ShareActivity {
|
||||||
|
|
||||||
// Fields that are accessed from background threads must be volatile
|
|
||||||
@Inject
|
@Inject
|
||||||
volatile BlogSharingManager blogSharingManager;
|
ShareBlogController controller;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
BaseMessageFragment getMessageFragment() {
|
BaseMessageFragment getMessageFragment() {
|
||||||
@@ -29,23 +37,40 @@ public class ShareBlogActivity extends ShareActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDisabled(GroupId groupId, Contact c) throws DbException {
|
public void onCreate(@Nullable Bundle bundle) {
|
||||||
return !blogSharingManager.canBeShared(groupId, c);
|
super.onCreate(bundle);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
if (bundle == null) {
|
||||||
protected void share(GroupId g, ContactId c, String msg)
|
ShareBlogFragment fragment = ShareBlogFragment.newInstance(groupId);
|
||||||
throws DbException {
|
getSupportFragmentManager().beginTransaction()
|
||||||
blogSharingManager.sendInvitation(g, c, msg);
|
.add(R.id.fragmentContainer, fragment)
|
||||||
}
|
.commit();
|
||||||
|
}
|
||||||
@Override
|
|
||||||
protected int getSharingError() {
|
|
||||||
return R.string.blogs_sharing_error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaximumMessageLength() {
|
public int getMaximumMessageLength() {
|
||||||
return MAX_MESSAGE_BODY_LENGTH;
|
return MAX_MESSAGE_BODY_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void share(Collection<ContactId> contacts, String msg) {
|
||||||
|
controller.share(groupId, contacts, msg,
|
||||||
|
new UiResultExceptionHandler<Void, DbException>(this) {
|
||||||
|
@Override
|
||||||
|
public void onResultUi(Void result) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onExceptionUi(DbException exception) {
|
||||||
|
// TODO proper error handling
|
||||||
|
Toast.makeText(ShareBlogActivity.this,
|
||||||
|
R.string.blogs_sharing_error, LENGTH_SHORT)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package org.briarproject.android.sharing;
|
||||||
|
|
||||||
|
import org.briarproject.android.contactselection.ContactSelectorController;
|
||||||
|
import org.briarproject.android.contactselection.SelectableContactItem;
|
||||||
|
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
||||||
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.db.DbException;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public interface ShareBlogController
|
||||||
|
extends ContactSelectorController<SelectableContactItem> {
|
||||||
|
|
||||||
|
void share(GroupId g, Collection<ContactId> contacts, String msg,
|
||||||
|
ResultExceptionHandler<Void, DbException> handler);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package org.briarproject.android.sharing;
|
||||||
|
|
||||||
|
import org.briarproject.android.contactselection.ContactSelectorControllerImpl;
|
||||||
|
import org.briarproject.android.contactselection.SelectableContactItem;
|
||||||
|
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
||||||
|
import org.briarproject.api.blogs.BlogSharingManager;
|
||||||
|
import org.briarproject.api.contact.Contact;
|
||||||
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.contact.ContactManager;
|
||||||
|
import org.briarproject.api.db.DatabaseExecutor;
|
||||||
|
import org.briarproject.api.db.DbException;
|
||||||
|
import org.briarproject.api.db.NoSuchContactException;
|
||||||
|
import org.briarproject.api.db.NoSuchGroupException;
|
||||||
|
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@NotNullByDefault
|
||||||
|
public class ShareBlogControllerImpl
|
||||||
|
extends ContactSelectorControllerImpl<SelectableContactItem>
|
||||||
|
implements ShareBlogController {
|
||||||
|
|
||||||
|
private final static Logger LOG =
|
||||||
|
Logger.getLogger(ShareBlogControllerImpl.class.getName());
|
||||||
|
|
||||||
|
private final BlogSharingManager blogSharingManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ShareBlogControllerImpl(
|
||||||
|
@DatabaseExecutor Executor dbExecutor,
|
||||||
|
LifecycleManager lifecycleManager,
|
||||||
|
ContactManager contactManager,
|
||||||
|
BlogSharingManager blogSharingManager) {
|
||||||
|
super(dbExecutor, lifecycleManager, contactManager);
|
||||||
|
this.blogSharingManager = blogSharingManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isSelected(Contact c, boolean wasSelected)
|
||||||
|
throws DbException {
|
||||||
|
return wasSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isDisabled(GroupId g, Contact c) throws DbException {
|
||||||
|
return !blogSharingManager.canBeShared(g, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SelectableContactItem getItem(Contact c, boolean selected,
|
||||||
|
boolean disabled) {
|
||||||
|
return new SelectableContactItem(c, selected, disabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void share(final GroupId g, final Collection<ContactId> contacts,
|
||||||
|
final String msg,
|
||||||
|
final ResultExceptionHandler<Void, DbException> handler) {
|
||||||
|
runOnDbThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
for (ContactId c : contacts) {
|
||||||
|
try {
|
||||||
|
blogSharingManager.sendInvitation(g, c, msg);
|
||||||
|
} catch (NoSuchContactException | NoSuchGroupException e) {
|
||||||
|
if (LOG.isLoggable(WARNING))
|
||||||
|
LOG.log(WARNING, e.toString(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DbException e) {
|
||||||
|
if (LOG.isLoggable(WARNING))
|
||||||
|
LOG.log(WARNING, e.toString(), e);
|
||||||
|
handler.onException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package org.briarproject.android.sharing;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import org.briarproject.android.ActivityComponent;
|
||||||
|
import org.briarproject.android.contactselection.ContactSelectorController;
|
||||||
|
import org.briarproject.android.contactselection.ContactSelectorFragment;
|
||||||
|
import org.briarproject.android.contactselection.SelectableContactItem;
|
||||||
|
import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
|
||||||
|
import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
|
||||||
|
|
||||||
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
|
public class ShareBlogFragment extends ContactSelectorFragment {
|
||||||
|
|
||||||
|
public static final String TAG = ShareBlogFragment.class.getName();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ShareBlogController controller;
|
||||||
|
|
||||||
|
public static ShareBlogFragment newInstance(GroupId groupId) {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putByteArray(GROUP_ID, groupId.getBytes());
|
||||||
|
ShareBlogFragment fragment = new ShareBlogFragment();
|
||||||
|
fragment.setArguments(args);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void injectFragment(ActivityComponent component) {
|
||||||
|
component.inject(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ContactSelectorController<SelectableContactItem> getController() {
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUniqueTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,22 +1,30 @@
|
|||||||
package org.briarproject.android.sharing;
|
package org.briarproject.android.sharing;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.ActivityComponent;
|
import org.briarproject.android.ActivityComponent;
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.forum.ForumSharingManager;
|
import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static android.widget.Toast.LENGTH_SHORT;
|
||||||
import static org.briarproject.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
import static org.briarproject.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
||||||
|
|
||||||
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
public class ShareForumActivity extends ShareActivity {
|
public class ShareForumActivity extends ShareActivity {
|
||||||
|
|
||||||
// Fields that are accessed from background threads must be volatile
|
|
||||||
@Inject
|
@Inject
|
||||||
volatile ForumSharingManager forumSharingManager;
|
ShareForumController controller;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
BaseMessageFragment getMessageFragment() {
|
BaseMessageFragment getMessageFragment() {
|
||||||
@@ -29,23 +37,40 @@ public class ShareForumActivity extends ShareActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDisabled(GroupId groupId, Contact c) throws DbException {
|
public void onCreate(@Nullable Bundle bundle) {
|
||||||
return !forumSharingManager.canBeShared(groupId, c);
|
super.onCreate(bundle);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
if (bundle == null) {
|
||||||
protected void share(GroupId g, ContactId c, String msg)
|
ShareForumFragment fragment =
|
||||||
throws DbException {
|
ShareForumFragment.newInstance(groupId);
|
||||||
forumSharingManager.sendInvitation(g, c, msg);
|
getSupportFragmentManager().beginTransaction()
|
||||||
}
|
.add(R.id.fragmentContainer, fragment)
|
||||||
|
.commit();
|
||||||
@Override
|
}
|
||||||
protected int getSharingError() {
|
|
||||||
return R.string.forum_share_error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaximumMessageLength() {
|
public int getMaximumMessageLength() {
|
||||||
return MAX_MESSAGE_BODY_LENGTH;
|
return MAX_MESSAGE_BODY_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void share(Collection<ContactId> contacts, String msg) {
|
||||||
|
controller.share(groupId, contacts, msg,
|
||||||
|
new UiResultExceptionHandler<Void, DbException>(this) {
|
||||||
|
@Override
|
||||||
|
public void onResultUi(Void result) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onExceptionUi(DbException exception) {
|
||||||
|
// TODO proper error handling
|
||||||
|
Toast.makeText(ShareForumActivity.this,
|
||||||
|
R.string.forum_share_error, LENGTH_SHORT)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package org.briarproject.android.sharing;
|
||||||
|
|
||||||
|
import org.briarproject.android.contactselection.ContactSelectorController;
|
||||||
|
import org.briarproject.android.contactselection.SelectableContactItem;
|
||||||
|
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
||||||
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.db.DbException;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public interface ShareForumController
|
||||||
|
extends ContactSelectorController<SelectableContactItem> {
|
||||||
|
|
||||||
|
void share(GroupId g, Collection<ContactId> contacts, String msg,
|
||||||
|
ResultExceptionHandler<Void, DbException> handler);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package org.briarproject.android.sharing;
|
||||||
|
|
||||||
|
import org.briarproject.android.contactselection.ContactSelectorControllerImpl;
|
||||||
|
import org.briarproject.android.contactselection.SelectableContactItem;
|
||||||
|
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
||||||
|
import org.briarproject.api.contact.Contact;
|
||||||
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.contact.ContactManager;
|
||||||
|
import org.briarproject.api.db.DatabaseExecutor;
|
||||||
|
import org.briarproject.api.db.DbException;
|
||||||
|
import org.briarproject.api.db.NoSuchContactException;
|
||||||
|
import org.briarproject.api.db.NoSuchGroupException;
|
||||||
|
import org.briarproject.api.forum.ForumSharingManager;
|
||||||
|
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@NotNullByDefault
|
||||||
|
public class ShareForumControllerImpl
|
||||||
|
extends ContactSelectorControllerImpl<SelectableContactItem>
|
||||||
|
implements ShareForumController {
|
||||||
|
|
||||||
|
private final static Logger LOG =
|
||||||
|
Logger.getLogger(ShareForumControllerImpl.class.getName());
|
||||||
|
|
||||||
|
private final ForumSharingManager forumSharingManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ShareForumControllerImpl(
|
||||||
|
@DatabaseExecutor Executor dbExecutor,
|
||||||
|
LifecycleManager lifecycleManager,
|
||||||
|
ContactManager contactManager,
|
||||||
|
ForumSharingManager forumSharingManager) {
|
||||||
|
super(dbExecutor, lifecycleManager, contactManager);
|
||||||
|
this.forumSharingManager = forumSharingManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isSelected(Contact c, boolean wasSelected)
|
||||||
|
throws DbException {
|
||||||
|
return wasSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isDisabled(GroupId g, Contact c) throws DbException {
|
||||||
|
return !forumSharingManager.canBeShared(g, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SelectableContactItem getItem(Contact c, boolean selected,
|
||||||
|
boolean disabled) {
|
||||||
|
return new SelectableContactItem(c, selected, disabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void share(final GroupId g, final Collection<ContactId> contacts,
|
||||||
|
final String msg,
|
||||||
|
final ResultExceptionHandler<Void, DbException> handler) {
|
||||||
|
runOnDbThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
for (ContactId c : contacts) {
|
||||||
|
try {
|
||||||
|
forumSharingManager.sendInvitation(g, c, msg);
|
||||||
|
} catch (NoSuchContactException | NoSuchGroupException e) {
|
||||||
|
if (LOG.isLoggable(WARNING))
|
||||||
|
LOG.log(WARNING, e.toString(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DbException e) {
|
||||||
|
if (LOG.isLoggable(WARNING))
|
||||||
|
LOG.log(WARNING, e.toString(), e);
|
||||||
|
handler.onException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package org.briarproject.android.sharing;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import org.briarproject.android.ActivityComponent;
|
||||||
|
import org.briarproject.android.contactselection.ContactSelectorController;
|
||||||
|
import org.briarproject.android.contactselection.ContactSelectorFragment;
|
||||||
|
import org.briarproject.android.contactselection.SelectableContactItem;
|
||||||
|
import org.briarproject.api.nullsafety.MethodsNotNullByDefault;
|
||||||
|
import org.briarproject.api.nullsafety.ParametersNotNullByDefault;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
|
||||||
|
|
||||||
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
|
public class ShareForumFragment extends ContactSelectorFragment {
|
||||||
|
|
||||||
|
public static final String TAG = ShareForumFragment.class.getName();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ShareForumController controller;
|
||||||
|
|
||||||
|
public static ShareForumFragment newInstance(GroupId groupId) {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putByteArray(GROUP_ID, groupId.getBytes());
|
||||||
|
ShareForumFragment fragment = new ShareForumFragment();
|
||||||
|
fragment.setArguments(args);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void injectFragment(ActivityComponent component) {
|
||||||
|
component.inject(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ContactSelectorController<SelectableContactItem> getController() {
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUniqueTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -11,7 +11,6 @@ import org.briarproject.android.contact.ContactItem;
|
|||||||
import org.briarproject.android.view.BriarRecyclerView;
|
import org.briarproject.android.view.BriarRecyclerView;
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.plugins.ConnectionRegistry;
|
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -19,8 +18,6 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
|
|
||||||
abstract class SharingStatusActivity extends BriarActivity {
|
abstract class SharingStatusActivity extends BriarActivity {
|
||||||
@@ -32,10 +29,6 @@ abstract class SharingStatusActivity extends BriarActivity {
|
|||||||
private BriarRecyclerView sharedByList, sharedWithList;
|
private BriarRecyclerView sharedByList, sharedWithList;
|
||||||
private SharingStatusAdapter sharedByAdapter, sharedWithAdapter;
|
private SharingStatusAdapter sharedByAdapter, sharedWithAdapter;
|
||||||
|
|
||||||
// Fields that are accessed from background threads must be volatile
|
|
||||||
@Inject
|
|
||||||
volatile ConnectionRegistry connectionRegistry;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -109,9 +102,7 @@ abstract class SharingStatusActivity extends BriarActivity {
|
|||||||
try {
|
try {
|
||||||
List<ContactItem> contactItems = new ArrayList<>();
|
List<ContactItem> contactItems = new ArrayList<>();
|
||||||
for (Contact c : getSharedBy()) {
|
for (Contact c : getSharedBy()) {
|
||||||
boolean isConnected =
|
ContactItem item = new ContactItem(c);
|
||||||
connectionRegistry.isConnected(c.getId());
|
|
||||||
ContactItem item = new ContactItem(c, isConnected);
|
|
||||||
contactItems.add(item);
|
contactItems.add(item);
|
||||||
}
|
}
|
||||||
displaySharedBy(contactItems);
|
displaySharedBy(contactItems);
|
||||||
@@ -140,9 +131,7 @@ abstract class SharingStatusActivity extends BriarActivity {
|
|||||||
try {
|
try {
|
||||||
List<ContactItem> contactItems = new ArrayList<>();
|
List<ContactItem> contactItems = new ArrayList<>();
|
||||||
for (Contact c : getSharedWith()) {
|
for (Contact c : getSharedWith()) {
|
||||||
boolean isConnected =
|
ContactItem item = new ContactItem(c);
|
||||||
connectionRegistry.isConnected(c.getId());
|
|
||||||
ContactItem item = new ContactItem(c, isConnected);
|
|
||||||
contactItems.add(item);
|
contactItems.add(item);
|
||||||
}
|
}
|
||||||
displaySharedWith(contactItems);
|
displaySharedWith(contactItems);
|
||||||
|
|||||||
Reference in New Issue
Block a user