mobisocial.musubi.ui.fragments.ContactsFragment.java Source code

Java tutorial

Introduction

Here is the source code for mobisocial.musubi.ui.fragments.ContactsFragment.java

Source

/*
 * Copyright 2012 The Stanford MobiSocial Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package mobisocial.musubi.ui.fragments;

import mobisocial.crypto.IBHashedIdentity.Authority;
import mobisocial.musubi.App;
import mobisocial.musubi.R;
import mobisocial.musubi.model.MFeed;
import mobisocial.musubi.model.MIdentity;
import mobisocial.musubi.model.MMyAccount;
import mobisocial.musubi.model.helpers.FeedManager;
import mobisocial.musubi.model.helpers.IdentitiesManager;
import mobisocial.musubi.model.helpers.MyAccountManager;
import mobisocial.musubi.service.MusubiService;
import mobisocial.musubi.ui.EmailInviteActivity;
import mobisocial.musubi.ui.ViewProfileActivity;
import mobisocial.musubi.ui.util.UiUtil;
import mobisocial.musubi.util.LessSpammyContentObserver;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.app.SupportActivity;
import android.support.v4.view.MenuItem;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Displays a list of contacts. If the intent used to create
 * this activity as Long extra "group_id", contacts are chosen
 * from this group. Otherwise, lists all known contacts.
 *
 */
public class ContactsFragment extends Fragment implements OnItemClickListener {
    private ContactListCursorAdapter mContacts;
    public static final String TAG = "ContactsFragment";
    public static final int GROUP_ID = 111;
    private static final int sBlockedColor = Color.parseColor("#66FF3333");

    public static enum ContactListType {
        WHITE_LIST, GRAY_LIST
    };

    public static final String CONTACT_LIST_TYPE = "contact_list_type";
    private ContactListType listType;

    private SQLiteOpenHelper mDatabaseSource;
    private IdentitiesManager mIdentityManager;
    private FeedManager mFeedManager;
    private MyAccountManager mAccountManager;

    private LessSpammyContentObserver mObserver;
    private ContentObserver mEditableObserver;
    private Activity mActivity;

    public static ContactsFragment newInstance(ContactListType type) {
        ContactsFragment frag = new ContactsFragment();
        Bundle args = new Bundle();
        args.putInt(CONTACT_LIST_TYPE, type.ordinal());
        frag.setArguments(args);
        return frag;
    }

    @Override
    public void onAttach(SupportActivity activity) {
        super.onAttach(activity);
        mActivity = activity.asActivity();
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.simple_list, container, false);
        Log.w(TAG, "returning view");
        return v;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mObserver = new LessSpammyContentObserver(new Handler(mActivity.getMainLooper())) {
            @Override
            public void lessSpammyOnChange(boolean arg0) {
                if (mContacts == null || mContacts.getCursor() == null || !isAdded())
                    return;
                mContacts.getCursor().requery();
            }
        };
        mEditableObserver = new ContentObserver(new Handler(mActivity.getMainLooper())) {
            @Override
            public void onChange(boolean arg0) {
                if (mContacts == null || mContacts.getCursor() == null || !isAdded())
                    return;
                mContacts.getCursor().requery();
            }
        };
    }

    @Override
    public void onResume() {
        super.onResume();
        mActivity.getContentResolver().registerContentObserver(MusubiService.WHITELIST_APPENDED, false,
                mEditableObserver);
        mActivity.getContentResolver().registerContentObserver(MusubiService.COLORLIST_CHANGED, false,
                mEditableObserver);
        mActivity.getContentResolver().registerContentObserver(MusubiService.PRIMARY_CONTENT_CHANGED, false,
                mObserver);
        mObserver.resetTimeout();
        mObserver.dispatchChange(false);
    }

    @Override
    public void onPause() {
        super.onPause();
        mActivity.getContentResolver().unregisterContentObserver(mObserver);
        mActivity.getContentResolver().unregisterContentObserver(mEditableObserver);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        listType = ContactListType.values()[getArguments().getInt(CONTACT_LIST_TYPE)];

        mDatabaseSource = App.getDatabaseSource(this.mActivity);
        mIdentityManager = new IdentitiesManager(mDatabaseSource);
        mFeedManager = new FeedManager(mDatabaseSource);
        mAccountManager = new MyAccountManager(mDatabaseSource);
        Cursor identities;

        if (listType == ContactListType.GRAY_LIST) {
            identities = mIdentityManager.getGrayListIdentitiesCursor();
        } else {
            identities = mIdentityManager.getWhiteListIdentitiesCursor();
        }

        mContacts = new ContactListCursorAdapter(this.mActivity, identities);

        ListView lv = (ListView) getView().findViewById(android.R.id.list);
        lv.setAdapter(mContacts);
        lv.setTextFilterEnabled(true);
        lv.setFastScrollEnabled(true);
        registerForContextMenu(lv);
        lv.setOnItemClickListener(this);
    }

    @Override
    public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
        final Cursor cursor = (Cursor) mContacts.getItem(position);
        final long identityId = cursor.getLong(cursor.getColumnIndexOrThrow(MIdentity.COL_ID));
        final MIdentity ident = mIdentityManager.getIdentityForId(identityId);
        assert (ident != null);
        switch (listType) {
        case WHITE_LIST:
            Intent intent = new Intent(mActivity, ViewProfileActivity.class);
            intent.putExtra(ViewProfileActivity.PROFILE_ID, identityId);
            mActivity.startActivity(intent);
            break;
        case GRAY_LIST:
            break;
        }
    }

    private void addContact(final MIdentity ident) {
        /*
        AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
        //name = cursor.getString(cursor.getColumnIndexOrThrow(Contact.NAME));
        String name = UiUtil.safeNameForIdentity(ident);
        builder = new AlertDialog.Builder(mActivity);
        //name = cursor.getString(cursor.getColumnIndexOrThrow(Contact.NAME));
        builder.setMessage("Do you want to add " + name + " to your friends list?")
          .setCancelable(true)
          .setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
              public void onClick(DialogInterface dialog, int id) {
                 addToWhitelist(ident);
                  dialog.cancel();
             }
          })
          .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
              public void onClick(DialogInterface dialog, int id) {
                  dialog.cancel();
              }
          });
        AlertDialog alert = builder.create();
        alert.show();*/
        addToWhitelist(ident);
    }

    void addToWhitelist(MIdentity ident) {
        ident.whitelisted_ = true;
        ident.blocked_ = false;
        //force a profile exchange to ensure we get an icon after a user action
        ident.sentProfileVersion_ = 0;
        mIdentityManager.updateIdentity(ident);
        mFeedManager.acceptFeedsFromMember(mActivity, ident.id_);
        //stop sending them broadcasts, e.g. profiles
        MMyAccount[] accounts = mAccountManager.getMyAccounts();
        boolean found_specific_account = false;
        for (MMyAccount account : accounts) {
            //TODO: someday you can remove these checks
            assert (account.identityId_ != null);
            if (account.identityId_ == null)
                continue;
            assert (account.feedId_ != null);
            if (account.feedId_ == null)
                continue;

            //check if this member is on a provisional whitelist, that's the identity we want to put them in
            if (!account.accountType_.equals(MMyAccount.INTERNAL_ACCOUNT_TYPE))
                continue;
            if (!account.accountName_.equals(MMyAccount.PROVISIONAL_WHITELIST_ACCOUNT))
                continue;
            MMyAccount whitelist_account = mAccountManager.getWhitelistForIdentity(account.identityId_);
            assert (whitelist_account != null); //should be guaranteed
            assert (whitelist_account.feedId_ != null); //should be guaranteed
            mFeedManager.ensureFeedMember(whitelist_account.feedId_, ident.id_);
            found_specific_account = true;
        }
        //put them in an unassociated group which will always use the default identity whatever that is
        if (!found_specific_account) {
            mFeedManager.ensureFeedMember(MFeed.NONIDENTITY_SPECIFIC_WHITELIST_ID, ident.id_);
        }
        mObserver.resetTimeout();
        mActivity.getContentResolver().notifyChange(MusubiService.WHITELIST_APPENDED, null);
        mActivity.getContentResolver().notifyChange(MusubiService.COLORLIST_CHANGED, null);
    }

    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
        Cursor c = (Cursor) mContacts.getItem(info.position);
        long identityId = c.getLong(c.getColumnIndexOrThrow(MIdentity.COL_ID));
        MIdentity ident = mIdentityManager.getIdentityForId(identityId);
        String[] menuItems;
        if (ident.type_ == Authority.Email && !ident.claimed_) {
            menuItems = new String[] { "Ignore", "Invite" };
        } else {
            menuItems = new String[] { "Ignore" };
        }

        for (int i = 0; i < menuItems.length; i++) {
            menu.add(GROUP_ID, i, i, menuItems[i]);
        }
    }

    public boolean onContextItemSelected(MenuItem item) {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
        int menuItemIndex = item.getItemId();

        Cursor cursor = (Cursor) mContacts.getItem(info.position);
        final MIdentity ident = mIdentityManager
                .getIdentityForId(cursor.getLong(cursor.getColumnIndexOrThrow(MIdentity.COL_ID)));

        switch (menuItemIndex) {
        case 0:
            ignoreContact(ident);
            break;
        case 1:
            String email = ident.principal_;
            if (email == null) {
                Toast.makeText(getActivity(), "Oops, couldn't set up email.", Toast.LENGTH_SHORT).show();
                return true;
            }

            Intent intent = EmailInviteActivity.getInviteIntentForEmail(getActivity(), email);
            startActivity(intent);
            break;
        }
        return true;
    }

    private void ignoreContact(final MIdentity ident) {
        AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
        //name = cursor.getString(cursor.getColumnIndexOrThrow(Contact.NAME));
        String name = UiUtil.safeNameForIdentity(ident);
        builder.setMessage("Are you sure you want to ignore " + name + "?").setCancelable(true)
                .setPositiveButton("Ignore", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        ident.whitelisted_ = false;
                        ident.blocked_ = true;
                        mIdentityManager.updateIdentity(ident);
                        //stop sending them broadcasts, e.g. profiles
                        MMyAccount[] accounts = mAccountManager.getMyAccounts();
                        for (MMyAccount account : accounts) {
                            //TODO: someday you can remove these checks
                            assert (account.feedId_ != null);
                            if (account.feedId_ == null)
                                continue;

                            mFeedManager.deleteFeedMember(account.feedId_, ident.id_);
                        }
                        //TODO: hide all the feeds this person is the only other person on?
                        //TODO: hide this persons objects or delete them? ew?
                        mObserver.resetTimeout();
                        mActivity.getContentResolver().notifyChange(MusubiService.COLORLIST_CHANGED, null);
                    }
                }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }
                });
        AlertDialog alert = builder.create();
        alert.show();
    }

    private class ContactListCursorAdapter extends CursorAdapter {
        public ContactListCursorAdapter(Context context, Cursor c) {
            super(context, c);
        }

        @Override
        public View newView(Context context, Cursor c, ViewGroup parent) {
            final LayoutInflater inflater = LayoutInflater.from(context);
            View v = inflater.inflate(R.layout.contacts_item, parent, false);
            return v;
        }

        @Override
        public void bindView(View v, Context context, Cursor cursor) {
            final MIdentity ident = mIdentityManager.getIdentityForId(cursor.getLong(0));
            v.setTag(ident.id_);

            TextView nameText = (TextView) v.findViewById(R.id.name_text);
            nameText.setText(UiUtil.safeNameForIdentity(ident));

            TextView principalText = (TextView) v.findViewById(R.id.principal_text);
            principalText.setText(UiUtil.safePrincipalForIdentity(ident));

            TextView statusText = (TextView) v.findViewById(R.id.status_text);
            statusText.setVisibility(View.GONE);

            TextView unreadCount = (TextView) v.findViewById(R.id.unread_count);
            unreadCount.setVisibility(View.GONE);

            ImageView icon = (ImageView) v.findViewById(R.id.icon);
            icon.setImageBitmap(UiUtil.safeGetContactThumbnail(context, mIdentityManager, ident));

            final ImageView presenceIcon = (ImageView) v.findViewById(R.id.presence_icon);
            presenceIcon.setVisibility(View.GONE);
            //presenceIcon.setImageResource(c.currentPresenceResource());

            final ImageView nearbyIcon = (ImageView) v.findViewById(R.id.nearby_icon);
            nearbyIcon.setVisibility(View.GONE);
            //nearbyIcon.setVisibility(c.nearby ? View.VISIBLE : View.GONE);

            final ImageView more = (ImageView) v.findViewById(R.id.more);
            more.setVisibility(View.GONE);

            if (listType == ContactListType.GRAY_LIST) {
                final View buttonBar = v.findViewById(R.id.button_bar);
                buttonBar.setVisibility(View.VISIBLE);

                Button addButton = (Button) v.findViewById(R.id.add_contact);
                addButton.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        addContact(ident);
                    }
                });

                Button ignoreButton = (Button) v.findViewById(R.id.ignore_contact);
                if (ident.blocked_) {
                    ignoreButton.setVisibility(View.GONE);
                    addButton.setText("Un-ignore");
                } else {
                    ignoreButton.setOnClickListener(new OnClickListener() {

                        @Override
                        public void onClick(View v) {
                            // TODO Auto-generated method stub
                            ignoreContact(ident);
                        }
                    });
                }
            }

            ImageView musubiEnabled = (ImageView) v.findViewById(R.id.musubi_enabled);
            ImageView ignoredOverlay = (ImageView) v.findViewById(R.id.ignored_overlay);
            if (ident.claimed_) {
                ignoredOverlay.setVisibility(View.GONE);
                nameText.setTextColor(Color.BLACK);
                principalText.setTextColor(Color.BLACK);
                musubiEnabled.setBackgroundResource(R.drawable.musubi_enabled);
            } else {
                ignoredOverlay.setVisibility(View.GONE);
                nameText.setTextColor(Color.BLACK);
                principalText.setTextColor(Color.BLACK);
                musubiEnabled.setBackgroundResource(R.drawable.musubi_disabled);
            }

            if (ident.blocked_) {
                nameText.setTextColor(sBlockedColor);
                principalText.setTextColor(sBlockedColor);
                ignoredOverlay.setVisibility(View.VISIBLE);
            }

            musubiEnabled.setVisibility(View.VISIBLE);
        }
    }
}