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

Java tutorial

Introduction

Here is the source code for mobisocial.musubi.ui.fragments.ViewProfileFragment.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 java.io.IOException;

import mobisocial.crypto.IBHashedIdentity;
import mobisocial.metrics.MusubiMetrics;
import mobisocial.musubi.App;
import mobisocial.musubi.R;
import mobisocial.musubi.model.MIdentity;
import mobisocial.musubi.model.helpers.IdentitiesManager;
import mobisocial.musubi.objects.PictureObj;
import mobisocial.musubi.service.MusubiService;
import mobisocial.musubi.service.WizardStepHandler;
import mobisocial.musubi.ui.EmailInviteActivity;
import mobisocial.musubi.ui.MusubiBaseActivity;
import mobisocial.musubi.ui.ViewProfileActivity;
import mobisocial.musubi.ui.util.AddToWhitelistListener;
import mobisocial.musubi.ui.util.EmojiSpannableFactory;
import mobisocial.musubi.ui.util.UiUtil;
import mobisocial.musubi.util.UriImage;
import mobisocial.socialkit.Obj;
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.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Intents.Insert;
import android.provider.ContactsContract.QuickContact;
import android.support.v4.app.Fragment;
import android.support.v4.app.SupportActivity;
import android.text.Editable;
import android.text.Spannable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

public class ViewProfileFragment extends Fragment {
    private ImageView mThumbnail;
    private TextView mProfileName, mProfilePrincipal;
    private TextView mEditProfileNameButton, mAddToAddressBook;
    //private TextView mProfileEmail;
    //private TextView mProfileAbout;
    private Activity mActivity;

    MIdentity mIdent;
    private ContentObserver mObserver;
    private IdentitiesManager mIdentitiesManager;
    private long mId;
    private TextView mAddToFriends;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SQLiteOpenHelper helper = App.getDatabaseSource(mActivity);
        mIdentitiesManager = new IdentitiesManager(helper);
        mId = this.getArguments().getLong(ViewProfileActivity.PROFILE_ID);

        mIdent = mIdentitiesManager.getIdentityWithThumbnailsForId(mId);

        //TODO: some of these can be "deduped" but some can't e.g. we depend on the my profile updated
        //ones to refresh the ui after a change happens.  for now, just don't leave musubi open to the profile screen
        //while your gettign a huge blast of changes
        mObserver = new ContentObserver(new Handler(mActivity.getMainLooper())) {
            @Override
            public void onChange(boolean arg0) {
                updateDynamicElements();
            }
        };
    }

    @Override
    public void onResume() {
        super.onResume();
        updateDynamicElements();

        if (mIdent.owned_) {
            mActivity.getContentResolver().registerContentObserver(MusubiService.MY_PROFILE_UPDATED, false,
                    mObserver);
        } else {
            mActivity.getContentResolver().registerContentObserver(MusubiService.PRIMARY_CONTENT_CHANGED, false,
                    mObserver);
        }
        mActivity.getContentResolver().registerContentObserver(MusubiService.WHITELIST_APPENDED, false, mObserver);
        mActivity.getContentResolver().registerContentObserver(MusubiService.COLORLIST_CHANGED, false, mObserver);
        mObserver.dispatchChange(false);
    }

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

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

    public static ViewProfileFragment newInstance(Long id) {
        ViewProfileFragment frag = new ViewProfileFragment();
        Bundle args = new Bundle();
        args.putLong(ViewProfileActivity.PROFILE_ID, id);
        frag.setArguments(args);
        return frag;
    }

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.view_profile, container, false);

        Spinner presence = (Spinner) v.findViewById(R.id.view_profile_presence);
        presence.setVisibility(View.GONE);

        mThumbnail = (ImageView) v.findViewById(R.id.view_profile_thumbnail);
        if (mIdent.owned_) {
            //show the person that they need to set their own musubi thumbnail if necessary
            if (!mIdentitiesManager.hasMusubiThumbnail(mIdent)) {
                mThumbnail.setImageResource(R.drawable.ic_set_profile_picture);
            } else {
                mThumbnail.setImageBitmap(UiUtil.safeGetContactPicture(mActivity, mIdentitiesManager, mIdent));
            }
        } else {
            //always just use the best available thumbnail for a friend
            mThumbnail.setImageBitmap(UiUtil.safeGetContactPicture(mActivity, mIdentitiesManager, mIdent));
        }
        mThumbnail.setOnLongClickListener(mCopyThumbnailToClipboard);
        mThumbnail.setOnClickListener(mThumbnailClickListener);

        mProfileName = (TextView) v.findViewById(R.id.view_profile_name);
        Spannable span = EmojiSpannableFactory.getInstance(mActivity)
                .newSpannable(UiUtil.safeNameForIdentity(mIdent));
        mProfileName.setText(span);

        mProfilePrincipal = (TextView) v.findViewById(R.id.view_profile_principal);

        mEditProfileNameButton = (TextView) v.findViewById(R.id.view_edit_profile_name);
        if (mIdent.owned_) {
            mThumbnail.setOnClickListener(new ThumbnailOnClickListener());
            mEditProfileNameButton.setOnClickListener(new EditNameOnClickListener());
            mProfilePrincipal.setVisibility(View.GONE);
        } else {
            mEditProfileNameButton.setVisibility(View.GONE);
            String email = UiUtil.safePrincipalForIdentity(mIdent);
            if (email != null) {
                // TODO: Fearful of the pushiness. On hold.
                v.findViewById(R.id.invite_over_email).setVisibility(View.GONE);
                v.findViewById(R.id.invite_over_email).setOnClickListener(mEmailListener);
                mProfilePrincipal.setText(email);
            }
        }

        mAddToFriends = (TextView) v.findViewById(R.id.add_to_friends);

        //TODO: android contact sync can change this state
        mAddToAddressBook = (TextView) v.findViewById(R.id.add_to_addressbook);
        updateDynamicElements();

        return v;
    }

    View.OnClickListener mEmailListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            App.getUsageMetrics(getActivity()).report(MusubiMetrics.CLICKED_TO_INVITE);
            String email = UiUtil.safePrincipalForIdentity(mIdent);
            Intent intent = EmailInviteActivity.getInviteIntentForEmail(getActivity(), email);
            startActivity(intent);
        }
    };

    void updateDynamicElements() {
        mIdent = mIdentitiesManager.getIdentityForId(mId);
        if (mIdent.owned_ && !mIdentitiesManager.hasMusubiThumbnail(mIdent)) {
            mThumbnail.setImageResource(R.drawable.ic_set_profile_picture);
        } else {
            mThumbnail.setImageBitmap(UiUtil.safeGetContactPicture(mActivity, mIdentitiesManager, mIdent));
        }
        Spannable span = EmojiSpannableFactory.getInstance(mActivity)
                .newSpannable(UiUtil.safeNameForIdentity(mIdent));
        mProfileName.setText(span);
        if (shouldShowAddToFriends()) {
            mAddToFriends.setVisibility(View.VISIBLE);
            mAddToFriends.setOnClickListener(new AddToWhitelistListener(mActivity, mIdent));
        } else {
            mAddToFriends.setVisibility(View.GONE);
        }
        if (shouldShowAddToAddressBook()) {
            mAddToAddressBook.setVisibility(View.VISIBLE);
            mAddToAddressBook.setOnClickListener(new AddToAddressBookListener());
        } else {
            mAddToAddressBook.setVisibility(View.GONE);
        }
    }

    boolean shouldShowAddToFriends() {
        //not owned is only necessary because our bootstrap identity is not whitelisted
        //and the view profile will show that profile
        return !mIdent.whitelisted_ && !mIdent.owned_;
    }

    boolean shouldShowAddToAddressBook() {
        return mIdent.whitelisted_ && mIdent.androidAggregatedContactId_ == null
                && mIdent.type_ == IBHashedIdentity.Authority.Email && mIdent.principal_ != null;
    }

    private class AddToAddressBookListener implements OnClickListener {
        @Override
        public void onClick(View v) {
            Intent i = new Intent(Intent.ACTION_INSERT_OR_EDIT);
            i.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);

            if (mIdent.musubiName_ != null) {
                i.putExtra(Insert.NAME, mIdent.musubiName_);
            }
            if (mIdent.type_ == IBHashedIdentity.Authority.Email) {
                i.putExtra(Insert.EMAIL, UiUtil.safePrincipalForIdentity(mIdent));
            }
            mActivity.startActivity(i);
        }
    }

    private class ThumbnailOnClickListener implements OnClickListener {
        @Override
        public void onClick(View v) {
            ChooseImageDialog spd = ChooseImageDialog.newInstance();
            spd.setTargetFragment(ViewProfileFragment.this, ChooseImageDialog.REQUEST_PROFILE_PICTURE);
            ((MusubiBaseActivity) getActivity()).showDialog(spd);
        }
    }

    private class EditNameOnClickListener implements OnClickListener {
        @Override
        public void onClick(View v) {
            AlertDialog.Builder alert = new AlertDialog.Builder(mActivity);

            alert.setTitle("Change your name");

            // Set an EditText view to get user input 
            final EditText input = new EditText(mActivity);

            Spannable span = EmojiSpannableFactory.getInstance(mActivity)
                    .newSpannable(UiUtil.safeNameForIdentity(mIdent));
            input.setText(span);
            input.addTextChangedListener(new TextWatcher() {
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                }

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                }

                @Override
                public void afterTextChanged(Editable s) {
                    EmojiSpannableFactory.getInstance(mActivity).updateSpannable(s);
                }
            });
            alert.setView(input);

            alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    String newName = input.getText().toString();
                    SQLiteOpenHelper helper = App.getDatabaseSource(mActivity);
                    IdentitiesManager manager = new IdentitiesManager(helper);
                    mIdent.musubiName_ = newName;
                    manager.updateMyProfileName(mActivity, newName, true);
                    WizardStepHandler.accomplishTask(mActivity, WizardStepHandler.TASK_SET_PROFILE_NAME);
                    App.getUsageMetrics(mActivity).report(MusubiMetrics.PROFILE_NAME_UPDATED);
                }
            });

            alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                }
            });

            final AlertDialog dialog = alert.create();

            input.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                @Override
                public void onFocusChange(View v, boolean hasFocus) {
                    if (hasFocus) {
                        ((EditText) v).selectAll();
                        dialog.getWindow()
                                .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
                    }
                }
            });

            dialog.show();

        }
    }

    View.OnLongClickListener mCopyThumbnailToClipboard = new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            IdentitiesManager im = new IdentitiesManager(App.getDatabaseSource(getActivity()));
            MIdentity person = im.getIdentityWithThumbnailsForId(mId);
            byte[] data = person.musubiThumbnail_;
            if (data == null) {
                data = person.thumbnail_;
            }
            if (data != null) {
                Obj obj = PictureObj.from(data);
                new ClipboardKeeper(getActivity()).store(obj, false);
                Toast.makeText(getActivity(), "Copied thumbnail to clipboard.", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(getActivity(), "No thumbnail to copy.", Toast.LENGTH_LONG).show();
            }
            return true;
        }
    };

    View.OnClickListener mThumbnailClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Context context = getActivity();
            String lookupKey = IdentitiesManager.androidLookupKeyForIdentitiy(context, mIdent);
            if (lookupKey == null) {
                return;
            }
            Uri lookupUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey);
            QuickContact.showQuickContact(context, v, lookupUri, QuickContact.MODE_LARGE, null);
        }
    };

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == ChooseImageDialog.REQUEST_PROFILE_PICTURE) {
            if (resultCode == Activity.RESULT_OK) {
                byte[] thumbnail = data.getByteArrayExtra(ChooseImageDialog.EXTRA_THUMBNAIL);
                setThumbnail(thumbnail);
            }
        }
        if (requestCode == ChooseImageDialog.REQUEST_GALLERY_THUMBNAIL) {
            if (resultCode == Activity.RESULT_OK) {
                new ThumbnailTask().execute(data.getData());
            }
        }
    };

    /**
     * Prepares a byte[] from an image uri in the background and sets
     * it on the main thread.
     *
     */
    class ThumbnailTask extends AsyncTask<Uri, Void, byte[]> {
        @Override
        protected byte[] doInBackground(Uri... params) {
            try {
                UriImage image = new UriImage(getActivity(), params[0]);
                return image.getResizedImageData(300, 300, 20 * 1024, true);
            } catch (IOException e) {
                Toast.makeText(getActivity(), "Error getting picture.", Toast.LENGTH_LONG).show();
            }
            return null;
        }

        @Override
        protected void onPostExecute(byte[] result) {
            // triggers a toast in WizardStepHandler, requires looper.
            setThumbnail(result);
        }
    }

    void setThumbnail(byte[] thumbnail) {
        SQLiteOpenHelper helper = App.getDatabaseSource(getActivity());
        IdentitiesManager manager = new IdentitiesManager(helper);
        manager.updateMyProfileThumbnail(getActivity(), thumbnail, true);
        mIdent.thumbnail_ = thumbnail;
        WizardStepHandler.accomplishTask(mActivity, WizardStepHandler.TASK_SET_PROFILE_PICTURE);
        App.getUsageMetrics(mActivity).report(MusubiMetrics.PROFILE_PICTURE_UPDATED);
    }
}