im.ene.lab.attiq.ui.activities.ProfileActivity.java Source code

Java tutorial

Introduction

Here is the source code for im.ene.lab.attiq.ui.activities.ProfileActivity.java

Source

/*
 * Copyright 2016 eneim@Eneim Labs, nam@ene.im
 *
 * 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 im.ene.lab.attiq.ui.activities;

import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.Toolbar;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import butterknife.Bind;
import butterknife.BindDimen;
import butterknife.ButterKnife;
import butterknife.OnClick;
import com.squareup.picasso.RequestCreator;
import de.greenrobot.event.EventBus;
import im.ene.lab.attiq.Attiq;
import im.ene.lab.attiq.R;
import im.ene.lab.attiq.data.api.ApiClient;
import im.ene.lab.attiq.data.api.DocumentCallback;
import im.ene.lab.attiq.data.model.local.RProfile;
import im.ene.lab.attiq.data.model.two.Profile;
import im.ene.lab.attiq.data.model.two.User;
import im.ene.lab.attiq.ui.fragment.DummyFragment;
import im.ene.lab.attiq.ui.fragment.UserItemsFragment;
import im.ene.lab.attiq.ui.fragment.UserStockedArticlesFragment;
import im.ene.lab.attiq.ui.fragment.UserTagsFragment;
import im.ene.lab.attiq.ui.widgets.NotBadImageButton;
import im.ene.lab.attiq.ui.widgets.RoundedTransformation;
import im.ene.lab.attiq.ui.widgets.UserInfoRowTextView;
import im.ene.lab.attiq.util.PrefUtil;
import im.ene.lab.attiq.util.UIUtil;
import im.ene.lab.attiq.util.WebUtil;
import im.ene.lab.attiq.util.event.DocumentEvent;
import im.ene.lab.attiq.util.event.Event;
import im.ene.lab.attiq.util.event.ProfileUpdatedEvent;
import im.ene.lab.attiq.util.event.UserFetchedEvent;
import im.ene.lab.support.widget.AlphaForegroundColorSpan;
import im.ene.lab.support.widget.AppBarLayout;
import im.ene.lab.support.widget.CollapsingToolbarLayout;
import im.ene.lab.support.widget.MathUtils;
import io.realm.Realm;
import io.realm.RealmChangeListener;
import java.util.Iterator;
import java.util.List;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class ProfileActivity extends BaseActivity implements RealmChangeListener {

    private static final int MESSAGE_ACTION_FOLLOW = 1;

    private static final int MESSAGE_DATA_UPDATE = 1 << 1;

    private static final String TAG = "ProfileActivity";
    // Used to keep track of index
    private static final int WEBSITE_BUTTON_INDEX = 0;
    private static final int FACEBOOK_BUTTON_INDEX = 1;
    private static final int TWITTER_BUTTON_INDEX = 2;
    private static final int GITHUB_BUTTON_INDEX = 3;
    private static final int LINKEDIN_BUTTON_INDEX = 4;

    private static final int HANDLER_DELAY = 200; // To prevent stress events

    @Bind(R.id.view_pager)
    ViewPager mViewPager;
    @Bind(R.id.app_bar)
    AppBarLayout mAppBarLayout;
    @Bind(R.id.toolbar_layout)
    CollapsingToolbarLayout mToolBarLayout;
    @Bind(R.id.toolbar_overlay)
    View mOverlayContainer;
    @Bind(R.id.toolbar)
    Toolbar mToolbar;
    @Bind(R.id.tab_layout)
    TabLayout mTabLayout;
    @Bind(R.id.profile_image)
    NotBadImageButton mProfileImage;
    @Bind(R.id.social_button_container)
    View mSocialButtonContainer;
    @Bind(R.id.profile_social_buttons)
    LinearLayout mSocialButtonView;
    @Bind(R.id.text_action_follow_container)
    View mBtnFollowContainer;
    @Bind(R.id.text_action_follow)
    TextView mBtnFollow;
    @Bind(R.id.profile_name)
    TextView mProfileName;
    @Bind(R.id.profile_description)
    TextView mProfileDescription;
    @Bind(R.id.description_container)
    LinearLayout mDescription;

    @Bind(R.id.user_item_count)
    TextView mItemCount;
    @Bind(R.id.user_item_count_quantity)
    TextView mItemQuantity;

    @Bind(R.id.user_follower_count)
    TextView mFollowerCount;
    @Bind(R.id.user_follower_count_quantity)
    TextView mFollowerQuantity;

    @Bind(R.id.user_following_count)
    TextView mFollowingCount;
    @Bind(R.id.user_following_count_quantity)
    TextView mFollowingQuantity;

    // Others
    // @BindDimen(R.dimen.item_icon_size_half) int mIconCornerRadius;
    @BindDimen(R.dimen.item_padding_half)
    int mImageBorderWidth;
    int mImageBorderColor;
    @BindDimen(R.dimen.profile_image_size)
    int mProfileImageSize;
    @BindDimen(R.dimen.item_padding)
    int mProfileImageRadius;
    @Bind({ R.id.profile_social_website, R.id.profile_social_facebook, R.id.profile_social_twitter,
            R.id.profile_social_github, R.id.profile_social_linkedin })
    ImageButton[] mSocialButtons;

    // private int mFollowTextPositive;
    // private int mFollowTextNegative;

    private ProfileViewPagerAdapter mPagerAdapter;
    // Title support
    private AlphaForegroundColorSpan mTitleColorSpan;
    private SpannableString mSpannableTitle;
    private SpannableString mSpannableSubtitle;
    private int mToolbarLayoutOffset;
    private AppBarLayout.OnOffsetChangedListener mOffsetChangedListener = new AppBarLayout.OnOffsetChangedListener() {
        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
            mToolbarLayoutOffset = verticalOffset;
            float maxOffset = mToolBarLayout.getHeight() - mToolBarLayout.getScrimOffsetBound();
            if (maxOffset > 0) {
                float offsetFraction = Math.abs(verticalOffset) / maxOffset;
                offsetFraction = MathUtils.constrain(offsetFraction, 0.f, 1.f);
                mOverlayContainer.setAlpha(1.f - offsetFraction);
                mProfileImage.setAlpha(1.f - Math.min(offsetFraction * 2.5f, 1.f));
                mProfileImage.setScaleX(1.f - offsetFraction);
                mProfileImage.setScaleY(1.f - offsetFraction);
            }
        }
    };
    private Realm mRealm;
    private RProfile mProfile;
    private Profile mRefUser;
    // private User mUser;
    // private State mState = new State();
    private String mUserId; // actually the User name
    private Callback<Void> mOnFollowStateCallback;
    private Callback<Void> mOnUnFollowStateCallback;
    private Callback<User> mOnUserCallback;
    private DocumentCallback mDocumentCallback;
    private Handler.Callback mHandlerCallback = new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            if (msg.what == MESSAGE_ACTION_FOLLOW) {
                if (!((State) mState).isFollowing) {
                    ((State) mState).isFollowing = true;
                    EventBus.getDefault()
                            .post(new StateEvent<>(ProfileActivity.class.getSimpleName(), true, null, mState));
                    ApiClient.followUser(mUserId).enqueue(mOnFollowStateCallback);
                } else {
                    ((State) mState).isFollowing = false;
                    EventBus.getDefault()
                            .post(new StateEvent<>(ProfileActivity.class.getSimpleName(), true, null, mState));
                    ApiClient.unFollowUser(mUserId).enqueue(mOnUnFollowStateCallback);
                }

                return true;
            } else if (msg.what == MESSAGE_DATA_UPDATE) {
                EventBus.getDefault()
                        .post(new ProfileUpdatedEvent(ProfileActivity.class.getSimpleName(), true, null, mProfile));
            }

            return false;
        }
    };
    private final Handler mHandler = new Handler(mHandlerCallback);

    public static Intent createIntent(Context context, String userName) {
        Intent intent = new Intent(context, ProfileActivity.class);
        Uri data = Uri.parse(context.getString(R.string.data_users_url, userName));
        intent.setData(data);
        return intent;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_profile);
        ButterKnife.bind(this);

        setSupportActionBar(mToolbar);

        if (getSupportActionBar() != null) {
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        }

        // empty title at start
        setTitle("");

        mAppBarLayout.addOnOffsetChangedListener(mOffsetChangedListener);
        TypedValue typedValue = new TypedValue();
        mToolbar.getContext().getTheme().resolveAttribute(android.R.attr.textColorPrimary, typedValue, true);
        int titleColorId = typedValue.resourceId;
        mTitleColorSpan = new AlphaForegroundColorSpan(ContextCompat.getColor(this, titleColorId));

        typedValue = new TypedValue();
        getTheme().resolveAttribute(R.attr.colorAccent, typedValue, true);
        int accentColorId = typedValue.resourceId;
        mImageBorderColor = ContextCompat.getColor(this, accentColorId);

        mRealm = Attiq.realm();
        mRealm.addChangeListener(this);

        Uri data = getIntent().getData();
        if (data != null) {
            List<String> paths = data.getPathSegments();
            if (!UIUtil.isEmpty(paths)) {
                Iterator<String> iterator = paths.iterator();
                while (iterator.hasNext()) {
                    if ("users".equals(iterator.next())) {
                        mUserId = iterator.next();
                        break;
                    }
                }
            }
        }

        mRefUser = mRealm.where(Profile.class).equalTo("token", PrefUtil.getCurrentToken()).findFirst();

        mProfile = mRealm.where(RProfile.class).equalTo(RProfile.FIELD_USER_NAME, mUserId).findFirst();
        if (mProfile == null) {
            mRealm.beginTransaction();
            mProfile = mRealm.createObject(RProfile.class);
            mProfile.setUserName(mUserId);
            mRealm.commitTransaction();
        }

        if (getSupportFragmentManager().findFragmentById(R.id.profile_info_tags) == null) {
            mTagFragment = UserTagsFragment.newInstance(mUserId);
            getSupportFragmentManager().beginTransaction().replace(R.id.profile_info_tags, mTagFragment).commit();
        }

        mPagerAdapter = new ProfileViewPagerAdapter(getSupportFragmentManager(), mUserId);
        mViewPager.setAdapter(mPagerAdapter);
        mViewPager.setOffscreenPageLimit(mPagerAdapter.getCount());
        mTabLayout.setupWithViewPager(mViewPager);

        // find a local user, if there is one, update current profile
        User user = mRealm.where(User.class).equalTo("id", mUserId).findFirst();
        if (user != null) {
            EventBus.getDefault().post(new UserFetchedEvent(getClass().getSimpleName(), true, null, user));
        }
    }

    @Override
    protected void onDestroy() {
        if (mRealm != null) {
            mRealm.removeChangeListener(this);
            mRealm.close();
        }
        ButterKnife.unbind(this);
        super.onDestroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
        // setup
        mOnFollowStateCallback = new Callback<Void>() {
            @Override
            public void onResponse(Call<Void> call, Response<Void> response) {
                ((State) mState).isFollowing = response != null && response.code() == 204;
                EventBus.getDefault()
                        .post(new StateEvent<>(ProfileActivity.class.getSimpleName(), true, null, mState));
            }

            @Override
            public void onFailure(Call<Void> call, Throwable t) {
                EventBus.getDefault().post(new StateEvent<>(ProfileActivity.class.getSimpleName(), false,
                        new Event.Error(Event.Error.ERROR_UNKNOWN, t.getLocalizedMessage()), null));
            }
        };

        mOnUnFollowStateCallback = new Callback<Void>() {
            @Override
            public void onResponse(Call<Void> call, Response<Void> response) {
                ((State) mState).isFollowing = response != null && !(response.code() == 204);
            }

            @Override
            public void onFailure(Call<Void> call, Throwable t) {
                EventBus.getDefault().post(new StateEvent<>(ProfileActivity.class.getSimpleName(), false,
                        new Event.Error(Event.Error.ERROR_UNKNOWN, t.getLocalizedMessage()), null));
            }
        };

        mOnUserCallback = new Callback<User>() {
            @Override
            public void onResponse(Call<User> call, Response<User> response) {
                User user = response.body();
                if (user != null) {
                    Realm realm = Attiq.realm();
                    realm.beginTransaction();
                    realm.copyToRealmOrUpdate(user);
                    realm.commitTransaction();
                    realm.close();
                    EventBus.getDefault()
                            .post(new UserFetchedEvent(ProfileActivity.class.getSimpleName(), true, null, user));
                } else {
                    EventBus.getDefault().post(new UserFetchedEvent(ProfileActivity.class.getSimpleName(), false,
                            new Event.Error(response.code(), response.message()), null));
                }
            }

            @Override
            public void onFailure(Call<User> call, Throwable error) {
                EventBus.getDefault().post(new UserFetchedEvent(ProfileActivity.class.getSimpleName(), false,
                        new Event.Error(Event.Error.ERROR_UNKNOWN, error.getLocalizedMessage()), null));
            }
        };

        final String baseUrl = "http://qiita.com/" + mUserId;

        mDocumentCallback = new DocumentCallback(baseUrl) {
            @Override
            public void onDocument(Document response) {
                if (response != null) {
                    EventBus.getDefault()
                            .post(new DocumentEvent(ProfileActivity.class.getSimpleName(), true, null, response));
                }
            }
        };

        WebUtil.loadWeb(baseUrl).enqueue(mDocumentCallback);

        // update UI
        if (mProfile != null) {
            EventBus.getDefault()
                    .post(new ProfileUpdatedEvent(ProfileActivity.class.getSimpleName(), true, null, mProfile));
        }

        ApiClient.isFollowing(mUserId).enqueue(mOnFollowStateCallback);
        ApiClient.user(mUserId).enqueue(mOnUserCallback);
    }

    @Override
    protected void onPause() {
        mOnUserCallback = null;
        mOnFollowStateCallback = null;
        mOnUnFollowStateCallback = null;
        mHandler.removeCallbacksAndMessages(null);
        mHandlerCallback = null;
        super.onPause();
    }

    @SuppressWarnings("unused")
    public void onEventMainThread(StateEvent<State> event) {
        mBtnFollow.setEnabled(mRefUser != null && !UIUtil.isEmpty(mRefUser.getToken()));
        mBtnFollow.setClickable(mRefUser != null && !UIUtil.isEmpty(mRefUser.getToken()));
        mBtnFollowContainer
                .setVisibility(mRefUser != null && mUserId.equals(mRefUser.getId()) ? View.GONE : View.VISIBLE);

        if (event.state != null) {
            mBtnFollow.setText(event.state.isFollowing ? R.string.state_following : R.string.state_not_following);

            mBtnFollow.setBackgroundResource(event.state.isFollowing ? R.drawable.rounded_background_active
                    : R.drawable.rounded_background_normal);

            mRealm.beginTransaction();
            mProfile.setContributionCount(event.state.contribution);
            mRealm.commitTransaction();
        }
    }

    @SuppressWarnings("unused")
    public void onEventMainThread(ProfileUpdatedEvent event) {
        mProfileName.setText(mProfile.getUserName());
        mProfileDescription.setText(mProfile.getBrief());

        final RequestCreator profileImageRequest;
        if (!UIUtil.isEmpty(mProfile.getProfileImageUrl())) {
            profileImageRequest = Attiq.picasso().load(mProfile.getProfileImageUrl());
        } else {
            profileImageRequest = Attiq.picasso().load(R.drawable.blank_profile_icon_large);
        }

        profileImageRequest.placeholder(R.drawable.blank_profile_icon_large)
                .error(R.drawable.blank_profile_icon_large).resize(mProfileImageSize, 0)
                .transform(new RoundedTransformation(0, mImageBorderColor, mProfileImageRadius))
                .into(mProfileImage);

        mSpannableTitle = new SpannableString(mUserId);
        if (!UIUtil.isEmpty(mProfile.getFullName())) {
            mSpannableSubtitle = new SpannableString(mProfile.getFullName());
        }

        updateTitle();
        updateDescription();
        updateQuantities();
        updateSocialButtons();
    }

    @SuppressWarnings("unused")
    public void onEventMainThread(UserFetchedEvent event) {
        Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
        if (event.user != null) {
            mRealm.beginTransaction();

            mProfile.setProfileImageUrl(event.user.getProfileImageUrl());

            StringBuilder description = new StringBuilder();

            boolean willBreakLine = false;
            boolean willSeparate = false;

            if (!UIUtil.isEmpty(event.user.getName())) {
                description.append(event.user.getName());
                willBreakLine = true;
            }

            if (!UIUtil.isEmpty(event.user.getLocation())) {
                if (willSeparate) {
                    description.append(", ");
                }

                if (willBreakLine) {
                    description.append(System.lineSeparator());
                }

                description.append(event.user.getLocation());
            }

            mProfile.setBrief(description.toString());

            mProfile.setDescription(event.user.getDescription());
            mProfile.setOrganization(event.user.getOrganization());

            mProfile.setItemCount(event.user.getItemsCount());
            mProfile.setFollowerCount(event.user.getFollowersCount());
            mProfile.setFollowingCount(event.user.getFolloweesCount());

            mProfile.setWebsite(event.user.getWebsiteUrl());
            mProfile.setFacebookName(event.user.getFacebookId());
            mProfile.setTwitterName(event.user.getTwitterScreenName());
            mProfile.setGithubName(event.user.getGithubLoginName());
            mProfile.setLinkedinName(event.user.getLinkedinId());

            mRealm.commitTransaction();
        }
    }

    private void updateDescription() {
        if (mProfile == null || mDescription == null) {
            return;
        }

        // mDescription.removeAllViews();
        final Context context = mDescription.getContext();

        if (mProfile.getContributionCount() != null) {
            TextView contribution = (TextView) mDescription.findViewById(R.id.profile_info_contribution);
            if (contribution == null) {
                contribution = (TextView) LayoutInflater.from(context).inflate(R.layout.widget_info_textview,
                        mDescription, false);
                contribution.setId(R.id.profile_info_contribution);
                mDescription.addView(contribution, 0);
            }

            contribution.setText(getResources().getQuantityString(R.plurals.user_contribution_quantity,
                    mProfile.getContributionCount(), mProfile.getContributionCount()));
        }

        if (!UIUtil.isEmpty(mProfile.getDescription())) {
            TextView description = (TextView) mDescription.findViewById(R.id.profile_info_description);
            if (description == null) {
                description = (TextView) LayoutInflater.from(context).inflate(R.layout.widget_info_textview,
                        mDescription, false);
                description.setId(R.id.profile_info_description);
                mDescription.addView(description);
            }
            description.setText(UIUtil.beautify(mProfile.getDescription()));
        }

        if (!UIUtil.isEmpty(mProfile.getOrganization())) {
            UserInfoRowTextView organization = (UserInfoRowTextView) mDescription
                    .findViewById(R.id.profile_info_organization);
            if (organization == null) {
                organization = new UserInfoRowTextView(mDescription.getContext());
                organization.setId(R.id.profile_info_organization);
                mDescription.addView(organization);
            }

            organization.setText(UIUtil.beautify(mProfile.getOrganization()));
            organization.setIcon(R.drawable.ic_organization);
        }
    }

    private UserTagsFragment mTagFragment;

    private void updateQuantities() {
        if (mProfile == null || isFinishing()) {
            return;
        }

        final Resources res = getResources();
        mItemCount.setText(mProfile.getItemCount() + "");
        mItemQuantity.setText(res.getQuantityString(R.plurals.user_items, mProfile.getItemCount()));

        mFollowerCount.setText(mProfile.getFollowerCount() + "");
        mFollowerQuantity.setText(res.getQuantityString(R.plurals.user_followers, mProfile.getFollowerCount()));

        mFollowingCount.setText(mProfile.getFollowingCount() + "");
        mFollowingQuantity.setText(res.getQuantityString(R.plurals.user_following, mProfile.getFollowingCount()));
    }

    private void updateTitle() {
        float titleAlpha = mToolBarLayout.shouldTriggerScrimOffset(mToolbarLayoutOffset) ? 1.f : 0.f;
        mTitleColorSpan.setAlpha(titleAlpha);
        // title
        mSpannableTitle.setSpan(mTitleColorSpan, 0, mSpannableTitle.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        mToolbar.setTitle(mSpannableTitle);

        // subtitle
        if (mSpannableSubtitle != null) {
            mSpannableSubtitle.setSpan(mTitleColorSpan, 0, mSpannableSubtitle.length(),
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            mToolbar.setSubtitle(mSpannableSubtitle);
        }
    }

    private void updateSocialButtons() {
        if (mProfile == null || mSocialButtonView == null || mSocialButtonContainer == null) {
            return;
        }

        boolean hasSocialButton = false;

        for (View button : mSocialButtons) {
            button.setVisibility(View.GONE);
        }

        if (!UIUtil.isEmpty(mProfile.getWebsite())) {
            hasSocialButton = true;
            mSocialButtons[WEBSITE_BUTTON_INDEX].setVisibility(View.VISIBLE);
        }

        if (!UIUtil.isEmpty(mProfile.getFacebookName())) {
            hasSocialButton = true;
            mSocialButtons[FACEBOOK_BUTTON_INDEX].setVisibility(View.VISIBLE);
        }

        if (!UIUtil.isEmpty(mProfile.getTwitterName())) {
            hasSocialButton = true;
            mSocialButtons[TWITTER_BUTTON_INDEX].setVisibility(View.VISIBLE);
        }

        if (!UIUtil.isEmpty(mProfile.getGithubName())) {
            hasSocialButton = true;
            mSocialButtons[GITHUB_BUTTON_INDEX].setVisibility(View.VISIBLE);
        }

        if (!UIUtil.isEmpty(mProfile.getLinkedinName())) {
            hasSocialButton = true;
            mSocialButtons[LINKEDIN_BUTTON_INDEX].setVisibility(View.VISIBLE);
        }

        mSocialButtonContainer.setVisibility(hasSocialButton ? View.VISIBLE : View.GONE);
    }

    @SuppressWarnings("unused")
    @OnClick(R.id.profile_social_website)
    void openWebsite() {
        if (mProfile != null) {
            UIUtil.openWebsite(this, mProfile.getWebsite());
        }
    }

    @SuppressWarnings("unused")
    @OnClick(R.id.profile_social_facebook)
    void openFacebook() {
        if (mProfile != null) {
            UIUtil.openFacebookUser(this, mProfile.getFacebookName());
        }
    }

    @SuppressWarnings("unused")
    @OnClick(R.id.profile_social_twitter)
    void openTwitter() {
        if (mProfile != null) {
            UIUtil.openTwitterUser(this, mProfile.getTwitterName());
        }
    }

    @SuppressWarnings("unused")
    @OnClick(R.id.profile_social_github)
    void openGithub() {
        if (mProfile != null) {
            UIUtil.openGithubUser(this, mProfile.getGithubName());
        }
    }

    @SuppressWarnings("unused")
    @OnClick(R.id.profile_social_linkedin)
    void openLinkedin() {
        if (mProfile != null) {
            UIUtil.openLinkedinUser(this, mProfile.getLinkedinName());
        }
    }

    @SuppressWarnings("unused")
    @OnClick(R.id.text_action_follow)
    void followUnFollow() {
        mHandler.removeMessages(MESSAGE_ACTION_FOLLOW);
        mHandler.sendEmptyMessageDelayed(MESSAGE_ACTION_FOLLOW, HANDLER_DELAY);
    }

    @Override
    public void onChange() {
        mHandler.removeMessages(MESSAGE_DATA_UPDATE);
        mHandler.sendEmptyMessageDelayed(MESSAGE_DATA_UPDATE, HANDLER_DELAY);
    }

    private static class ProfileViewPagerAdapter extends FragmentStatePagerAdapter {

        private final String mUserId;

        public ProfileViewPagerAdapter(FragmentManager fm, String userId) {
            super(fm);
            this.mUserId = userId;
        }

        @Override
        public Fragment getItem(int position) {
            if (position == 0) {
                return UserItemsFragment.newInstance(mUserId);
            } else if (position == 1) {
                return UserStockedArticlesFragment.newInstance(mUserId);
            }

            // fallback
            return DummyFragment.newInstance();
        }

        @Override
        public int getCount() {
            return 2;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            if (position == 0) {
                return Attiq.creator().getString(R.string.tab_title_items);
            } else if (position == 1) {
                return Attiq.creator().getString(R.string.tab_title_stocks);
            } else if (position == 2) {
                return Attiq.creator().getString(R.string.tab_title_tags);
            }

            // fallback
            return "Tab: " + position;
        }
    }

    @SuppressWarnings("unused")
    public void onEventMainThread(DocumentEvent event) {
        if (event.document != null) {
            Elements stats = event.document.getElementsByClass("userActivityChart_stats");
            Element statBlock;
            if (!UIUtil.isEmpty(stats) && (statBlock = stats.first()) != null) {
                Elements statElements = statBlock.children();
                Integer contribution = null;
                for (Element element : statElements) {
                    String unit = element.getElementsByClass("userActivityChart_statUnit").text();
                    if ("Contribution".equals(unit.trim())) {
                        try {
                            contribution = Integer
                                    .valueOf(element.getElementsByClass("userActivityChart_statCount").text());
                        } catch (NumberFormatException er) {
                            er.printStackTrace();
                        }

                        break;
                    }
                }

                if (contribution != null) {
                    ((State) mState).contribution = contribution;
                    EventBus.getDefault().post(new StateEvent<>(getClass().getSimpleName(), true, null, mState));
                }
            }
        }
    }

    @Override
    protected void initState() {
        mState = new State();
    }

    private static class State extends BaseState {

        private boolean isFollowing;

        private Integer contribution;
    }

    @Override
    protected int lookupTheme(UIUtil.Themes themes) {
        return themes == UIUtil.Themes.DARK ? R.style.Attiq_Theme_Dark_NoActionBar_Profile
                : R.style.Attiq_Theme_Light_NoActionBar_Profile;
    }
}