org.mariotaku.twidere.fragment.UserProfileFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.mariotaku.twidere.fragment.UserProfileFragment.java

Source

/*
 *            Twidere - Twitter client for Android
 * 
 * Copyright (C) 2012 Mariotaku Lee <mariotaku.lee@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.mariotaku.twidere.fragment;

import static android.os.Environment.getExternalStorageDirectory;
import static android.os.Environment.getExternalStorageState;
import static android.text.TextUtils.isEmpty;
import static org.mariotaku.twidere.util.Utils.addIntentToSubMenu;
import static org.mariotaku.twidere.util.Utils.clearUserColor;
import static org.mariotaku.twidere.util.Utils.createTakePhotoIntent;
import static org.mariotaku.twidere.util.Utils.formatToLongTimeString;
import static org.mariotaku.twidere.util.Utils.getAccountColor;
import static org.mariotaku.twidere.util.Utils.getImagePathFromUri;
import static org.mariotaku.twidere.util.Utils.getOriginalTwitterProfileImage;
import static org.mariotaku.twidere.util.Utils.getTwitterInstance;
import static org.mariotaku.twidere.util.Utils.getUserColor;
import static org.mariotaku.twidere.util.Utils.getUserTypeIconRes;
import static org.mariotaku.twidere.util.Utils.isMyAccount;
import static org.mariotaku.twidere.util.Utils.openImage;
import static org.mariotaku.twidere.util.Utils.openIncomingFriendships;
import static org.mariotaku.twidere.util.Utils.openSavedSearches;
import static org.mariotaku.twidere.util.Utils.openTweetSearch;
import static org.mariotaku.twidere.util.Utils.openUserBlocks;
import static org.mariotaku.twidere.util.Utils.openUserFavorites;
import static org.mariotaku.twidere.util.Utils.openUserFollowers;
import static org.mariotaku.twidere.util.Utils.openUserFriends;
import static org.mariotaku.twidere.util.Utils.openUserLists;
import static org.mariotaku.twidere.util.Utils.openUserMentions;
import static org.mariotaku.twidere.util.Utils.openUserProfile;
import static org.mariotaku.twidere.util.Utils.openUserTimeline;
import static org.mariotaku.twidere.util.Utils.setUserColor;

import java.io.File;

import org.mariotaku.popupmenu.PopupMenu;
import org.mariotaku.popupmenu.PopupMenu.OnMenuItemClickListener;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.EditUserProfileActivity;
import org.mariotaku.twidere.activity.SetColorActivity;
import org.mariotaku.twidere.adapter.ListActionAdapter;
import org.mariotaku.twidere.loader.ParcelableUserLoader;
import org.mariotaku.twidere.loader.UserBannerImageLoader;
import org.mariotaku.twidere.model.ListAction;
import org.mariotaku.twidere.model.Panes;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.model.SingleResponse;
import org.mariotaku.twidere.provider.TweetStore.Accounts;
import org.mariotaku.twidere.provider.TweetStore.CachedUsers;
import org.mariotaku.twidere.provider.TweetStore.Filters;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.EnvironmentAccessor;
import org.mariotaku.twidere.util.LazyImageLoader;
import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener;
import org.mariotaku.twidere.view.ColorLabelRelativeLayout;
import org.mariotaku.twidere.view.ProfileNameBannerContainer;
import org.mariotaku.twidere.view.iface.IExtendedView.OnSizeChangedListener;

import twitter4j.Relationship;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
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.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public class UserProfileFragment extends BaseListFragment implements OnClickListener, OnItemClickListener,
        OnItemLongClickListener, OnMenuItemClickListener, OnLinkClickListener, Panes.Right, OnSizeChangedListener {

    private static final int LOADER_ID_USER = 1;
    private static final int LOADER_ID_FRIENDSHIP = 2;
    private static final int LOADER_ID_BANNER = 3;

    private LazyImageLoader mProfileImageLoader;
    private SharedPreferences mPreferences;

    private ImageView mProfileImageView;
    private TextView mNameView, mScreenNameView, mDescriptionView, mLocationView, mURLView, mCreatedAtView,
            mTweetCount, mFollowersCount, mFriendsCount, mFollowingYouIndicator, mErrorMessageView;
    private View mNameContainer, mProfileImageContainer, mDescriptionContainer, mLocationContainer, mURLContainer,
            mTweetsContainer, mFollowersContainer, mFriendsContainer, mEditFollowContainer, mMoreOptionsContainer;
    private ProfileNameBannerContainer mProfileNameBannerContainer;
    private ProgressBar mFollowProgress, mMoreOptionsProgress;
    private Button mEditFollowButton, mMoreOptionsButton, mRetryButton;
    private ColorLabelRelativeLayout mProfileNameContainer;
    private ListView mListView;
    private View mHeaderView;

    private ListActionAdapter mAdapter;

    private long mAccountId;
    private Uri mImageUri;
    private Relationship mFriendship;
    private ParcelableUser mUser = null;

    private View mListContainer, mErrorRetryContainer;

    private boolean mGetUserInfoLoaderInitialized;
    private boolean mGetFriendShipLoaderInitialized;
    private boolean mBannerImageLoaderInitialized;

    private long mUserId;
    private String mScreenName;
    private int mBannerWidth;

    private AsyncTwitterWrapper mTwitterWrapper;

    private PopupMenu mPopupMenu;

    private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(final Context context, final Intent intent) {
            if (mUser == null)
                return;
            final String action = intent.getAction();
            if (BROADCAST_FRIENDSHIP_CHANGED.equals(action)) {
                if (intent.getLongExtra(INTENT_KEY_USER_ID, -1) == mUser.user_id
                        && intent.getBooleanExtra(INTENT_KEY_SUCCEED, false)) {
                    getFriendship();
                }
            }
            if (BROADCAST_BLOCKSTATE_CHANGED.equals(action)) {
                if (intent.getLongExtra(INTENT_KEY_USER_ID, -1) == mUser.user_id
                        && intent.getBooleanExtra(INTENT_KEY_SUCCEED, false)) {
                    getFriendship();
                }
            }
            if (BROADCAST_PROFILE_UPDATED.equals(action) || BROADCAST_PROFILE_IMAGE_UPDATED.equals(action)
                    || BROADCAST_PROFILE_BANNER_UPDATED.equals(action)) {
                if (intent.getLongExtra(INTENT_KEY_USER_ID, -1) == mUser.user_id
                        && intent.getBooleanExtra(INTENT_KEY_SUCCEED, false)) {
                    getUserInfo(true);
                }
            }
        }
    };

    private final LoaderCallbacks<SingleResponse<ParcelableUser>> mUserInfoLoaderCallbacks = new LoaderCallbacks<SingleResponse<ParcelableUser>>() {

        @Override
        public Loader<SingleResponse<ParcelableUser>> onCreateLoader(final int id, final Bundle args) {
            mListContainer.setVisibility(View.VISIBLE);
            mErrorRetryContainer.setVisibility(View.GONE);
            mErrorMessageView.setText(null);
            mErrorMessageView.setVisibility(View.GONE);
            setListShown(mUser != null);
            setProgressBarIndeterminateVisibility(true);
            final boolean omit_intent_extra = args != null ? args.getBoolean(INTENT_KEY_OMIT_INTENT_EXTRA, true)
                    : true;
            return new ParcelableUserLoader(getActivity(), mAccountId, mUserId, mScreenName, getArguments(),
                    omit_intent_extra, mUser == null || !mUser.is_cache && mUserId != mUser.user_id);
        }

        @Override
        public void onLoaderReset(final Loader<SingleResponse<ParcelableUser>> loader) {

        }

        @Override
        public void onLoadFinished(final Loader<SingleResponse<ParcelableUser>> loader,
                final SingleResponse<ParcelableUser> data) {
            if (getActivity() == null)
                return;
            if (data.data != null && data.data.user_id > 0) {
                setListShown(true);
                displayUser(data.data);
                mErrorRetryContainer.setVisibility(View.GONE);
                if (data.data.is_cache) {
                    getLoaderManager().restartLoader(LOADER_ID_USER, null, this);
                }
            } else if (mUser != null && mUser.is_cache
                    && (mUserId == mUser.user_id || mScreenName != null && mScreenName.equals(mUser.screen_name))) {
                setListShown(true);
                displayUser(mUser);
            } else {
                if (data.exception != null) {
                    mErrorMessageView.setText(data.exception.getMessage());
                    mErrorMessageView.setVisibility(View.VISIBLE);
                }
                mListContainer.setVisibility(View.GONE);
                mErrorRetryContainer.setVisibility(View.VISIBLE);
            }
            setProgressBarIndeterminateVisibility(false);
        }

    };

    private final LoaderCallbacks<SingleResponse<Relationship>> mFriendshipLoaderCallbacks = new LoaderCallbacks<SingleResponse<Relationship>>() {

        @Override
        public Loader<SingleResponse<Relationship>> onCreateLoader(final int id, final Bundle args) {
            final boolean user_is_me = mUserId == mAccountId;
            mFollowingYouIndicator.setVisibility(View.GONE);
            mEditFollowContainer.setVisibility(View.VISIBLE);
            mMoreOptionsContainer.setVisibility(user_is_me ? View.VISIBLE : View.GONE);
            mEditFollowButton.setVisibility(user_is_me ? View.VISIBLE : View.GONE);
            mFollowProgress.setVisibility(user_is_me ? View.GONE : View.VISIBLE);
            mMoreOptionsButton.setVisibility(View.GONE);
            mMoreOptionsProgress.setVisibility(user_is_me ? View.GONE : View.VISIBLE);
            mEditFollowButton.setText(user_is_me ? R.string.edit : R.string.loading);
            return new FriendshipLoader(getActivity(), mAccountId, mUserId);
        }

        @Override
        public void onLoaderReset(final Loader<SingleResponse<Relationship>> loader) {

        }

        @Override
        public void onLoadFinished(final Loader<SingleResponse<Relationship>> loader,
                final SingleResponse<Relationship> data) {
            mFriendship = null;
            if (mUser == null)
                return;
            final boolean user_is_me = mAccountId == mUserId;
            if (data.data != null) {
                mFriendship = data.data;
                final boolean followed_by_user = data.data.isTargetFollowingSource();
                mEditFollowButton.setVisibility(View.VISIBLE);
                if (data.data.isSourceFollowingTarget()) {
                    mEditFollowButton.setText(R.string.unfollow);
                } else {
                    if (mUser.is_protected) {
                        mEditFollowButton.setText(mUser.is_follow_request_sent ? R.string.follow_request_sent
                                : R.string.send_follow_request);
                    } else {
                        mEditFollowButton.setText(R.string.follow);
                    }
                }
                mFollowingYouIndicator.setVisibility(followed_by_user && !user_is_me ? View.VISIBLE : View.GONE);
                final ContentResolver resolver = getContentResolver();
                final String where = CachedUsers.USER_ID + " = " + mUserId;
                resolver.delete(CachedUsers.CONTENT_URI, where, null);
                // I bet you don't want to see blocked user in your auto
                // complete list.
                if (!data.data.isSourceBlockingTarget()) {
                    final ContentValues cached_values = ParcelableUser.makeCachedUserContentValues(mUser);
                    if (cached_values != null) {
                        resolver.insert(CachedUsers.CONTENT_URI, cached_values);
                    }
                }
            }
            mEditFollowContainer.setVisibility(data.data == null && !user_is_me ? View.GONE : View.VISIBLE);
            mMoreOptionsContainer.setVisibility(data.data == null && !user_is_me ? View.GONE : View.VISIBLE);
            mMoreOptionsButton.setVisibility(data.data != null || user_is_me ? View.VISIBLE : View.GONE);
            mFollowProgress.setVisibility(View.GONE);
            mMoreOptionsProgress.setVisibility(View.GONE);
        }

    };

    private final LoaderCallbacks<Bitmap> mBannerImageCallback = new LoaderCallbacks<Bitmap>() {

        @Override
        public Loader<Bitmap> onCreateLoader(final int id, final Bundle args) {
            mProfileNameBannerContainer.setBanner(null);
            final int def_width = getResources().getDisplayMetrics().widthPixels;
            final int width = mBannerWidth > 0 ? mBannerWidth : def_width;
            return new UserBannerImageLoader(getActivity(), mUser, width, true);
        }

        @Override
        public void onLoaderReset(final Loader<Bitmap> loader) {
        }

        @Override
        public void onLoadFinished(final Loader<Bitmap> loader, final Bitmap data) {
            mProfileNameBannerContainer.setBanner(data);
        }

    };

    public void displayUser(final ParcelableUser user) {
        mFriendship = null;
        mUser = null;
        mUserId = -1;
        mAccountId = -1;
        mAdapter.clear();
        if (user == null || user.user_id <= 0 || getActivity() == null)
            return;
        final LoaderManager lm = getLoaderManager();
        lm.destroyLoader(LOADER_ID_USER);
        lm.destroyLoader(LOADER_ID_FRIENDSHIP);
        final boolean user_is_me = user.account_id == user.user_id;
        mErrorRetryContainer.setVisibility(View.GONE);
        mAccountId = user.account_id;
        mUser = user;
        mUserId = user.user_id;
        mScreenName = user.screen_name;
        mProfileNameContainer.drawLeft(getUserColor(getActivity(), mUserId));
        mProfileNameContainer.drawRight(getAccountColor(getActivity(), user.account_id));
        mNameView.setText(user.name);
        mNameView.setCompoundDrawablesWithIntrinsicBounds(0, 0,
                getUserTypeIconRes(user.is_verified, user.is_protected), 0);
        mScreenNameView.setText("@" + user.screen_name);
        final String description = user.description;
        mDescriptionContainer.setVisibility(user_is_me || !isEmpty(description) ? View.VISIBLE : View.GONE);
        mDescriptionView.setText(description);
        final TwidereLinkify linkify = new TwidereLinkify(mDescriptionView);
        linkify.setOnLinkClickListener(this);
        linkify.addAllLinks();
        mDescriptionView.setMovementMethod(null);
        final String location = user.location;
        mLocationContainer.setVisibility(user_is_me || !isEmpty(location) ? View.VISIBLE : View.GONE);
        mLocationView.setText(location);
        mURLContainer.setVisibility(user_is_me || !isEmpty(user.url) ? View.VISIBLE : View.GONE);
        mURLView.setText(user.url);
        mURLView.setMovementMethod(null);
        mCreatedAtView.setText(formatToLongTimeString(getActivity(), user.created_at));
        mTweetCount.setText(String.valueOf(user.statuses_count));
        mFollowersCount.setText(String.valueOf(user.followers_count));
        mFriendsCount.setText(String.valueOf(user.friends_count));
        if (mPreferences.getBoolean(PREFERENCE_KEY_DISPLAY_PROFILE_IMAGE, true)) {
            mProfileImageLoader.displayImage(mProfileImageView, user.profile_image_url);
        } else {
            mProfileImageView.setImageResource(R.drawable.ic_profile_image_default);
        }
        if (isMyAccount(getActivity(), user.user_id)) {
            final ContentResolver resolver = getContentResolver();
            final ContentValues values = new ContentValues();
            if (user.profile_image_url != null) {
                values.put(Accounts.PROFILE_IMAGE_URL, user.profile_image_url);
            }
            values.put(Accounts.NAME, user.name);
            values.put(Accounts.SCREEN_NAME, user.screen_name);
            final String where = Accounts.ACCOUNT_ID + " = " + user.user_id;
            resolver.update(Accounts.CONTENT_URI, values, where, null);
        }
        mAdapter.add(new FavoritesAction(1));
        mAdapter.add(new UserMentionsAction(2));
        mAdapter.add(new UserListsAction(3));
        if (user_is_me) {
            mAdapter.add(new SavedSearchesAction(4));
            if (user.is_protected) {
                mAdapter.add(new IncomingFriendshipsAction(5));
            }
            mAdapter.add(new UserBlocksAction(6));
        }
        mAdapter.notifyDataSetChanged();
        if (!user.is_cache) {
            getFriendship();
        }
        getBannerImage();
    }

    public void getUserInfo(final long account_id, final long user_id, final String screen_name,
            final boolean omit_intent_extra) {
        mAccountId = account_id;
        mUserId = user_id;
        mScreenName = screen_name;
        final LoaderManager lm = getLoaderManager();
        lm.destroyLoader(LOADER_ID_USER);
        lm.destroyLoader(LOADER_ID_FRIENDSHIP);
        lm.destroyLoader(LOADER_ID_BANNER);
        if (!isMyAccount(getActivity(), mAccountId)) {
            mListContainer.setVisibility(View.GONE);
            mErrorRetryContainer.setVisibility(View.GONE);
            return;
        }
        final Bundle args = new Bundle();
        args.putBoolean(INTENT_KEY_OMIT_INTENT_EXTRA, omit_intent_extra);
        if (!mGetUserInfoLoaderInitialized) {
            lm.initLoader(LOADER_ID_USER, args, mUserInfoLoaderCallbacks);
            mGetUserInfoLoaderInitialized = true;
        } else {
            lm.restartLoader(LOADER_ID_USER, args, mUserInfoLoaderCallbacks);
        }
        if (account_id == -1 || user_id == -1 && screen_name == null) {
            mListContainer.setVisibility(View.GONE);
            mErrorRetryContainer.setVisibility(View.GONE);
            return;
        }
    }

    @Override
    public void onActivityCreated(final Bundle savedInstanceState) {
        mTwitterWrapper = getApplication().getTwitterWrapper();
        mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
        super.onActivityCreated(savedInstanceState);
        final Bundle args = getArguments();
        long account_id = -1, user_id = -1;
        String screen_name = null;
        if (args != null) {
            if (savedInstanceState != null) {
                args.putAll(savedInstanceState);
            }
            account_id = args.getLong(INTENT_KEY_ACCOUNT_ID, -1);
            user_id = args.getLong(INTENT_KEY_USER_ID, -1);
            screen_name = args.getString(INTENT_KEY_SCREEN_NAME);
        }
        mProfileImageLoader = getApplication().getProfileImageLoader();
        mAdapter = new ListActionAdapter(getActivity());
        mProfileImageContainer.setOnClickListener(this);
        mNameContainer.setOnClickListener(this);
        mEditFollowButton.setOnClickListener(this);
        mTweetsContainer.setOnClickListener(this);
        mFollowersContainer.setOnClickListener(this);
        mFriendsContainer.setOnClickListener(this);
        mRetryButton.setOnClickListener(this);
        mMoreOptionsButton.setOnClickListener(this);
        mProfileNameBannerContainer.setOnSizeChangedListener(this);
        setListAdapter(null);
        mListView = getListView();
        mListView.addHeaderView(mHeaderView, null, false);
        mListView.setOnItemClickListener(this);
        mListView.setOnItemLongClickListener(this);
        setListAdapter(mAdapter);
        getUserInfo(account_id, user_id, screen_name, false);

    }

    @Override
    public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
        if (intent == null)
            return;
        switch (requestCode) {
        case REQUEST_TAKE_PHOTO: {
            if (resultCode == Activity.RESULT_OK) {
                final String path = mImageUri.getPath();
                final File file = path != null ? new File(path) : null;
                if (file != null && file.exists()) {
                    mTwitterWrapper.updateProfileImage(mUser.user_id, mImageUri, true);
                }
            }
            break;
        }
        case REQUEST_PICK_IMAGE: {
            if (resultCode == Activity.RESULT_OK && intent != null) {
                final Uri uri = intent.getData();
                final String image_path = getImagePathFromUri(getActivity(), uri);
                final File file = image_path != null ? new File(image_path) : null;
                if (file != null && file.exists()) {
                    mTwitterWrapper.updateProfileImage(mUser.user_id, Uri.fromFile(file), false);
                }
            }
            break;
        }
        case REQUEST_SET_COLOR: {
            if (resultCode == Activity.RESULT_OK && intent != null) {
                final int color = intent.getIntExtra(Accounts.USER_COLOR, Color.TRANSPARENT);
                setUserColor(getActivity(), mUserId, color);
                mProfileNameContainer.drawLeft(getUserColor(getActivity(), mUserId));
            }
            break;
        }
        }

    }

    @Override
    public void onClick(final View view) {
        if (getActivity() == null)
            return;
        switch (view.getId()) {
        case R.id.edit_follow: {
            if (mUser == null || mAccountId <= 0)
                return;
            if (mAccountId == mUserId) {
                final Bundle bundle = getArguments();
                final Intent intent = new Intent(INTENT_ACTION_EDIT_USER_PROFILE);
                intent.setClass(getActivity(), EditUserProfileActivity.class);
                if (bundle != null) {
                    intent.putExtras(bundle);
                }
                startActivity(intent);
            } else {
                if (mUser.is_follow_request_sent)
                    return;
                if (mFriendship.isSourceFollowingTarget()) {
                    mPopupMenu = PopupMenu.getInstance(getActivity(), view);
                    mPopupMenu.inflate(R.menu.action_user_profile_follow);
                    mPopupMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {

                        @Override
                        public boolean onMenuItemClick(final MenuItem item) {
                            switch (item.getItemId()) {
                            case R.id.unfollow: {
                                mFollowProgress.setVisibility(View.VISIBLE);
                                mEditFollowButton.setVisibility(View.GONE);
                                mTwitterWrapper.destroyFriendship(mAccountId, mUser.user_id);
                                return true;
                            }
                            }
                            return false;
                        }
                    });
                    mPopupMenu.show();
                } else {
                    mFollowProgress.setVisibility(View.VISIBLE);
                    mEditFollowButton.setVisibility(View.GONE);
                    mTwitterWrapper.createFriendship(mAccountId, mUser.user_id);
                }
            }
            break;
        }
        case R.id.retry: {
            getUserInfo(true);
            break;
        }
        case R.id.profile_image_container: {
            final Uri uri = Uri.parse(getOriginalTwitterProfileImage(mUser.profile_image_url));
            openImage(getActivity(), uri, false);
            break;
        }
        case R.id.tweets_container: {
            if (mUser == null)
                return;
            openUserTimeline(getActivity(), mAccountId, mUser.user_id, mUser.screen_name);
            break;
        }
        case R.id.followers_container: {
            if (mUser == null)
                return;
            openUserFollowers(getActivity(), mAccountId, mUser.user_id, mUser.screen_name);
            break;
        }
        case R.id.friends_container: {
            if (mUser == null)
                return;
            openUserFriends(getActivity(), mAccountId, mUser.user_id, mUser.screen_name);
            break;
        }
        case R.id.more_options: {
            if (mUser == null)
                return;
            mPopupMenu = PopupMenu.getInstance(getActivity(), view);
            mPopupMenu.inflate(R.menu.action_user_profile);
            final Menu menu = mPopupMenu.getMenu();
            if (mUser.user_id != mAccountId) {
                if (mFriendship == null)
                    return;
                final MenuItem blockItem = menu.findItem(MENU_BLOCK);
                if (blockItem != null) {
                    final Drawable blockIcon = blockItem.getIcon();
                    if (mFriendship.isSourceBlockingTarget()) {
                        blockItem.setTitle(R.string.unblock);
                        blockIcon.mutate().setColorFilter(getResources().getColor(R.color.holo_blue_bright),
                                PorterDuff.Mode.MULTIPLY);
                    } else {
                        blockItem.setTitle(R.string.block);
                        blockIcon.clearColorFilter();
                    }
                }
                final MenuItem sendDirectMessageItem = menu.findItem(MENU_SEND_DIRECT_MESSAGE);
                if (sendDirectMessageItem != null) {
                    sendDirectMessageItem.setVisible(mFriendship.isTargetFollowingSource());
                }
            } else {
                final int size = menu.size();
                for (int i = 0; i < size; i++) {
                    final MenuItem item = menu.getItem(i);
                    final int id = item.getItemId();
                    item.setVisible(id == R.id.set_color_submenu || id == MENU_EXTENSIONS_SUBMENU);
                }
            }
            final MenuItem extensions = menu.findItem(MENU_EXTENSIONS_SUBMENU);
            if (extensions != null) {
                final Intent intent = new Intent(INTENT_ACTION_EXTENSION_OPEN_USER);
                final Bundle extras = new Bundle();
                extras.putParcelable(INTENT_KEY_USER, mUser);
                intent.putExtras(extras);
                addIntentToSubMenu(getActivity(), extensions.getSubMenu(), intent);
            }
            mPopupMenu.setOnMenuItemClickListener(this);
            mPopupMenu.show();
            break;
        }
        case R.id.name_container: {
            if (mUser == null || mAccountId != mUserId)
                return;
            startActivity(new Intent(getActivity(), EditUserProfileActivity.class));
            break;
        }
        }

    }

    @Override
    public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
            final Bundle savedInstanceState) {
        mHeaderView = inflater.inflate(R.layout.user_profile_header, null, false);
        mNameContainer = mHeaderView.findViewById(R.id.name_container);
        mNameView = (TextView) mHeaderView.findViewById(R.id.name);
        mScreenNameView = (TextView) mHeaderView.findViewById(R.id.screen_name);
        mDescriptionView = (TextView) mHeaderView.findViewById(R.id.description);
        mLocationView = (TextView) mHeaderView.findViewById(R.id.location);
        mURLView = (TextView) mHeaderView.findViewById(R.id.url);
        mCreatedAtView = (TextView) mHeaderView.findViewById(R.id.created_at);
        mTweetsContainer = mHeaderView.findViewById(R.id.tweets_container);
        mTweetCount = (TextView) mHeaderView.findViewById(R.id.tweet_count);
        mFollowersContainer = mHeaderView.findViewById(R.id.followers_container);
        mFollowersCount = (TextView) mHeaderView.findViewById(R.id.followers_count);
        mFriendsContainer = mHeaderView.findViewById(R.id.friends_container);
        mFriendsCount = (TextView) mHeaderView.findViewById(R.id.friends_count);
        mProfileNameContainer = (ColorLabelRelativeLayout) mHeaderView.findViewById(R.id.profile_name_container);
        mProfileImageView = (ImageView) mHeaderView.findViewById(R.id.profile_image);
        mProfileImageContainer = mHeaderView.findViewById(R.id.profile_image_container);
        mDescriptionContainer = mHeaderView.findViewById(R.id.description_container);
        mLocationContainer = mHeaderView.findViewById(R.id.location_container);
        mURLContainer = mHeaderView.findViewById(R.id.url_container);
        mEditFollowContainer = mHeaderView.findViewById(R.id.edit_follow_container);
        mEditFollowButton = (Button) mHeaderView.findViewById(R.id.edit_follow);
        mFollowProgress = (ProgressBar) mHeaderView.findViewById(R.id.follow_progress);
        mMoreOptionsContainer = mHeaderView.findViewById(R.id.more_options_container);
        mMoreOptionsButton = (Button) mHeaderView.findViewById(R.id.more_options);
        mMoreOptionsProgress = (ProgressBar) mHeaderView.findViewById(R.id.more_options_progress);
        mFollowingYouIndicator = (TextView) mHeaderView.findViewById(R.id.following_you_indicator);
        mProfileNameBannerContainer = (ProfileNameBannerContainer) mHeaderView
                .findViewById(R.id.profile_name_banner_container);
        mListContainer = super.onCreateView(inflater, container, savedInstanceState);
        final View container_view = inflater.inflate(R.layout.list_with_error_message, null);
        ((FrameLayout) container_view.findViewById(R.id.list_container)).addView(mListContainer);
        mErrorRetryContainer = container_view.findViewById(R.id.error_retry_container);
        mRetryButton = (Button) container_view.findViewById(R.id.retry);
        mErrorMessageView = (TextView) container_view.findViewById(R.id.error_message);
        return container_view;
    }

    @Override
    public void onDestroyView() {
        mUser = null;
        mFriendship = null;
        mAccountId = -1;
        mUserId = -1;
        mScreenName = null;
        final LoaderManager lm = getLoaderManager();
        lm.destroyLoader(LOADER_ID_USER);
        lm.destroyLoader(LOADER_ID_FRIENDSHIP);
        lm.destroyLoader(LOADER_ID_BANNER);
        super.onDestroyView();
    }

    @Override
    public void onItemClick(final AdapterView<?> adapter, final View view, final int position, final long id) {
        final ListAction action = mAdapter.findItem(id);
        if (action != null) {
            action.onClick();
        }
    }

    @Override
    public boolean onItemLongClick(final AdapterView<?> adapter, final View view, final int position,
            final long id) {
        final ListAction action = mAdapter.findItem(id);
        if (action != null)
            return action.onLongClick();
        return false;
    }

    @Override
    public void onLinkClick(final String link, final int type) {
        if (mUser == null)
            return;
        switch (type) {
        case TwidereLinkify.LINK_TYPE_MENTION_LIST: {
            openUserProfile(getActivity(), mAccountId, -1, link);
            break;
        }
        case TwidereLinkify.LINK_TYPE_HASHTAG: {
            openTweetSearch(getActivity(), mAccountId, link);
            break;
        }
        case TwidereLinkify.LINK_TYPE_LINK_WITH_IMAGE_EXTENSION: {
            openImage(getActivity(), Uri.parse(link), false);
            break;
        }
        case TwidereLinkify.LINK_TYPE_LINK: {
            final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
            startActivity(intent);
            break;
        }
        case TwidereLinkify.LINK_TYPE_LIST: {
            final String[] mention_list = link.split("\\/");
            if (mention_list == null || mention_list.length != 2) {
                break;
            }
            break;
        }
        }
    }

    @Override
    public boolean onMenuItemClick(final MenuItem item) {
        if (mUser == null || mTwitterWrapper == null)
            return false;
        switch (item.getItemId()) {
        case MENU_TAKE_PHOTO: {
            takePhoto();
            break;
        }
        case MENU_ADD_IMAGE: {
            pickImage();
            break;
        }
        case MENU_BLOCK: {
            if (mTwitterWrapper == null || mFriendship == null) {
                break;
            }
            if (mFriendship.isSourceBlockingTarget()) {
                mTwitterWrapper.destroyBlock(mAccountId, mUser.user_id);
            } else {
                mTwitterWrapper.createBlockAsync(mAccountId, mUser.user_id);
            }
            break;
        }
        case MENU_REPORT_SPAM: {
            mTwitterWrapper.reportSpam(mAccountId, mUser.user_id);
            break;
        }
        case MENU_MUTE_USER: {
            final String screen_name = mUser.screen_name;
            final Uri uri = Filters.Users.CONTENT_URI;
            final ContentValues values = new ContentValues();
            final ContentResolver resolver = getContentResolver();
            values.put(Filters.Users.TEXT, screen_name);
            resolver.delete(uri, Filters.Users.TEXT + " = '" + screen_name + "'", null);
            resolver.insert(uri, values);
            Toast.makeText(getActivity(), R.string.user_muted, Toast.LENGTH_SHORT).show();
            break;
        }
        case MENU_MENTION: {
            final Intent intent = new Intent(INTENT_ACTION_COMPOSE);
            final Bundle bundle = new Bundle();
            final String name = mUser.name;
            final String screen_name = mUser.screen_name;
            bundle.putLong(INTENT_KEY_ACCOUNT_ID, mAccountId);
            bundle.putString(INTENT_KEY_TEXT, "@" + screen_name + " ");
            bundle.putString(INTENT_KEY_IN_REPLY_TO_SCREEN_NAME, screen_name);
            bundle.putString(INTENT_KEY_IN_REPLY_TO_NAME, name);
            intent.putExtras(bundle);
            startActivity(intent);
            break;
        }
        case MENU_SEND_DIRECT_MESSAGE: {
            final Uri.Builder builder = new Uri.Builder();
            builder.scheme(SCHEME_TWIDERE);
            builder.authority(AUTHORITY_DIRECT_MESSAGES_CONVERSATION);
            builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(mAccountId));
            builder.appendQueryParameter(QUERY_PARAM_CONVERSATION_ID, String.valueOf(mUser.user_id));
            startActivity(new Intent(Intent.ACTION_VIEW, builder.build()));
            break;
        }
        case MENU_SET_COLOR: {
            final Intent intent = new Intent(getActivity(), SetColorActivity.class);
            startActivityForResult(intent, REQUEST_SET_COLOR);
            break;
        }
        case MENU_CLEAR_COLOR: {
            clearUserColor(getActivity(), mUserId);
            mProfileNameContainer.drawLeft(getUserColor(getActivity(), mUserId));
            break;
        }
        default: {
            if (item.getIntent() != null) {
                try {
                    startActivity(item.getIntent());
                } catch (final ActivityNotFoundException e) {
                    Log.w(LOGTAG, e);
                    return false;
                }
            }
            break;
        }
        }
        return true;
    }

    @Override
    public void onSaveInstanceState(final Bundle outState) {
        outState.putLong(INTENT_KEY_ACCOUNT_ID, mAccountId);
        outState.putLong(INTENT_KEY_USER_ID, mUserId);
        outState.putString(INTENT_KEY_SCREEN_NAME, mScreenName);
        outState.putParcelable(INTENT_KEY_USER, mUser);
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onSizeChanged(final View view, final int w, final int h, final int oldw, final int oldh) {
        mBannerWidth = w;
    }

    @Override
    public void onStart() {
        super.onStart();
        final IntentFilter filter = new IntentFilter(BROADCAST_FRIENDSHIP_CHANGED);
        filter.addAction(BROADCAST_BLOCKSTATE_CHANGED);
        filter.addAction(BROADCAST_PROFILE_UPDATED);
        filter.addAction(BROADCAST_PROFILE_IMAGE_UPDATED);
        filter.addAction(BROADCAST_PROFILE_BANNER_UPDATED);
        registerReceiver(mStatusReceiver, filter);
        mProfileNameContainer.drawLeft(getUserColor(getActivity(), mUserId));
    }

    @Override
    public void onStop() {
        unregisterReceiver(mStatusReceiver);
        super.onStop();
    }

    private void getBannerImage() {
        final LoaderManager lm = getLoaderManager();
        lm.destroyLoader(LOADER_ID_BANNER);
        if (mBannerImageLoaderInitialized) {
            lm.restartLoader(LOADER_ID_BANNER, null, mBannerImageCallback);
        } else {
            lm.initLoader(LOADER_ID_BANNER, null, mBannerImageCallback);
            mBannerImageLoaderInitialized = true;
        }
    }

    private void getFriendship() {
        final LoaderManager lm = getLoaderManager();
        lm.destroyLoader(LOADER_ID_FRIENDSHIP);
        if (!mGetFriendShipLoaderInitialized) {
            lm.initLoader(LOADER_ID_FRIENDSHIP, null, mFriendshipLoaderCallbacks);
            mGetFriendShipLoaderInitialized = true;
        } else {
            lm.restartLoader(LOADER_ID_FRIENDSHIP, null, mFriendshipLoaderCallbacks);
        }
    }

    private void getUserInfo(final boolean omit_intent_extra) {
        getUserInfo(mAccountId, mUserId, mScreenName, omit_intent_extra);
    }

    private void pickImage() {
        final Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(i, REQUEST_PICK_IMAGE);
    }

    private void takePhoto() {
        if (getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            final File cache_dir = Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO
                    ? EnvironmentAccessor.getExternalCacheDir(getActivity())
                    : new File(getExternalStorageDirectory().getPath() + "/Android/data/"
                            + getActivity().getPackageName() + "/cache/");
            final File file = new File(cache_dir, "tmp_photo_" + System.currentTimeMillis() + ".jpg");
            mImageUri = Uri.fromFile(file);
            final Intent intent = createTakePhotoIntent(mImageUri);
            startActivityForResult(intent, REQUEST_TAKE_PHOTO);
        }
    }

    final class FavoritesAction extends ListAction {

        public FavoritesAction(final int order) {
            super(order);
        }

        @Override
        public String getName() {
            return getString(R.string.favorites);
        }

        @Override
        public String getSummary() {
            if (mUser == null)
                return null;
            return String.valueOf(mUser.favorites_count);
        }

        @Override
        public void onClick() {
            if (mUser == null)
                return;
            openUserFavorites(getActivity(), mAccountId, mUser.user_id, mUser.screen_name);
        }

    }

    static class FriendshipLoader extends AsyncTaskLoader<SingleResponse<Relationship>> {

        private final Context context;
        private final long account_id, user_id;

        public FriendshipLoader(final Context context, final long account_id, final long user_id) {
            super(context);
            this.context = context;
            this.account_id = account_id;
            this.user_id = user_id;
        }

        @Override
        public SingleResponse<Relationship> loadInBackground() {
            return getFriendship();
        }

        @Override
        protected void onStartLoading() {
            forceLoad();
        }

        private SingleResponse<Relationship> getFriendship() {
            if (account_id == user_id)
                return new SingleResponse<Relationship>(null, null);
            final Twitter twitter = getTwitterInstance(context, account_id, false);
            if (twitter == null)
                return new SingleResponse<Relationship>(null, null);
            try {
                final Relationship result = twitter.showFriendship(account_id, user_id);
                return new SingleResponse<Relationship>(result, null);
            } catch (final TwitterException e) {
                return new SingleResponse<Relationship>(null, e);
            }
        }
    }

    final class IncomingFriendshipsAction extends ListAction {

        public IncomingFriendshipsAction(final int order) {
            super(order);
        }

        @Override
        public String getName() {
            return getString(R.string.incoming_friendships);
        }

        @Override
        public void onClick() {
            if (mUser == null)
                return;
            openIncomingFriendships(getActivity(), mAccountId);
        }

    }

    final class SavedSearchesAction extends ListAction {

        public SavedSearchesAction(final int order) {
            super(order);
        }

        @Override
        public String getName() {
            return getString(R.string.saved_searches);
        }

        @Override
        public void onClick() {
            if (mUser == null)
                return;
            openSavedSearches(getActivity(), mAccountId);
        }

    }

    final class UserBlocksAction extends ListAction {

        public UserBlocksAction(final int order) {
            super(order);
        }

        @Override
        public String getName() {
            return getString(R.string.blocked_users);
        }

        @Override
        public void onClick() {
            if (mUser == null)
                return;
            openUserBlocks(getActivity(), mAccountId);
        }

    }

    final class UserListsAction extends ListAction {

        public UserListsAction(final int order) {
            super(order);
        }

        @Override
        public String getName() {
            return getString(R.string.user_list);
        }

        @Override
        public void onClick() {
            if (mUser == null)
                return;
            openUserLists(getActivity(), mAccountId, mUser.user_id, mUser.screen_name);
        }

    }

    final class UserMentionsAction extends ListAction {

        public UserMentionsAction(final int order) {
            super(order);
        }

        @Override
        public String getName() {
            return getString(R.string.user_mentions);
        }

        @Override
        public void onClick() {
            if (mUser == null)
                return;
            openUserMentions(getActivity(), mAccountId, mUser.screen_name);
        }

    }

}