Merge branch '732-reveal-contacts-ui-preparation' into 'master'

Prepare UI for revealing contacts

This changes the visibility of some methods (that need to be accessed from another package), removes unnecessary abstractions and fixes erroneous static import of GroupId constant.

See merge request !404
This commit is contained in:
akwizgran
2016-11-11 17:33:54 +00:00
21 changed files with 122 additions and 126 deletions

View File

@@ -36,6 +36,7 @@ import org.briarproject.android.view.TextInputView;
import org.briarproject.android.view.TextInputView.TextInputListener;
import org.briarproject.api.FormatException;
import org.briarproject.api.blogs.BlogSharingManager;
import org.briarproject.api.clients.ProtocolStateException;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
@@ -898,7 +899,11 @@ public class ConversationActivity extends BriarActivity
@DatabaseExecutor
private void respondToGroupRequest(SessionId id, boolean accept)
throws DbException {
groupInvitationManager.respondToInvitation(contactId, id, accept);
try {
groupInvitationManager.respondToInvitation(contactId, id, accept);
} catch (ProtocolStateException e) {
// this action is no longer possible
}
}
private void introductionResponseError() {

View File

@@ -14,12 +14,12 @@ import java.util.Collection;
public abstract class BaseContactSelectorAdapter<I extends SelectableContactItem, H extends ContactItemViewHolder<I>>
extends BaseContactListAdapter<I, H> {
BaseContactSelectorAdapter(Context context, Class<I> c,
public BaseContactSelectorAdapter(Context context, Class<I> c,
OnContactClickListener<I> listener) {
super(context, c, listener);
}
Collection<ContactId> getSelectedContactIds() {
public Collection<ContactId> getSelectedContactIds() {
Collection<ContactId> selected = new ArrayList<>();
for (int i = 0; i < items.size(); i++) {

View File

@@ -26,28 +26,28 @@ import org.briarproject.api.sync.GroupId;
import java.util.ArrayList;
import java.util.Collection;
import static org.briarproject.android.BriarActivity.GROUP_ID;
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>>
public abstract class BaseContactSelectorFragment<I extends SelectableContactItem, A extends BaseContactSelectorAdapter<I, ? extends ContactItemViewHolder<I>>>
extends BaseFragment
implements OnContactClickListener<I> {
protected BriarRecyclerView list;
protected BaseContactSelectorAdapter<I, H> adapter;
protected A adapter;
protected Collection<ContactId> selectedContacts = new ArrayList<>();
protected ContactSelectorListener<I> listener;
protected ContactSelectorListener listener;
private GroupId groupId;
@Override
public void onAttach(Context context) {
super.onAttach(context);
listener = (ContactSelectorListener<I>) context;
listener = (ContactSelectorListener) context;
}
@Override
@@ -75,6 +75,8 @@ public abstract class BaseContactSelectorFragment<I extends SelectableContactIte
list = (BriarRecyclerView) contentView.findViewById(R.id.list);
list.setLayoutManager(new LinearLayoutManager(getActivity()));
list.setEmptyText(getString(R.string.no_contacts_selector));
adapter = getAdapter(getContext(), this);
list.setAdapter(adapter);
// restore selected contacts if available
if (savedInstanceState != null) {
@@ -87,6 +89,9 @@ public abstract class BaseContactSelectorFragment<I extends SelectableContactIte
return contentView;
}
protected abstract A getAdapter(Context context,
OnContactClickListener<I> listener);
@Override
public void onStart() {
super.onStart();

View File

@@ -0,0 +1,58 @@
package org.briarproject.android.contactselection;
import android.support.annotation.UiThread;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
import org.briarproject.R;
import org.briarproject.android.contact.BaseContactListAdapter.OnContactClickListener;
import org.briarproject.android.contact.ContactItemViewHolder;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.jetbrains.annotations.Nullable;
import static org.briarproject.android.util.AndroidUtils.GREY_OUT;
@UiThread
@NotNullByDefault
public class BaseSelectableContactHolder<I extends SelectableContactItem>
extends ContactItemViewHolder<I> {
private final CheckBox checkBox;
protected final TextView info;
public BaseSelectableContactHolder(View v) {
super(v);
checkBox = (CheckBox) v.findViewById(R.id.checkBox);
info = (TextView) v.findViewById(R.id.infoView);
}
@Override
protected void bind(I item, @Nullable
OnContactClickListener<I> listener) {
super.bind(item, listener);
if (item.isSelected()) {
checkBox.setChecked(true);
} else {
checkBox.setChecked(false);
}
if (item.isDisabled()) {
layout.setEnabled(false);
grayOutItem(true);
} else {
layout.setEnabled(true);
grayOutItem(false);
}
}
protected void grayOutItem(boolean gray) {
float alpha = gray ? GREY_OUT : 1f;
avatar.setAlpha(alpha);
name.setAlpha(alpha);
checkBox.setAlpha(alpha);
info.setAlpha(alpha);
}
}

View File

@@ -1,9 +1,12 @@
package org.briarproject.android.contactselection;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import android.transition.Fade;
import org.briarproject.R;
import org.briarproject.android.BriarActivity;
@@ -19,9 +22,9 @@ import java.util.List;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public abstract class ContactSelectorActivity<I extends SelectableContactItem>
public abstract class ContactSelectorActivity
extends BriarActivity
implements BaseFragmentListener, ContactSelectorListener<I> {
implements BaseFragmentListener, ContactSelectorListener {
final static String CONTACTS = "contacts";
@@ -33,7 +36,11 @@ public abstract class ContactSelectorActivity<I extends SelectableContactItem>
public void onCreate(@Nullable Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_fragment_container);
setContentView(getLayout());
if (Build.VERSION.SDK_INT >= 21) {
getWindow().setExitTransition(new Fade());
}
if (bundle != null) {
// restore group ID if it was saved
@@ -48,6 +55,11 @@ public abstract class ContactSelectorActivity<I extends SelectableContactItem>
}
}
@LayoutRes
protected int getLayout() {
return R.layout.activity_fragment_container;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);

View File

@@ -22,9 +22,9 @@ import static java.util.logging.Level.WARNING;
@Immutable
@NotNullByDefault
public abstract class ContactSelectorControllerImpl<I extends SelectableContactItem>
public abstract class ContactSelectorControllerImpl
extends DbControllerImpl
implements ContactSelectorController<I> {
implements ContactSelectorController<SelectableContactItem> {
private static final Logger LOG =
Logger.getLogger(ContactSelectorControllerImpl.class.getName());
@@ -40,19 +40,20 @@ public abstract class ContactSelectorControllerImpl<I extends SelectableContactI
@Override
public void loadContacts(final GroupId g,
final Collection<ContactId> selection,
final ResultExceptionHandler<Collection<I>, DbException> handler) {
final ResultExceptionHandler<Collection<SelectableContactItem>, DbException> handler) {
runOnDbThread(new Runnable() {
@Override
public void run() {
try {
Collection<I> contacts = new ArrayList<>();
Collection<SelectableContactItem> contacts =
new ArrayList<>();
for (Contact c : contactManager.getActiveContacts()) {
// was this contact already selected?
boolean selected =
isSelected(c, selection.contains(c.getId()));
boolean selected = selection.contains(c.getId());
// can this contact be selected?
boolean disabled = isDisabled(g, c);
contacts.add(getItem(c, selected, disabled));
contacts.add(new SelectableContactItem(c, selected,
disabled));
}
handler.onResult(contacts);
} catch (DbException e) {
@@ -64,14 +65,8 @@ public abstract class ContactSelectorControllerImpl<I extends SelectableContactI
});
}
@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);
}

View File

@@ -1,23 +1,19 @@
package org.briarproject.android.contactselection;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.content.Context;
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>
BaseContactSelectorFragment<SelectableContactItem, ContactSelectorAdapter>
implements OnContactClickListener<SelectableContactItem> {
public static final String TAG = ContactSelectorFragment.class.getName();
@@ -25,14 +21,9 @@ public abstract class ContactSelectorFragment extends
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;
protected ContactSelectorAdapter getAdapter(Context context,
OnContactClickListener<SelectableContactItem> listener) {
return new ContactSelectorAdapter(context, listener);
}
@Override

View File

@@ -9,8 +9,7 @@ import org.briarproject.api.nullsafety.NotNullByDefault;
import java.util.Collection;
@NotNullByDefault
interface ContactSelectorListener<I extends SelectableContactItem>
extends DestroyableContext {
public interface ContactSelectorListener extends DestroyableContext {
@UiThread
void contactsSelected(Collection<ContactId> contacts);

View File

@@ -2,12 +2,9 @@ package org.briarproject.android.contactselection;
import android.support.annotation.UiThread;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
import org.briarproject.R;
import org.briarproject.android.contact.BaseContactListAdapter;
import org.briarproject.android.contact.BaseContactListAdapter.OnContactClickListener;
import org.briarproject.android.contact.ContactItemViewHolder;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.jetbrains.annotations.Nullable;
@@ -17,15 +14,10 @@ import static android.view.View.VISIBLE;
@UiThread
@NotNullByDefault
public class SelectableContactHolder
extends ContactItemViewHolder<SelectableContactItem> {
private final CheckBox checkBox;
private final TextView shared;
extends BaseSelectableContactHolder<SelectableContactItem> {
SelectableContactHolder(View v) {
super(v);
checkBox = (CheckBox) v.findViewById(R.id.checkBox);
shared = (TextView) v.findViewById(R.id.infoView);
}
@Override
@@ -33,29 +25,11 @@ public class SelectableContactHolder
OnContactClickListener<SelectableContactItem> listener) {
super.bind(item, listener);
if (item.isSelected()) {
checkBox.setChecked(true);
} else {
checkBox.setChecked(false);
}
if (item.isDisabled()) {
// we share this forum already with that contact
layout.setEnabled(false);
shared.setVisibility(VISIBLE);
grayOutItem(true);
info.setVisibility(VISIBLE);
} else {
layout.setEnabled(true);
shared.setVisibility(GONE);
grayOutItem(false);
info.setVisibility(GONE);
}
}
private void grayOutItem(boolean gray) {
float alpha = gray ? 0.25f : 1f;
avatar.setAlpha(alpha);
name.setAlpha(alpha);
checkBox.setAlpha(alpha);
}
}

View File

@@ -27,7 +27,7 @@ public class SelectableContactItem extends ContactItem {
selected = !selected;
}
boolean isDisabled() {
public boolean isDisabled() {
return disabled;
}

View File

@@ -2,7 +2,6 @@ package org.briarproject.android.privategroup.creation;
import org.briarproject.R;
import org.briarproject.android.contactselection.ContactSelectorActivity;
import org.briarproject.android.contactselection.SelectableContactItem;
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
import org.briarproject.api.contact.ContactId;
@@ -20,8 +19,7 @@ import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public abstract class BaseGroupInviteActivity
extends ContactSelectorActivity<SelectableContactItem>
implements MessageFragmentListener {
extends ContactSelectorActivity implements MessageFragmentListener {
@Inject
CreateGroupController controller;

View File

@@ -7,7 +7,6 @@ import android.support.v4.app.ActivityOptionsCompat;
import org.briarproject.R;
import org.briarproject.android.ActivityComponent;
import org.briarproject.android.contactselection.ContactSelectorFragment;
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
import org.briarproject.android.privategroup.conversation.GroupActivity;
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;

View File

@@ -1,7 +1,6 @@
package org.briarproject.android.privategroup.creation;
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;
@@ -37,8 +36,7 @@ import static java.util.logging.Level.WARNING;
@Immutable
@NotNullByDefault
public class CreateGroupControllerImpl
extends ContactSelectorControllerImpl<SelectableContactItem>
public class CreateGroupControllerImpl extends ContactSelectorControllerImpl
implements CreateGroupController {
private static final Logger LOG =
@@ -130,23 +128,11 @@ public class CreateGroupControllerImpl
});
}
@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
public void sendInvitation(final GroupId g,
final Collection<ContactId> contactIds, final String message,

View File

@@ -5,7 +5,6 @@ import android.os.Bundle;
import org.briarproject.R;
import org.briarproject.android.ActivityComponent;
import org.briarproject.android.contactselection.ContactSelectorFragment;
import org.briarproject.android.sharing.BaseMessageFragment.MessageFragmentListener;
import org.briarproject.api.sync.GroupId;

View File

@@ -1,8 +1,11 @@
package org.briarproject.android.privategroup.creation;
import android.content.Context;
import android.os.Bundle;
import org.briarproject.android.ActivityComponent;
import org.briarproject.android.contact.BaseContactListAdapter;
import org.briarproject.android.contactselection.ContactSelectorAdapter;
import org.briarproject.android.contactselection.ContactSelectorController;
import org.briarproject.android.contactselection.ContactSelectorFragment;
import org.briarproject.android.contactselection.SelectableContactItem;
@@ -12,7 +15,7 @@ import org.briarproject.api.sync.GroupId;
import javax.inject.Inject;
import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
import static org.briarproject.android.BriarActivity.GROUP_ID;
@MethodsNotNullByDefault
@ParametersNotNullByDefault

View File

@@ -20,8 +20,7 @@ import java.util.Collection;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public abstract class ShareActivity
extends ContactSelectorActivity<SelectableContactItem>
public abstract class ShareActivity extends ContactSelectorActivity
implements MessageFragmentListener {
@Override

View File

@@ -1,7 +1,6 @@
package org.briarproject.android.sharing;
import org.briarproject.android.contactselection.ContactSelectorControllerImpl;
import org.briarproject.android.contactselection.SelectableContactItem;
import org.briarproject.android.controller.handler.ExceptionHandler;
import org.briarproject.api.blogs.BlogSharingManager;
import org.briarproject.api.contact.Contact;
@@ -26,8 +25,7 @@ import static java.util.logging.Level.WARNING;
@Immutable
@NotNullByDefault
public class ShareBlogControllerImpl
extends ContactSelectorControllerImpl<SelectableContactItem>
public class ShareBlogControllerImpl extends ContactSelectorControllerImpl
implements ShareBlogController {
private final static Logger LOG =
@@ -45,23 +43,11 @@ public class ShareBlogControllerImpl
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,

View File

@@ -12,7 +12,7 @@ import org.briarproject.api.sync.GroupId;
import javax.inject.Inject;
import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
import static org.briarproject.android.BriarActivity.GROUP_ID;
@MethodsNotNullByDefault
@ParametersNotNullByDefault

View File

@@ -1,7 +1,6 @@
package org.briarproject.android.sharing;
import org.briarproject.android.contactselection.ContactSelectorControllerImpl;
import org.briarproject.android.contactselection.SelectableContactItem;
import org.briarproject.android.controller.handler.ExceptionHandler;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
@@ -26,8 +25,7 @@ import static java.util.logging.Level.WARNING;
@Immutable
@NotNullByDefault
public class ShareForumControllerImpl
extends ContactSelectorControllerImpl<SelectableContactItem>
public class ShareForumControllerImpl extends ContactSelectorControllerImpl
implements ShareForumController {
private final static Logger LOG =
@@ -45,23 +43,11 @@ public class ShareForumControllerImpl
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,

View File

@@ -12,7 +12,7 @@ import org.briarproject.api.sync.GroupId;
import javax.inject.Inject;
import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
import static org.briarproject.android.BriarActivity.GROUP_ID;
@MethodsNotNullByDefault
@ParametersNotNullByDefault

View File

@@ -47,6 +47,7 @@ public class AndroidUtils {
public static final long MIN_RESOLUTION = MINUTE_IN_MILLIS;
public static final int TEASER_LENGTH = 320;
public static final float GREY_OUT = 0.5f;
// Fake Bluetooth address returned by BluetoothAdapter on API 23 and later
private static final String FAKE_BLUETOOTH_ADDRESS = "02:00:00:00:00:00";