mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-14 03:39:05 +01:00
Forum Sharing Client UI
This changes `ShareForumActivity` to use two fragments to facilitate forum sharing with the new Forum Sharing Client backend. The `ContactSelectorFragment` allows the user to select a number of contacts. If there is an ongoing sharing session or the forum is already shared with the contact, it is disabled in the list. If there is at least one contact selected, a button appears in the toolbar that brings the user to the `ShareForumMessageFragment` where the user can write an optional message to be send along with the invitation. After sending an invitation, the user is brought back to the forum that she shared and there is a snackbar showing up briefly to indicate the successful invitation. The invitation is shown along with the message within the private conversation of each contact. The person who shares the forum also sees the invitation and the message as outgoing messages that also display the current status of the messages. A notification is shown like for other private messages as well. Please note that this commit does not include a way for users to respond to invitations.
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
package org.briarproject.android.forum;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.os.Build;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -47,10 +52,16 @@ public class ContactSelectorAdapter
|
||||
} else {
|
||||
ui.checkBox.setChecked(false);
|
||||
}
|
||||
|
||||
if (item.isDisabled()) {
|
||||
// we share this forum already with that contact
|
||||
ui.layout.setEnabled(false);
|
||||
grayOutItem(ui);
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<ContactId> getSelectedContactIds() {
|
||||
Collection<ContactId> selected = new ArrayList<ContactId>();
|
||||
Collection<ContactId> selected = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < contacts.size(); i++) {
|
||||
SelectableContactListItem item =
|
||||
@@ -78,4 +89,19 @@ public class ContactSelectorAdapter
|
||||
return compareByName(c1, c2);
|
||||
}
|
||||
|
||||
private void grayOutItem(final SelectableContactHolder ui) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
float alpha = 0.25f;
|
||||
ui.avatar.setAlpha(alpha);
|
||||
ui.name.setAlpha(alpha);
|
||||
ui.checkBox.setAlpha(alpha);
|
||||
} else {
|
||||
ColorFilter colorFilter = new PorterDuffColorFilter(Color.GRAY,
|
||||
PorterDuff.Mode.MULTIPLY);
|
||||
ui.avatar.setColorFilter(colorFilter);
|
||||
ui.name.setEnabled(false);
|
||||
ui.checkBox.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
package org.briarproject.android.forum;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
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.AndroidComponent;
|
||||
import org.briarproject.android.contact.BaseContactListAdapter;
|
||||
import org.briarproject.android.contact.ContactListItem;
|
||||
import org.briarproject.android.fragment.BaseFragment;
|
||||
import org.briarproject.android.util.BriarRecyclerView;
|
||||
import org.briarproject.api.contact.Contact;
|
||||
import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.contact.ContactManager;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.forum.ForumSharingManager;
|
||||
import org.briarproject.api.identity.IdentityManager;
|
||||
import org.briarproject.api.identity.LocalAuthor;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
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.forum.ShareForumActivity.CONTACTS;
|
||||
import static org.briarproject.android.forum.ShareForumActivity.getContactsFromIds;
|
||||
import static org.briarproject.api.forum.ForumConstants.GROUP_ID;
|
||||
|
||||
public class ContactSelectorFragment extends BaseFragment implements
|
||||
BaseContactListAdapter.OnItemClickListener {
|
||||
|
||||
public final static String TAG = "ContactSelectorFragment";
|
||||
private ShareForumActivity shareForumActivity;
|
||||
private Menu menu;
|
||||
private BriarRecyclerView list;
|
||||
private ContactSelectorAdapter adapter;
|
||||
private Collection<ContactId> selectedContacts;
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(ContactSelectorFragment.class.getName());
|
||||
|
||||
// Fields that are accessed from background threads must be volatile
|
||||
protected volatile GroupId groupId;
|
||||
@Inject
|
||||
protected volatile ContactManager contactManager;
|
||||
@Inject
|
||||
protected volatile IdentityManager identityManager;
|
||||
@Inject
|
||||
protected volatile ForumSharingManager forumSharingManager;
|
||||
|
||||
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 onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
try {
|
||||
shareForumActivity = (ShareForumActivity) context;
|
||||
} catch (ClassCastException e) {
|
||||
throw new InstantiationError(
|
||||
"This fragment is only meant to be attached to the ShareForumActivity");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectActivity(AndroidComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
groupId = new GroupId(getArguments().getByteArray(GROUP_ID));
|
||||
if (groupId == null) throw new IllegalStateException("No GroupId");
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
||||
View contentView =
|
||||
inflater.inflate(R.layout.introduction_contact_chooser,
|
||||
container, false);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
setExitTransition(new Fade());
|
||||
}
|
||||
|
||||
adapter = new ContactSelectorAdapter(getActivity(), this);
|
||||
|
||||
list = (BriarRecyclerView) contentView.findViewById(R.id.contactList);
|
||||
list.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||
list.setAdapter(adapter);
|
||||
list.setEmptyText(getString(R.string.no_contacts));
|
||||
|
||||
// restore selected contacts if available
|
||||
if (savedInstanceState != null) {
|
||||
ArrayList<Integer> intContacts =
|
||||
savedInstanceState.getIntegerArrayList(CONTACTS);
|
||||
selectedContacts = ShareForumActivity.getContactsFromIntegers(intContacts);
|
||||
}
|
||||
|
||||
return contentView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if (selectedContacts != null) {
|
||||
loadContacts(Collections.unmodifiableCollection(selectedContacts));
|
||||
} else {
|
||||
loadContacts(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
if (adapter != null) {
|
||||
selectedContacts = adapter.getSelectedContactIds();
|
||||
outState.putIntegerArrayList(CONTACTS,
|
||||
getContactsFromIds(selectedContacts));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.forum_share_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 android.R.id.home:
|
||||
shareForumActivity.onBackPressed();
|
||||
return true;
|
||||
case R.id.action_share_forum:
|
||||
selectedContacts = adapter.getSelectedContactIds();
|
||||
shareForumActivity.showMessageScreen(groupId, selectedContacts);
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUniqueTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(View view, ContactListItem item) {
|
||||
((SelectableContactListItem) item).toggleSelected();
|
||||
adapter.notifyItemChanged(adapter.findItemPosition(item), item);
|
||||
|
||||
updateMenuItem();
|
||||
}
|
||||
|
||||
private void loadContacts(final Collection<ContactId> selection) {
|
||||
shareForumActivity.runOnDbThread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
long now = System.currentTimeMillis();
|
||||
List<ContactListItem> contacts =
|
||||
new ArrayList<>();
|
||||
|
||||
for (Contact c : contactManager.getActiveContacts()) {
|
||||
LocalAuthor localAuthor = identityManager
|
||||
.getLocalAuthor(c.getLocalAuthorId());
|
||||
// was this contact already selected?
|
||||
boolean selected = selection != null &&
|
||||
selection.contains(c.getId());
|
||||
// do we have already some sharing with that contact?
|
||||
boolean disabled =
|
||||
!forumSharingManager.canBeShared(groupId, c);
|
||||
contacts.add(
|
||||
new SelectableContactListItem(c, localAuthor,
|
||||
groupId, selected, disabled));
|
||||
}
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Load took " + duration + " ms");
|
||||
displayContacts(Collections.unmodifiableList(contacts));
|
||||
} catch (DbException e) {
|
||||
displayContacts(Collections.<ContactListItem>emptyList());
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void displayContacts(final List<ContactListItem> contacts) {
|
||||
shareForumActivity.runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
if (!contacts.isEmpty()) {
|
||||
adapter.addAll(contacts);
|
||||
} else {
|
||||
list.showData();
|
||||
}
|
||||
updateMenuItem();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateMenuItem() {
|
||||
if (menu == null) return;
|
||||
MenuItem item = menu.findItem(R.id.action_share_forum);
|
||||
if (item == null) return;
|
||||
|
||||
selectedContacts = adapter.getSelectedContactIds();
|
||||
if (selectedContacts.size() > 0) {
|
||||
item.setVisible(true);
|
||||
} else {
|
||||
item.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package org.briarproject.android.forum;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.ActivityOptionsCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
@@ -49,6 +50,7 @@ import javax.inject.Inject;
|
||||
|
||||
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
|
||||
import static android.support.design.widget.Snackbar.LENGTH_LONG;
|
||||
import static android.view.Gravity.CENTER;
|
||||
import static android.view.Gravity.CENTER_HORIZONTAL;
|
||||
import static android.view.View.GONE;
|
||||
@@ -68,6 +70,7 @@ public class ForumActivity extends BriarActivity implements EventListener,
|
||||
public static final String MIN_TIMESTAMP = "briar.MIN_TIMESTAMP";
|
||||
|
||||
private static final int REQUEST_READ = 2;
|
||||
private static final int REQUEST_FORUM_SHARED = 3;
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(ForumActivity.class.getName());
|
||||
|
||||
@@ -165,7 +168,9 @@ public class ForumActivity extends BriarActivity implements EventListener,
|
||||
ActivityOptionsCompat options = ActivityOptionsCompat
|
||||
.makeCustomAnimation(this, android.R.anim.slide_in_left,
|
||||
android.R.anim.slide_out_right);
|
||||
ActivityCompat.startActivity(this, i2, options.toBundle());
|
||||
ActivityCompat
|
||||
.startActivityForResult(this, i2, REQUEST_FORUM_SHARED,
|
||||
options.toBundle());
|
||||
return true;
|
||||
case R.id.action_forum_delete:
|
||||
showUnsubscribeDialog();
|
||||
@@ -297,6 +302,12 @@ public class ForumActivity extends BriarActivity implements EventListener,
|
||||
if (position >= 0 && position < adapter.getCount())
|
||||
displayPost(position);
|
||||
}
|
||||
else if (request == REQUEST_FORUM_SHARED && result == RESULT_OK) {
|
||||
Snackbar s = Snackbar.make(list, R.string.forum_shared_snackbar,
|
||||
LENGTH_LONG);
|
||||
s.getView().setBackgroundResource(R.color.briar_primary);
|
||||
s.show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -11,14 +11,15 @@ import java.util.Collections;
|
||||
// This class is not thread-safe
|
||||
public class SelectableContactListItem extends ContactListItem {
|
||||
|
||||
private boolean selected;
|
||||
private boolean selected, disabled;
|
||||
|
||||
public SelectableContactListItem(Contact contact, LocalAuthor localAuthor,
|
||||
GroupId groupId, boolean selected) {
|
||||
GroupId groupId, boolean selected, boolean disabled) {
|
||||
|
||||
super(contact, localAuthor, false, groupId, Collections.<ConversationItem>emptyList());
|
||||
|
||||
this.selected = selected;
|
||||
this.disabled = disabled;
|
||||
}
|
||||
|
||||
public void setSelected(boolean selected) {
|
||||
@@ -33,4 +34,8 @@ public class SelectableContactListItem extends ContactListItem {
|
||||
selected = !selected;
|
||||
}
|
||||
|
||||
public boolean isDisabled() {
|
||||
return disabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,98 +2,41 @@ package org.briarproject.android.forum;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import org.briarproject.R;
|
||||
import org.briarproject.android.AndroidComponent;
|
||||
import org.briarproject.android.BriarActivity;
|
||||
import org.briarproject.android.contact.BaseContactListAdapter;
|
||||
import org.briarproject.android.contact.ContactListItem;
|
||||
import org.briarproject.android.util.BriarRecyclerView;
|
||||
import org.briarproject.api.contact.Contact;
|
||||
import org.briarproject.android.fragment.BaseFragment;
|
||||
import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.contact.ContactManager;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.forum.ForumSharingManager;
|
||||
import org.briarproject.api.identity.IdentityManager;
|
||||
import org.briarproject.api.identity.LocalAuthor;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
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;
|
||||
|
||||
public class ShareForumActivity extends BriarActivity implements
|
||||
BaseContactListAdapter.OnItemClickListener {
|
||||
BaseFragment.BaseFragmentListener {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(ShareForumActivity.class.getName());
|
||||
|
||||
private ContactSelectorAdapter adapter;
|
||||
|
||||
// Fields that are accessed from background threads must be volatile
|
||||
@Inject protected volatile IdentityManager identityManager;
|
||||
@Inject protected volatile ContactManager contactManager;
|
||||
@Inject protected volatile ForumSharingManager forumSharingManager;
|
||||
private volatile GroupId groupId;
|
||||
public final static String CONTACTS = "contacts";
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle state) {
|
||||
super.onCreate(state);
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.introduction_contact_chooser);
|
||||
setContentView(R.layout.activity_share_forum);
|
||||
|
||||
Intent i = getIntent();
|
||||
byte[] b = i.getByteArrayExtra(GROUP_ID);
|
||||
if (b == null) throw new IllegalStateException();
|
||||
groupId = new GroupId(b);
|
||||
if (b == null) throw new IllegalStateException("No GroupId");
|
||||
GroupId groupId = new GroupId(b);
|
||||
|
||||
adapter = new ContactSelectorAdapter(this, this);
|
||||
BriarRecyclerView list =
|
||||
(BriarRecyclerView) findViewById(R.id.contactList);
|
||||
list.setLayoutManager(new LinearLayoutManager(this));
|
||||
list.setAdapter(adapter);
|
||||
list.setEmptyText(getString(R.string.no_contacts));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
loadContactsAndVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
// Inflate the menu items for use in the action bar
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.forum_share_actions, menu);
|
||||
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
// Handle presses on the action bar items
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
case R.id.action_share_forum:
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
if (savedInstanceState == null) {
|
||||
ContactSelectorFragment contactSelectorFragment =
|
||||
ContactSelectorFragment.newInstance(groupId);
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.add(R.id.shareForumContainer, contactSelectorFragment)
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,47 +45,59 @@ public class ShareForumActivity extends BriarActivity implements
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
private void loadContactsAndVisibility() {
|
||||
runOnDbThread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
long now = System.currentTimeMillis();
|
||||
List<ContactListItem> contacts = new ArrayList<>();
|
||||
Collection<ContactId> selectedContacts = new HashSet<>(
|
||||
forumSharingManager.getSharedWith(groupId));
|
||||
public void showMessageScreen(GroupId groupId,
|
||||
Collection<ContactId> contacts) {
|
||||
|
||||
for (Contact c : contactManager.getActiveContacts()) {
|
||||
LocalAuthor localAuthor = identityManager
|
||||
.getLocalAuthor(c.getLocalAuthorId());
|
||||
boolean selected = selectedContacts.contains(c.getId());
|
||||
contacts.add(
|
||||
new SelectableContactListItem(c, localAuthor,
|
||||
groupId, selected));
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
ShareForumMessageFragment messageFragment =
|
||||
ShareForumMessageFragment.newInstance(groupId, contacts);
|
||||
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.setCustomAnimations(android.R.anim.fade_in,
|
||||
android.R.anim.fade_out,
|
||||
android.R.anim.slide_in_left,
|
||||
android.R.anim.slide_out_right)
|
||||
.replace(R.id.shareForumContainer, messageFragment,
|
||||
ContactSelectorFragment.TAG)
|
||||
.addToBackStack(null)
|
||||
.commit();
|
||||
}
|
||||
|
||||
private void displayContacts(final List<ContactListItem> contact) {
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
adapter.addAll(contact);
|
||||
}
|
||||
});
|
||||
public static ArrayList<Integer> getContactsFromIds(
|
||||
Collection<ContactId> contacts) {
|
||||
|
||||
// transform ContactIds to Integers so they can be added to a bundle
|
||||
ArrayList<Integer> intContacts = new ArrayList<>(contacts.size());
|
||||
for (ContactId contactId : contacts) {
|
||||
intContacts.add(contactId.getInt());
|
||||
}
|
||||
return intContacts;
|
||||
}
|
||||
|
||||
public void sharingSuccessful(View v) {
|
||||
setResult(RESULT_OK);
|
||||
hideSoftKeyboard(v);
|
||||
supportFinishAfterTransition();
|
||||
}
|
||||
|
||||
protected static Collection<ContactId> getContactsFromIntegers(
|
||||
ArrayList<Integer> intContacts) {
|
||||
|
||||
// turn contact integers from a bundle back to ContactIds
|
||||
List<ContactId> contacts = new ArrayList<>(intContacts.size());
|
||||
for(Integer c : intContacts) {
|
||||
contacts.add(new ContactId(c));
|
||||
}
|
||||
return contacts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(View view, ContactListItem item) {
|
||||
((SelectableContactListItem) item).toggleSelected();
|
||||
adapter.notifyItemChanged(adapter.findItemPosition(item), item);
|
||||
public void showLoadingScreen(boolean isBlocking, int stringId) {
|
||||
// this is handled by the recycler view in ContactSelectorFragment
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideLoadingScreen() {
|
||||
// this is handled by the recycler view in ContactSelectorFragment
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
package org.briarproject.android.forum;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.briarproject.R;
|
||||
import org.briarproject.android.AndroidComponent;
|
||||
import org.briarproject.android.fragment.BaseFragment;
|
||||
import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.forum.ForumSharingManager;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.android.forum.ShareForumActivity.CONTACTS;
|
||||
import static org.briarproject.android.forum.ShareForumActivity.getContactsFromIds;
|
||||
import static org.briarproject.api.forum.ForumConstants.GROUP_ID;
|
||||
|
||||
public class ShareForumMessageFragment extends BaseFragment {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(ShareForumMessageFragment.class.getName());
|
||||
|
||||
public final static String TAG = "IntroductionMessageFragment";
|
||||
private ShareForumActivity shareForumActivity;
|
||||
private ViewHolder ui;
|
||||
|
||||
// Fields that are accessed from background threads must be volatile
|
||||
@Inject protected volatile ForumSharingManager forumSharingManager;
|
||||
private volatile GroupId groupId;
|
||||
private volatile Collection<ContactId> contacts;
|
||||
|
||||
public static ShareForumMessageFragment newInstance(GroupId groupId,
|
||||
Collection<ContactId> contacts) {
|
||||
|
||||
ShareForumMessageFragment f = new ShareForumMessageFragment();
|
||||
|
||||
Bundle args = new Bundle();
|
||||
args.putByteArray(GROUP_ID, groupId.getBytes());
|
||||
args.putIntegerArrayList(CONTACTS, getContactsFromIds(contacts));
|
||||
f.setArguments(args);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
try {
|
||||
shareForumActivity = (ShareForumActivity) context;
|
||||
} catch (ClassCastException e) {
|
||||
throw new InstantiationError(
|
||||
"This fragment is only meant to be attached to the ShareForumActivity");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectActivity(AndroidComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
||||
// change toolbar text
|
||||
ActionBar actionBar = shareForumActivity.getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setTitle(R.string.forum_share_button);
|
||||
}
|
||||
|
||||
// allow for home button to act as back button
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
// inflate view
|
||||
View v =
|
||||
inflater.inflate(R.layout.share_forum_message, container,
|
||||
false);
|
||||
ui = new ViewHolder(v);
|
||||
ui.button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onButtonClick();
|
||||
}
|
||||
});
|
||||
|
||||
// get groupID and contactIDs from fragment arguments
|
||||
groupId = new GroupId(getArguments().getByteArray(GROUP_ID));
|
||||
ArrayList<Integer> intContacts =
|
||||
getArguments().getIntegerArrayList(CONTACTS);
|
||||
if (intContacts == null) throw new IllegalArgumentException();
|
||||
contacts = ShareForumActivity.getContactsFromIntegers(intContacts);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
shareForumActivity.onBackPressed();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUniqueTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
public void onButtonClick() {
|
||||
// disable button to prevent accidental double invitations
|
||||
ui.button.setEnabled(false);
|
||||
|
||||
String msg = ui.message.getText().toString();
|
||||
shareForum(msg);
|
||||
|
||||
// don't wait for the introduction to be made before finishing activity
|
||||
shareForumActivity.sharingSuccessful(ui.message);
|
||||
}
|
||||
|
||||
private void shareForum(final String msg) {
|
||||
shareForumActivity.runOnDbThread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
for (ContactId c : contacts) {
|
||||
forumSharingManager
|
||||
.sendForumInvitation(groupId, c, msg);
|
||||
}
|
||||
} catch (DbException e) {
|
||||
sharingError();
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void sharingError() {
|
||||
shareForumActivity.runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
Toast.makeText(shareForumActivity,
|
||||
R.string.introduction_error, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static class ViewHolder {
|
||||
final private TextView text;
|
||||
final private EditText message;
|
||||
final private Button button;
|
||||
|
||||
ViewHolder(View v) {
|
||||
text = (TextView) v.findViewById(R.id.introductionText);
|
||||
message = (EditText) v.findViewById(R.id.invitationMessageView);
|
||||
button = (Button) v.findViewById(R.id.shareForumButton);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user