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

Java tutorial

Introduction

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

Source

/*
 *             Twidere - Twitter client for Android
 * 
 *  Copyright (C) 2012-2014 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 android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;

import com.rengwuxian.materialedittext.MaterialEditText;
import com.twitter.Validator;

import org.mariotaku.abstask.library.AbstractTask;
import org.mariotaku.abstask.library.TaskStarter;
import org.mariotaku.microblog.library.MicroBlog;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.model.ProfileUpdate;
import org.mariotaku.microblog.library.twitter.model.User;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.ColorPickerDialogActivity;
import org.mariotaku.twidere.activity.ThemedImagePickerActivity;
import org.mariotaku.twidere.fragment.iface.IBaseFragment;
import org.mariotaku.twidere.loader.ParcelableUserLoader;
import org.mariotaku.twidere.model.ParcelableAccount;
import org.mariotaku.twidere.model.ParcelableCredentials;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.model.SingleResponse;
import org.mariotaku.twidere.model.UserKey;
import org.mariotaku.twidere.model.util.ParcelableCredentialsUtils;
import org.mariotaku.twidere.model.util.ParcelableUserUtils;
import org.mariotaku.twidere.task.UpdateAccountInfoTask;
import org.mariotaku.twidere.task.UpdateProfileBackgroundImageTask;
import org.mariotaku.twidere.task.UpdateProfileBannerImageTask;
import org.mariotaku.twidere.util.AsyncTwitterWrapper.UpdateProfileImageTask;
import org.mariotaku.twidere.util.HtmlEscapeHelper;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
import org.mariotaku.twidere.util.MicroBlogAPIFactory;
import org.mariotaku.twidere.util.ParseUtils;
import org.mariotaku.twidere.util.TwitterValidatorMETLengthChecker;
import org.mariotaku.twidere.util.TwitterWrapper;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.ForegroundColorView;
import org.mariotaku.twidere.view.iface.IExtendedView.OnSizeChangedListener;

import static android.text.TextUtils.isEmpty;

public class UserProfileEditorFragment extends BaseSupportFragment
        implements OnSizeChangedListener, TextWatcher, OnClickListener,
        LoaderCallbacks<SingleResponse<ParcelableUser>>, KeyboardShortcutsHandler.TakeAllKeyboardShortcut {

    private static final int LOADER_ID_USER = 1;

    private static final int REQUEST_UPLOAD_PROFILE_IMAGE = 1;
    private static final int REQUEST_UPLOAD_PROFILE_BANNER_IMAGE = 2;
    private static final int REQUEST_UPLOAD_PROFILE_BACKGROUND_IMAGE = 3;
    private static final int REQUEST_PICK_LINK_COLOR = 11;
    private static final int REQUEST_PICK_BACKGROUND_COLOR = 12;

    private static final int RESULT_REMOVE_BANNER = 101;
    private static final String UPDATE_PROFILE_DIALOG_FRAGMENT_TAG = "update_profile";

    private AbstractTask<?, ?, UserProfileEditorFragment> mTask;
    private ImageView mProfileImageView;
    private ImageView mProfileBannerView;
    private ImageView mProfileBackgroundView;
    private MaterialEditText mEditName;
    private MaterialEditText mEditDescription;
    private MaterialEditText mEditLocation;
    private MaterialEditText mEditUrl;
    private View mProgressContainer, mEditProfileContent;
    private View mEditProfileImage;
    private View mEditProfileBanner;
    private View mEditProfileBackground;
    private View mSetLinkColor, mSetBackgroundColor;
    private ForegroundColorView mLinkColor, mBackgroundColor;
    private UserKey mAccountId;
    private ParcelableUser mUser;
    private boolean mUserInfoLoaderInitialized;
    private boolean mGetUserInfoCalled;

    @Override
    public void beforeTextChanged(final CharSequence s, final int length, final int start, final int end) {
    }

    @Override
    public void onTextChanged(final CharSequence s, final int length, final int start, final int end) {
        updateDoneButton();
    }

    @Override
    public void afterTextChanged(final Editable s) {
    }

    @Override
    public void onClick(final View view) {
        final ParcelableUser user = mUser;
        if (user == null || (mTask != null && !mTask.isFinished()))
            return;
        switch (view.getId()) {
        case R.id.profile_image: {
            break;
        }
        case R.id.profile_banner: {
            break;
        }
        case R.id.edit_profile_image: {
            final Intent intent = ThemedImagePickerActivity.withThemed(getActivity()).aspectRatio(1, 1)
                    .maximumSize(512, 512).build();
            startActivityForResult(intent, REQUEST_UPLOAD_PROFILE_IMAGE);
            break;
        }
        case R.id.edit_profile_banner: {
            final Intent intent = ThemedImagePickerActivity.withThemed(getActivity()).aspectRatio(3, 1)
                    .maximumSize(1500, 500)
                    .addEntry(getString(R.string.remove), "remove_banner", RESULT_REMOVE_BANNER).build();
            startActivityForResult(intent, REQUEST_UPLOAD_PROFILE_BANNER_IMAGE);
            break;
        }
        case R.id.edit_profile_background: {
            final Intent intent = ThemedImagePickerActivity.withThemed(getActivity()).build();
            startActivityForResult(intent, REQUEST_UPLOAD_PROFILE_BACKGROUND_IMAGE);
            break;
        }
        case R.id.set_link_color: {
            final Intent intent = new Intent(getActivity(), ColorPickerDialogActivity.class);
            intent.putExtra(EXTRA_COLOR, user.link_color);
            intent.putExtra(EXTRA_ALPHA_SLIDER, false);
            startActivityForResult(intent, REQUEST_PICK_LINK_COLOR);
            break;
        }
        case R.id.set_background_color: {
            final Intent intent = new Intent(getActivity(), ColorPickerDialogActivity.class);
            intent.putExtra(EXTRA_COLOR, user.background_color);
            intent.putExtra(EXTRA_ALPHA_SLIDER, false);
            startActivityForResult(intent, REQUEST_PICK_BACKGROUND_COLOR);
            break;
        }
        }
    }

    @Override
    public Loader<SingleResponse<ParcelableUser>> onCreateLoader(final int id, final Bundle args) {
        mProgressContainer.setVisibility(View.VISIBLE);
        mEditProfileContent.setVisibility(View.GONE);
        return new ParcelableUserLoader(getActivity(), mAccountId, mAccountId, null, getArguments(), false, false);
    }

    @Override
    public void onLoadFinished(final Loader<SingleResponse<ParcelableUser>> loader,
            final SingleResponse<ParcelableUser> data) {
        if (data.getData() != null && data.getData().key != null) {
            displayUser(data.getData());
        } else if (mUser == null) {
        }
    }

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

    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu_profile_editor, menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.save: {
            final String name = ParseUtils.parseString(mEditName.getText());
            final String url = ParseUtils.parseString(mEditUrl.getText());
            final String location = ParseUtils.parseString(mEditLocation.getText());
            final String description = ParseUtils.parseString(mEditDescription.getText());
            final int linkColor = mLinkColor.getColor();
            final int backgroundColor = mBackgroundColor.getColor();
            mTask = new UpdateProfileTaskInternal(this, mAccountId, mUser, name, url, location, description,
                    linkColor, backgroundColor);
            TaskStarter.execute(mTask);
            return true;
        }
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onActivityCreated(final Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setHasOptionsMenu(true);
        final Bundle args = getArguments();
        final UserKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY);
        mAccountId = accountKey;
        if (!Utils.isMyAccount(getActivity(), accountKey)) {
            getActivity().finish();
            return;
        }

        final TwitterValidatorMETLengthChecker lengthChecker = new TwitterValidatorMETLengthChecker(
                new Validator());
        mEditName.addTextChangedListener(this);
        mEditDescription.addTextChangedListener(this);
        mEditLocation.addTextChangedListener(this);
        mEditUrl.addTextChangedListener(this);

        mEditDescription.setLengthChecker(lengthChecker);

        mProfileImageView.setOnClickListener(this);
        mProfileBannerView.setOnClickListener(this);
        mProfileBackgroundView.setOnClickListener(this);

        mEditProfileImage.setOnClickListener(this);
        mEditProfileBanner.setOnClickListener(this);
        mEditProfileBackground.setOnClickListener(this);

        mSetLinkColor.setOnClickListener(this);
        mSetBackgroundColor.setOnClickListener(this);

        if (savedInstanceState != null && savedInstanceState.getParcelable(EXTRA_USER) != null) {
            final ParcelableUser user = savedInstanceState.getParcelable(EXTRA_USER);
            assert user != null;
            displayUser(user);
            mEditName.setText(savedInstanceState.getString(EXTRA_NAME, user.name));
            mEditLocation.setText(savedInstanceState.getString(EXTRA_LOCATION, user.location));
            mEditDescription.setText(savedInstanceState.getString(EXTRA_DESCRIPTION,
                    ParcelableUserUtils.getExpandedDescription(user)));
            mEditUrl.setText(savedInstanceState.getString(EXTRA_URL, user.url_expanded));
        } else {
            getUserInfo();
        }
    }

    @Override
    public void onSaveInstanceState(final Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable(EXTRA_USER, mUser);
        outState.putString(EXTRA_NAME, ParseUtils.parseString(mEditName.getText()));
        outState.putString(EXTRA_DESCRIPTION, ParseUtils.parseString(mEditDescription.getText()));
        outState.putString(EXTRA_LOCATION, ParseUtils.parseString(mEditLocation.getText()));
        outState.putString(EXTRA_URL, ParseUtils.parseString(mEditUrl.getText()));
    }

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

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_user_profile_editor, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mProgressContainer = view.findViewById(R.id.progress_container);
        mEditProfileContent = view.findViewById(R.id.edit_profile_content);
        mProfileImageView = (ImageView) view.findViewById(R.id.profile_image);
        mProfileBannerView = (ImageView) view.findViewById(R.id.profile_banner);
        mProfileBackgroundView = (ImageView) view.findViewById(R.id.profile_background);
        mEditName = (MaterialEditText) view.findViewById(R.id.name);
        mEditDescription = (MaterialEditText) view.findViewById(R.id.description);
        mEditLocation = (MaterialEditText) view.findViewById(R.id.location);
        mEditUrl = (MaterialEditText) view.findViewById(R.id.url);
        mEditProfileImage = view.findViewById(R.id.edit_profile_image);
        mEditProfileBanner = view.findViewById(R.id.edit_profile_banner);
        mEditProfileBackground = view.findViewById(R.id.edit_profile_background);
        mLinkColor = (ForegroundColorView) view.findViewById(R.id.link_color);
        mBackgroundColor = (ForegroundColorView) view.findViewById(R.id.background_color);
        mSetLinkColor = view.findViewById(R.id.set_link_color);
        mSetBackgroundColor = view.findViewById(R.id.set_background_color);
    }

    @Override
    public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        if (resultCode == FragmentActivity.RESULT_CANCELED)
            return;
        switch (requestCode) {
        case REQUEST_UPLOAD_PROFILE_BANNER_IMAGE: {
            if (mTask != null && !mTask.isFinished())
                return;
            if (resultCode == RESULT_REMOVE_BANNER) {
                mTask = new RemoveProfileBannerTaskInternal(mAccountId);
            } else {
                mTask = new UpdateProfileBannerImageTaskInternal(getActivity(), mAccountId, data.getData(), true);
            }
            break;
        }
        case REQUEST_UPLOAD_PROFILE_BACKGROUND_IMAGE: {
            //TODO upload profile background
            if (mTask != null && !mTask.isFinished())
                return;
            mTask = new UpdateProfileBackgroundImageTaskInternal(getActivity(), mAccountId, data.getData(), false,
                    true);
            break;
        }
        case REQUEST_UPLOAD_PROFILE_IMAGE: {
            if (mTask != null && !mTask.isFinished())
                return;
            mTask = new UpdateProfileImageTaskInternal(getActivity(), mAccountId, data.getData(), true);
            break;
        }
        case REQUEST_PICK_LINK_COLOR: {
            if (resultCode == ColorPickerDialogActivity.RESULT_OK) {
                mLinkColor.setColor(data.getIntExtra(EXTRA_COLOR, 0));
                updateDoneButton();
            }
            break;
        }
        case REQUEST_PICK_BACKGROUND_COLOR: {
            if (resultCode == ColorPickerDialogActivity.RESULT_OK) {
                mBackgroundColor.setColor(data.getIntExtra(EXTRA_COLOR, 0));
                updateDoneButton();
            }
            break;
        }
        }

    }

    private void displayUser(final ParcelableUser user) {
        if (!mGetUserInfoCalled)
            return;
        mGetUserInfoCalled = false;
        mUser = user;
        if (user != null) {
            mProgressContainer.setVisibility(View.GONE);
            mEditProfileContent.setVisibility(View.VISIBLE);
            mEditName.setText(user.name);
            mEditDescription.setText(ParcelableUserUtils.getExpandedDescription(user));
            mEditLocation.setText(user.location);
            mEditUrl.setText(isEmpty(user.url_expanded) ? user.url : user.url_expanded);
            mMediaLoader.displayProfileImage(mProfileImageView, user);
            final int defWidth = getResources().getDisplayMetrics().widthPixels;
            mMediaLoader.displayProfileBanner(mProfileBannerView, user.profile_banner_url, defWidth);
            mMediaLoader.displayImage(mProfileBackgroundView, user.profile_background_url);
            mLinkColor.setColor(user.link_color);
            mBackgroundColor.setColor(user.background_color);
            if (USER_TYPE_FANFOU_COM.equals(user.key.getHost())) {
                mEditProfileBanner.setVisibility(View.GONE);
            } else {
                mEditProfileBanner.setVisibility(View.VISIBLE);
            }
        } else {
            mProgressContainer.setVisibility(View.GONE);
            mEditProfileContent.setVisibility(View.GONE);
        }
        updateDoneButton();
    }

    private void getUserInfo() {
        if (getActivity() == null || isDetached())
            return;
        final LoaderManager lm = getLoaderManager();
        lm.destroyLoader(LOADER_ID_USER);
        mGetUserInfoCalled = true;
        if (mUserInfoLoaderInitialized) {
            lm.restartLoader(LOADER_ID_USER, null, this);
        } else {
            lm.initLoader(LOADER_ID_USER, null, this);
            mUserInfoLoaderInitialized = true;
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mTask != null && !mTask.isFinished()) {
            TaskStarter.execute(mTask);
        }
    }

    private void dismissDialogFragment(final String tag) {
        executeAfterFragmentResumed(new Action() {
            @Override
            public void execute(IBaseFragment fragment) {
                final FragmentManager fm = getChildFragmentManager();
                final Fragment f = fm.findFragmentByTag(tag);
                if (f instanceof DialogFragment) {
                    ((DialogFragment) f).dismiss();
                }
            }
        });
    }

    private void setUpdateState(final boolean start) {
        if (!start) {
            dismissDialogFragment(UPDATE_PROFILE_DIALOG_FRAGMENT_TAG);
            return;
        }
        executeAfterFragmentResumed(new Action() {
            @Override
            public void execute(IBaseFragment fragment) {
                final FragmentManager fm = getChildFragmentManager();
                ProgressDialogFragment df = new ProgressDialogFragment();
                df.show(fm, UPDATE_PROFILE_DIALOG_FRAGMENT_TAG);
                df.setCancelable(false);
            }
        });
    }

    private static boolean stringEquals(final CharSequence str1, final CharSequence str2) {
        if (str1 == null || str2 == null)
            return str1 == str2;
        if (str1.length() != str2.length())
            return false;
        for (int i = 0, j = str1.length(); i < j; i++) {
            if (str1.charAt(i) != str2.charAt(i))
                return false;
        }
        return true;
    }

    private void updateDoneButton() {

    }

    static class UpdateProfileTaskInternal
            extends AbstractTask<Object, SingleResponse<ParcelableUser>, UserProfileEditorFragment> {

        private static final String DIALOG_FRAGMENT_TAG = "updating_user_profile";
        private final FragmentActivity mActivity;

        // Data fields
        private final UserKey mAccountKey;
        private final ParcelableUser mOriginal;
        private final String mName;
        private final String mUrl;
        private final String mLocation;
        private final String mDescription;
        private final int mLinkColor;
        private final int mBackgroundColor;

        public UpdateProfileTaskInternal(final UserProfileEditorFragment fragment, final UserKey accountKey,
                final ParcelableUser original, final String name, final String url, final String location,
                final String description, final int linkColor, final int backgroundColor) {
            mActivity = fragment.getActivity();
            mAccountKey = accountKey;
            mOriginal = original;
            mName = name;
            mUrl = url;
            mLocation = location;
            mDescription = description;
            mLinkColor = linkColor;
            mBackgroundColor = backgroundColor;
        }

        @Override
        protected SingleResponse<ParcelableUser> doLongOperation(final Object params) {
            final ParcelableCredentials credentials = ParcelableCredentialsUtils.getCredentials(mActivity,
                    mAccountKey);
            if (credentials == null)
                return SingleResponse.getInstance();
            final MicroBlog twitter = MicroBlogAPIFactory.getInstance(mActivity, credentials, true, true);
            if (twitter == null)
                return SingleResponse.getInstance();
            try {
                User user = null;
                if (isProfileChanged()) {
                    final ProfileUpdate profileUpdate = new ProfileUpdate();
                    profileUpdate.name(HtmlEscapeHelper.escapeBasic(mName));
                    profileUpdate.location(HtmlEscapeHelper.escapeBasic(mLocation));
                    profileUpdate.description(HtmlEscapeHelper.escapeBasic(mDescription));
                    profileUpdate.url(mUrl);
                    profileUpdate.linkColor(mLinkColor);
                    profileUpdate.backgroundColor(mBackgroundColor);
                    user = twitter.updateProfile(profileUpdate);
                }
                if (user == null) {
                    // User profile unchanged
                    return SingleResponse.getInstance();
                }
                final SingleResponse<ParcelableUser> response = SingleResponse
                        .getInstance(ParcelableUserUtils.fromUser(user, mAccountKey));
                response.getExtras().putParcelable(EXTRA_ACCOUNT, credentials);
                return response;
            } catch (MicroBlogException e) {
                return SingleResponse.getInstance(e);
            }
        }

        private boolean isProfileChanged() {
            final ParcelableUser orig = mOriginal;
            if (orig == null)
                return true;
            if (mLinkColor != orig.link_color)
                return true;
            if (mBackgroundColor != orig.background_color)
                return true;
            if (!stringEquals(mName, orig.name))
                return true;
            if (!stringEquals(mDescription, ParcelableUserUtils.getExpandedDescription(orig)))
                return true;
            if (!stringEquals(mLocation, orig.location))
                return true;
            if (!stringEquals(mUrl, isEmpty(orig.url_expanded) ? orig.url : orig.url_expanded))
                return true;
            return false;
        }

        @Override
        protected void afterExecute(UserProfileEditorFragment callback, SingleResponse<ParcelableUser> result) {
            super.afterExecute(callback, result);
            if (result.hasData()) {
                final ParcelableAccount account = result.getExtras().getParcelable(EXTRA_ACCOUNT);
                if (account != null) {
                    final UpdateAccountInfoTask task = new UpdateAccountInfoTask(mActivity);
                    task.setParams(Pair.create(account, result.getData()));
                    TaskStarter.execute(task);
                }
            }
            callback.executeAfterFragmentResumed(new Action() {
                @Override
                public void execute(IBaseFragment fragment) {
                    final Fragment f = ((UserProfileEditorFragment) fragment).getFragmentManager()
                            .findFragmentByTag(DIALOG_FRAGMENT_TAG);
                    if (f instanceof DialogFragment) {
                        ((DialogFragment) f).dismissAllowingStateLoss();
                    }
                    f.getActivity().finish();
                }
            });
        }

        @Override
        protected void beforeExecute() {
            super.beforeExecute();
            final UserProfileEditorFragment callback = getCallback();
            if (callback != null) {
                callback.executeAfterFragmentResumed(new Action() {
                    @Override
                    public void execute(IBaseFragment fragment) {
                        final DialogFragment df = ProgressDialogFragment
                                .show(((UserProfileEditorFragment) fragment).getActivity(), DIALOG_FRAGMENT_TAG);
                        df.setCancelable(false);
                    }
                });
            }
        }

    }

    class RemoveProfileBannerTaskInternal
            extends AbstractTask<Object, SingleResponse<Boolean>, UserProfileEditorFragment> {

        private final UserKey mAccountKey;

        RemoveProfileBannerTaskInternal(final UserKey accountKey) {
            this.mAccountKey = accountKey;
        }

        @Override
        protected SingleResponse<Boolean> doLongOperation(final Object params) {
            return TwitterWrapper.deleteProfileBannerImage(getActivity(), mAccountKey);
        }

        @Override
        protected void afterExecute(UserProfileEditorFragment callback, final SingleResponse<Boolean> result) {
            super.afterExecute(callback, result);
            if (result.getData() != null && result.getData()) {
                getUserInfo();
                Toast.makeText(getActivity(), R.string.profile_banner_image_updated, Toast.LENGTH_SHORT).show();
            } else {
                Utils.showErrorMessage(getActivity(), R.string.action_removing_profile_banner_image,
                        result.getException(), true);
            }
            setUpdateState(false);
        }

        @Override
        protected void beforeExecute() {
            super.beforeExecute();
            setUpdateState(true);
        }

    }

    private class UpdateProfileBannerImageTaskInternal
            extends UpdateProfileBannerImageTask<UserProfileEditorFragment> {

        public UpdateProfileBannerImageTaskInternal(final Context context, final UserKey accountKey,
                final Uri imageUri, final boolean deleteImage) {
            super(context, accountKey, imageUri, deleteImage);
        }

        @Override
        protected void afterExecute(UserProfileEditorFragment callback,
                final SingleResponse<ParcelableUser> result) {
            super.afterExecute(callback, result);
            setUpdateState(false);
            getUserInfo();
        }

        @Override
        protected void beforeExecute() {
            super.beforeExecute();
            setUpdateState(true);
        }

    }

    private class UpdateProfileBackgroundImageTaskInternal
            extends UpdateProfileBackgroundImageTask<UserProfileEditorFragment> {

        public UpdateProfileBackgroundImageTaskInternal(final Context context, final UserKey accountKey,
                final Uri imageUri, final boolean tile, final boolean deleteImage) {
            super(context, accountKey, imageUri, tile, deleteImage);
        }

        @Override
        protected void afterExecute(UserProfileEditorFragment callback,
                final SingleResponse<ParcelableUser> result) {
            super.afterExecute(callback, result);
            setUpdateState(false);
            getUserInfo();
        }

        @Override
        protected void beforeExecute() {
            super.beforeExecute();
            setUpdateState(true);
        }

    }

    private class UpdateProfileImageTaskInternal extends UpdateProfileImageTask<UserProfileEditorFragment> {

        public UpdateProfileImageTaskInternal(final Context context, final UserKey accountKey, final Uri imageUri,
                final boolean deleteImage) {
            super(context, accountKey, imageUri, deleteImage);
        }

        @Override
        protected void afterExecute(UserProfileEditorFragment callback, SingleResponse<ParcelableUser> result) {
            super.afterExecute(callback, result);
            if (result != null && result.getData() != null) {
                displayUser(result.getData());
            }
            setUpdateState(false);
        }

        @Override
        protected void beforeExecute() {
            super.beforeExecute();
            setUpdateState(true);
        }

    }
}