org.runbuddy.tomahawk.ui.fragments.starpage.SocialActionsFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.runbuddy.tomahawk.ui.fragments.starpage.SocialActionsFragment.java

Source

/* == This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
 *
 *   Copyright 2014, Enno Gottschalk <mrmaffen@googlemail.com>
 *
 *   Tomahawk 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.
 *
 *   Tomahawk 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 Tomahawk. If not, see <http://www.gnu.org/licenses/>.
 */
package org.runbuddy.tomahawk.ui.fragments.starpage;

import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.media.session.PlaybackStateCompat;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;

import org.jdeferred.DoneCallback;
import org.runbuddy.libtomahawk.collection.Album;
import org.runbuddy.libtomahawk.collection.Artist;
import org.runbuddy.libtomahawk.collection.Playlist;
import org.runbuddy.libtomahawk.collection.PlaylistEntry;
import org.runbuddy.libtomahawk.infosystem.InfoSystem;
import org.runbuddy.libtomahawk.infosystem.SocialAction;
import org.runbuddy.libtomahawk.infosystem.User;
import org.runbuddy.libtomahawk.infosystem.hatchet.HatchetInfoPlugin;
import org.runbuddy.libtomahawk.resolver.Query;
import org.runbuddy.libtomahawk.utils.ViewUtils;
import org.runbuddy.tomahawk.R;
import org.runbuddy.tomahawk.activities.TomahawkMainActivity;
import org.runbuddy.tomahawk.adapters.Segment;
import org.runbuddy.tomahawk.adapters.TomahawkListAdapter;
import org.runbuddy.tomahawk.app.TomahawkApp;
import org.runbuddy.tomahawk.ui.fragments.ArtistPagerFragment;
import org.runbuddy.tomahawk.ui.fragments.ContentHeaderFragment;
import org.runbuddy.tomahawk.ui.fragments.PlaylistEntriesFragment;
import org.runbuddy.tomahawk.ui.fragments.TomahawkFragment;
import org.runbuddy.tomahawk.ui.fragments.UserPagerFragment;
import org.runbuddy.tomahawk.utils.FragmentUtils;
import org.runbuddy.tomahawk.utils.IdGenerator;
import org.runbuddy.tomahawk.utils.ThreadManager;
import org.runbuddy.tomahawk.utils.TomahawkRunnable;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;

import se.emilsjolander.stickylistheaders.StickyListHeadersListView;

/**
 * {@link org.runbuddy.tomahawk.ui.fragments.TomahawkFragment} which shows information provided
 * by a User object. Such as the image, feed and nowPlaying info of a user.
 */
public class SocialActionsFragment extends TomahawkFragment implements
        StickyListHeadersListView.OnHeaderClickListener, NavigationView.OnNavigationItemSelectedListener {

    private static final String TAG = SocialActionsFragment.class.getSimpleName();

    public static final int SHOW_MODE_SOCIALACTIONS = 0;

    public static final int SHOW_MODE_DASHBOARD = 1;

    public final HashSet<Date> mResolvingPages = new HashSet<>();

    private List<User> mSuggestedUsers;

    private String mRandomUsersRequestId;

    @SuppressWarnings("unused")
    public void onEvent(InfoSystem.ResultsEvent event) {
        if (mRandomUsersRequestId != null && mRandomUsersRequestId.equals(event.mInfoRequestData.getRequestId())) {
            mSuggestedUsers = event.mInfoRequestData.getResultList(User.class);
        }

        super.onEvent(event);
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mUser == null) {
            return;
        }

        mHideRemoveButton = true;

        if (mShowMode == SHOW_MODE_DASHBOARD) {
            if (mContainerFragmentClass == null) {
                getActivity().setTitle(getString(R.string.drawer_title_star_runner).toUpperCase());
            }
            for (Date date : mUser.getFriendsFeed().keySet()) {
                String requestId = InfoSystem.get().resolveFriendsFeed(mUser, date);
                if (requestId != null) {
                    mCorrespondingRequestIds.add(requestId);
                }
            }
            User.getSelf().done(new DoneCallback<User>() {
                @Override
                public void onDone(User user) {
                    if (user.getFollowCount() >= 0 && user.getFollowCount() <= 5 && mRandomUsersRequestId == null) {
                        mRandomUsersRequestId = InfoSystem.get().getRandomUsers(5);
                        mCorrespondingRequestIds.add(mRandomUsersRequestId);
                    }
                }
            });
        } else {
            if (mContainerFragmentClass == null) {
                getActivity().setTitle("");
            }
            for (Date date : mUser.getSocialActions().keySet()) {
                String requestId = InfoSystem.get().resolveSocialActions(mUser, date);
                if (requestId != null) {
                    mCorrespondingRequestIds.add(requestId);
                }
            }
        }
        getListView().setOnHeaderClickListener(this);
        updateAdapter();
    }

    @Override
    public void onPause() {
        super.onPause();

        mResolvingPages.clear();
    }

    /**
     * Called every time an item inside a ListView or GridView is clicked
     *
     * @param view the clicked view
     * @param o    the Object which corresponds to the click
     */
    @Override
    public void onItemClick(View view, Object o, Segment segment) {
        if (getMediaController() == null) {
            Log.e(TAG, "onItemClick failed because getMediaController() is null");
            return;
        }
        final TomahawkMainActivity activity = (TomahawkMainActivity) getActivity();

        Object item = o;
        if (o instanceof SocialAction) {
            item = ((SocialAction) o).getTargetObject();
        }
        Bundle bundle = new Bundle();
        if (item instanceof User) {
            bundle.putString(TomahawkFragment.USER, ((User) item).getId());
            bundle.putInt(CONTENT_HEADER_MODE, ContentHeaderFragment.MODE_HEADER_STATIC_USER);
            FragmentUtils.replace(activity, UserPagerFragment.class, bundle);
        } else if (item instanceof Query && o instanceof SocialAction) {
            PlaylistEntry entry = mUser.getPlaylistEntry((SocialAction) o);
            if (entry.getQuery().isPlayable()) {
                if (getPlaybackManager().getCurrentEntry() == entry) {
                    // if the user clicked on an already playing track
                    int playState = getMediaController().getPlaybackState().getState();
                    if (playState == PlaybackStateCompat.STATE_PLAYING) {
                        getMediaController().getTransportControls().pause();
                    } else if (playState == PlaybackStateCompat.STATE_PAUSED) {
                        getMediaController().getTransportControls().play();
                    }
                } else {
                    Playlist playlist;
                    if (mShowMode == SHOW_MODE_SOCIALACTIONS) {
                        playlist = mUser.getSocialActionsPlaylist();
                    } else {
                        playlist = mUser.getFriendsFeedPlaylist();
                    }
                    getPlaybackManager().setPlaylist(playlist, entry);
                    getMediaController().getTransportControls().play();
                }
            }
        } else if (item instanceof Album) {
            bundle.putString(TomahawkFragment.ALBUM, ((Album) item).getCacheKey());
            bundle.putString(TomahawkFragment.COLLECTION_ID, mCollection.getId());
            bundle.putInt(CONTENT_HEADER_MODE, ContentHeaderFragment.MODE_HEADER_DYNAMIC);
            FragmentUtils.replace(activity, PlaylistEntriesFragment.class, bundle);
        } else if (item instanceof Artist) {
            bundle.putString(TomahawkFragment.ARTIST, ((Artist) item).getCacheKey());
            bundle.putString(TomahawkFragment.COLLECTION_ID, mCollection.getId());
            bundle.putInt(CONTENT_HEADER_MODE, ContentHeaderFragment.MODE_HEADER_DYNAMIC_PAGER);
            bundle.putLong(CONTAINER_FRAGMENT_ID, IdGenerator.getSessionUniqueId());
            FragmentUtils.replace(activity, ArtistPagerFragment.class, bundle);
        } else if (item instanceof Playlist) {
            bundle.putInt(CONTENT_HEADER_MODE, ContentHeaderFragment.MODE_HEADER_DYNAMIC);
            bundle.putString(TomahawkFragment.PLAYLIST, ((Playlist) item).getCacheKey());
            FragmentUtils.replace(activity, PlaylistEntriesFragment.class, bundle);
        }
    }

    @Override
    public void onHeaderClick(StickyListHeadersListView l, View header, int itemPosition, long headerId,
            boolean currentlySticky) {
        TomahawkMainActivity activity = (TomahawkMainActivity) getActivity();
        Object item = getListAdapter().getItem(itemPosition);
        if (item instanceof List && !((List) item).isEmpty()) {
            item = ((List) item).get(0);
        }
        if (item instanceof SocialAction) {
            Bundle bundle = new Bundle();
            bundle.putString(TomahawkFragment.USER, ((SocialAction) item).getUser().getId());
            bundle.putInt(CONTENT_HEADER_MODE, ContentHeaderFragment.MODE_HEADER_STATIC_USER);
            FragmentUtils.replace(activity, UserPagerFragment.class, bundle);
        }
    }

    /**
     * Update this {@link TomahawkFragment}'s {@link TomahawkListAdapter} content
     */
    @Override
    protected void updateAdapter() {
        if (!mIsResumed) {
            return;
        }
        if (mShowMode == SHOW_MODE_DASHBOARD && !getResources().getBoolean(R.bool.is_landscape)) {
            setAreHeadersSticky(true);
        }
        TomahawkRunnable r = new TomahawkRunnable(TomahawkRunnable.PRIORITY_IS_VERYHIGH) {
            @Override
            public void run() {
                if (mUser != null) {
                    List<Segment> segments = new ArrayList<>();
                    int extraPadding = TomahawkApp.getContext().getResources()
                            .getDimensionPixelSize(R.dimen.padding_medium) + ViewUtils.convertDpToPixel(32);
                    if (mSuggestedUsers != null) {
                        List<Object> suggestions = new ArrayList<>();
                        suggestions.addAll(mSuggestedUsers);
                        Segment segment = new Segment.Builder(suggestions)
                                .headerLayout(R.layout.list_header_socialaction_fake)
                                .headerString(TomahawkApp.getContext().getString(R.string.suggest_users) + ":")
                                .leftExtraPadding(extraPadding).build();
                        segments.add(segment);
                    }
                    TreeMap<Date, List<SocialAction>> socialActionsList;
                    if (mShowMode == SHOW_MODE_DASHBOARD) {
                        socialActionsList = mUser.getFriendsFeed();
                    } else {
                        socialActionsList = mUser.getSocialActions();
                    }
                    List<List<SocialAction>> mergedActions = mergeSocialActions(socialActionsList);
                    for (List<SocialAction> actions : mergedActions) {
                        Segment segment = toSegment(actions);
                        segments.add(segment);
                    }
                    fillAdapter(segments);
                }
            }
        };
        ThreadManager.get().execute(r);
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        super.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);

        if (mUser != null && firstVisibleItem + visibleItemCount + 5 > totalItemCount) {
            mShowMode = getArguments().getInt(SHOW_MODE);
            if (mShowMode == SHOW_MODE_DASHBOARD) {
                if (!mResolvingPages.contains(mUser.getFriendsFeedNextDate())) {
                    mResolvingPages.add(mUser.getFriendsFeedNextDate());
                    String requestId = InfoSystem.get().resolveFriendsFeed(mUser, mUser.getFriendsFeedNextDate());
                    if (requestId != null) {
                        mCorrespondingRequestIds.add(requestId);
                    }
                }
            } else {
                if (!mResolvingPages.contains(mUser.getSocialActionsNextDate())) {
                    mResolvingPages.add(mUser.getSocialActionsNextDate());
                    String requestId = InfoSystem.get().resolveSocialActions(mUser,
                            mUser.getSocialActionsNextDate());
                    if (requestId != null) {
                        mCorrespondingRequestIds.add(requestId);
                    }
                }
            }
        }
    }

    public static List<List<SocialAction>> mergeSocialActions(TreeMap<Date, List<SocialAction>> actions) {
        List<List<SocialAction>> mergedActionsList = new ArrayList<>();
        for (List<SocialAction> socialActions : actions.descendingMap().values()) {
            mergedActionsList.addAll(mergeSocialActions(socialActions));
        }
        return mergedActionsList;
    }

    public static List<List<SocialAction>> mergeSocialActions(List<SocialAction> actions) {
        List<List<SocialAction>> mergedActionsList = new ArrayList<>();
        Set<SocialAction> checkedActions = new HashSet<>();
        for (SocialAction socialAction : actions) {
            if (!checkedActions.contains(socialAction) && shouldDisplayAction(socialAction)) {
                List<SocialAction> mergedActions = new ArrayList<>();
                mergedActions.add(socialAction);
                checkedActions.add(socialAction);
                for (SocialAction actionToCompare : actions) {
                    if (!checkedActions.contains(actionToCompare)
                            && shouldMergeAction(actionToCompare, socialAction)) {
                        mergedActions.add(actionToCompare);
                        checkedActions.add(actionToCompare);
                    }
                }
                mergedActionsList.add(mergedActions);
            }
        }
        return mergedActionsList;
    }

    private static boolean shouldDisplayAction(SocialAction socialAction) {
        boolean action = Boolean.valueOf(socialAction.getAction());
        String type = socialAction.getType();
        return HatchetInfoPlugin.HATCHET_SOCIALACTION_TYPE_CREATEPLAYLIST.equals(type)
                || HatchetInfoPlugin.HATCHET_SOCIALACTION_TYPE_LATCHON.equals(type)
                || HatchetInfoPlugin.HATCHET_SOCIALACTION_TYPE_FOLLOW.equals(type)
                || (action && HatchetInfoPlugin.HATCHET_SOCIALACTION_TYPE_LOVE.equals(type));
    }

    private static boolean shouldMergeAction(SocialAction actionToCompare, SocialAction socialAction) {
        return actionToCompare.getUser() == socialAction.getUser()
                && actionToCompare.getType().equals(socialAction.getType())
                && actionToCompare.getTargetObject().getClass() == socialAction.getTargetObject().getClass();
    }

    private Segment toSegment(List<SocialAction> actions) {
        SocialAction first = actions.get(0);
        Segment.Builder builder;
        if (first.getTargetObject() instanceof Album || first.getTargetObject() instanceof User
                || first.getTargetObject() instanceof Artist || first.getTargetObject() instanceof Playlist) {
            builder = new Segment.Builder(actions).headerLayout(R.layout.list_header_socialaction).showAsGrid(
                    R.integer.grid_column_count_feed, R.dimen.padding_superlarge, R.dimen.padding_small);
        } else {
            builder = new Segment.Builder(actions).headerLayout(R.layout.list_header_socialaction);
        }
        int extraPadding = TomahawkApp.getContext().getResources().getDimensionPixelSize(R.dimen.padding_medium)
                + ViewUtils.convertDpToPixel(32);
        builder.leftExtraPadding(extraPadding);
        return builder.build();
    }

    @Override
    public boolean onNavigationItemSelected(MenuItem item) {

        return false;
    }

}