com.andrada.sitracker.ui.fragment.RemoteAuthorsFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.andrada.sitracker.ui.fragment.RemoteAuthorsFragment.java

Source

/*
 * Copyright 2014 Gleb Godonoga.
 *
 * 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 com.andrada.sitracker.ui.fragment;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.text.TextUtils;
import android.view.View;
import android.widget.BaseAdapter;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.andrada.sitracker.Constants;
import com.andrada.sitracker.R;
import com.andrada.sitracker.contracts.AppUriContract;
import com.andrada.sitracker.db.beans.SearchedAuthor;
import com.andrada.sitracker.events.AuthorAddedEvent;
import com.andrada.sitracker.exceptions.SearchException;
import com.andrada.sitracker.loader.AsyncTaskResult;
import com.andrada.sitracker.loader.SamlibSearchLoader;
import com.andrada.sitracker.tasks.AddAuthorTask;
import com.andrada.sitracker.ui.BaseActivity;
import com.andrada.sitracker.ui.components.CollectionView;
import com.andrada.sitracker.ui.fragment.adapters.SearchResultsAdapter;
import com.andrada.sitracker.util.AnalyticsHelper;
import com.andrada.sitracker.util.UIUtils;

import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EFragment;
import org.androidannotations.annotations.UiThread;
import org.androidannotations.annotations.ViewById;
import org.jetbrains.annotations.NotNull;

import java.util.List;

import de.greenrobot.event.EventBus;
import de.keyboardsurfer.android.widget.crouton.Configuration;
import de.keyboardsurfer.android.widget.crouton.Crouton;
import de.keyboardsurfer.android.widget.crouton.Style;

import static com.andrada.sitracker.util.LogUtils.LOGD;
import static com.andrada.sitracker.util.LogUtils.makeLogTag;

@EFragment(R.layout.fragment_search)
public class RemoteAuthorsFragment extends Fragment implements
        LoaderManager.LoaderCallbacks<AsyncTaskResult<List<SearchedAuthor>>>, SearchResultsAdapter.Callbacks {

    private static final String TAG = makeLogTag(RemoteAuthorsFragment.class);
    private static SearchResultsAdapter.Callbacks sDummyCallbacks = new SearchResultsAdapter.Callbacks() {
        @Override
        public void onAuthorSelected(SearchedAuthor author) {
        }
    };
    @ViewById
    CollectionView list;
    @ViewById
    ProgressBar loading;
    @ViewById
    TextView emptyText;
    @Bean
    SearchResultsAdapter adapter;
    private Bundle mArguments;
    private Uri mCurrentUri;

    @Override
    public void onAuthorSelected(SearchedAuthor author) {
        final SearchedAuthor authorToAdd = author;
        if (author.isAdded()) {
            return;
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage(getString(R.string.add_author_confirmation))
                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        //TODO make sure to run this in UI thread
                        loading.setVisibility(View.VISIBLE);
                        new AddAuthorTask(getActivity()).execute(authorToAdd.getAuthorUrl());
                    }
                }).setNegativeButton(android.R.string.cancel, null);
        builder.create().show();
    }

    public void onEvent(@NotNull AuthorAddedEvent event) {
        //Cancel any further delivery
        EventBus.getDefault().cancelEventDelivery(event);
        if (event.authorUrl != null) {
            //Find author with this url
            SearchedAuthor auth = adapter.getItemById(event.authorUrl);
            if (auth != null) {
                auth.setAdded(true);
                ((BaseAdapter) list.getAdapter()).notifyDataSetChanged();
            }
        }
        loading.setVisibility(View.GONE);
        String message = event.message;

        AnalyticsHelper.getInstance().sendEvent(Constants.GA_EXPLORE_CATEGORY, Constants.GA_EVENT_AUTHOR_ADDED,
                Constants.GA_EVENT_AUTHOR_ADDED);

        if (getActivity() == null) {
            return;
        }
        View view = getLayoutInflater(null).inflate(R.layout.crouton_custom_pos_textview, null);
        if (message.length() == 0) {
            message = getString(R.string.author_add_success_crouton_message);
            view.findViewById(android.R.id.background).setBackgroundColor(Style.holoGreenLight);
        } else {
            view.findViewById(android.R.id.background).setBackgroundColor(Style.holoRedLight);
        }

        int topPadding = UIUtils.calculateActionBarSize(getActivity());
        view.setPadding(view.getPaddingLeft(), topPadding, view.getPaddingRight(), view.getPaddingBottom());
        TextView tv = (TextView) view.findViewById(android.R.id.text1);
        tv.setText(message);
        Crouton cr = Crouton.make(getActivity(), view);
        cr.setConfiguration(new Configuration.Builder().setDuration(Configuration.DURATION_LONG).build());
        cr.show();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
        setRetainInstance(true);
        adapter.setCallbacks(this);
        //noinspection VariableNotUsedInsideIf
        if (mCurrentUri != null) {
            // Only if this is a config change should we initLoader(), to reconnect with an
            // existing loader. Otherwise, the loader will be init'd when reloadFromArguments
            // is called.
            getLoaderManager().initLoader(SamlibSearchLoader.SEARCH_TOKEN, null, RemoteAuthorsFragment.this);
        }
    }

    @Override
    public void onDestroy() {
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }

    @UiThread(delay = 100)
    void requestUpdateCollectionView(List<SearchedAuthor> data) {
        updateCollectionView(data);
    }

    public void requestQueryUpdate(String query, int searchType) {
        //Test query for URL
        if (query.matches(Constants.SIMPLE_URL_REGEX) && query.startsWith(Constants.HTTP_PROTOCOL)) {
            //This looks like an url
            loading.setVisibility(View.VISIBLE);
            new AddAuthorTask(getActivity()).execute(query);
        } else {
            reloadFromArguments(BaseActivity.intentToFragmentArguments(
                    new Intent(Intent.ACTION_SEARCH, AppUriContract.buildSamlibSearchUri(query, searchType))));
        }
    }

    public void setContentTopClearance(int topClearance) {
        list.setContentTopClearance(topClearance);
    }

    public void reloadFromArguments(Bundle arguments) {
        // Load new arguments
        if (arguments == null) {
            arguments = new Bundle();
        } else {
            // since we might make changes, don't meddle with caller's copy
            arguments = (Bundle) arguments.clone();
        }

        // save arguments so we can reuse it when reloading from content observer events
        mArguments = arguments;

        LOGD(TAG, "SessionsFragment reloading from arguments: " + arguments);
        mCurrentUri = arguments.getParcelable("_uri");
        LOGD(TAG, "SessionsFragment reloading, uri=" + mCurrentUri);
        reloadSearchData();
    }

    private void reloadSearchData() {
        LOGD(TAG, "Reloading search data");
        getLoaderManager().restartLoader(SamlibSearchLoader.SEARCH_TOKEN, mArguments, RemoteAuthorsFragment.this);
        emptyText.setVisibility(View.GONE);
        list.setVisibility(View.GONE);
        loading.setVisibility(View.VISIBLE);
    }

    private void updateCollectionView(List<SearchedAuthor> data) {
        adapter.swapData(data);
        LOGD(TAG, "Data has " + data.size() + " items. Will now update collection view.");
        int itemCount = data.size();
        CollectionView.Inventory inv;
        if (itemCount == 0) {
            showEmptyView();
            inv = new CollectionView.Inventory();
        } else {
            hideEmptyView();
            inv = prepareInventory();
        }
        list.setCollectionAdapter(adapter);
        list.updateInventory(inv, UIUtils.hasHoneycombMR1());

    }

    private CollectionView.Inventory prepareInventory() {
        LOGD(TAG, "Preparing collection view inventory.");
        final int displayCols = getResources().getInteger(R.integer.search_grid_columns);
        CollectionView.InventoryGroup group = new CollectionView.InventoryGroup(1000).setDisplayCols(displayCols)
                .setShowHeader(false);
        int dataIndex = -1;
        while ((dataIndex + 1) < adapter.getCount()) {
            ++dataIndex;
            group.addItemWithCustomDataIndex(dataIndex);
        }
        CollectionView.Inventory inventory = new CollectionView.Inventory();
        inventory.addGroup(group);
        return inventory;
    }

    @Override
    public void onDetach() {
        super.onDetach();
        adapter.setCallbacks(sDummyCallbacks);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (adapter != null) {
            adapter.setCallbacks(this);
            if (adapter.getCount() > 0) {
                requestUpdateCollectionView(adapter.getData());
            }
        }
    }

    private void hideEmptyView() {
        emptyText.setVisibility(View.GONE);
        loading.setVisibility(View.GONE);
        list.setVisibility(View.VISIBLE);
    }

    private void showEmptyView() {
        final String searchQuery = AppUriContract.isSearchUri(mCurrentUri)
                ? AppUriContract.getSearchQuery(mCurrentUri)
                : null;

        if (AppUriContract.isSearchUri(mCurrentUri)
                && (TextUtils.isEmpty(searchQuery) || "*".equals(searchQuery))) {
            // Empty search query (for example, user hasn't started to type the query yet),
            // so don't show an empty view.
            emptyText.setText("");
            emptyText.setVisibility(View.VISIBLE);
            list.setVisibility(View.VISIBLE);
            loading.setVisibility(View.GONE);
        } else {
            // Showing authors as a result of search. If blank - show no resuls
            emptyText.setText(R.string.empty_search_results);
            emptyText.setVisibility(View.VISIBLE);
            list.setVisibility(View.VISIBLE);
            loading.setVisibility(View.GONE);
        }
    }

    @Override
    public Loader<AsyncTaskResult<List<SearchedAuthor>>> onCreateLoader(int id, Bundle data) {
        LOGD(TAG, "onCreateLoader, id=" + id + ", data=" + data);
        final Intent intent = BaseActivity.fragmentArgumentsToIntent(data);
        Uri searchUri = intent.getData();
        Loader<AsyncTaskResult<List<SearchedAuthor>>> loader = null;
        if (id == SamlibSearchLoader.SEARCH_TOKEN) {
            LOGD(TAG, "Creating search loader for " + searchUri);
            loader = new SamlibSearchLoader(getActivity(), searchUri);
        }
        return loader;
    }

    @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
    @Override
    public void onLoadFinished(Loader<AsyncTaskResult<List<SearchedAuthor>>> loader,
            AsyncTaskResult<List<SearchedAuthor>> data) {
        if (getActivity() == null) {
            return;
        }

        int token = loader.getId();
        LOGD(TAG, "Loader finished: search");
        if (token == SamlibSearchLoader.SEARCH_TOKEN) {
            if (data.getError() instanceof SearchException) {
                int errorMsg;
                switch (((SearchException) data.getError()).getError()) {
                case SAMLIB_BUSY:
                    errorMsg = R.string.cannot_search_busy;
                    break;
                case NETWORK_ERROR:
                    errorMsg = R.string.cannot_search_network;
                    break;
                case INTERNAL_ERROR:
                    errorMsg = R.string.cannot_search_internal;
                    break;
                default:
                    errorMsg = R.string.cannot_search_unknown;
                    break;
                }
                Style.Builder alertStyle = new Style.Builder().setTextAppearance(android.R.attr.textAppearanceLarge)
                        .setPaddingInPixels(25).setBackgroundColorValue(Style.holoRedLight);
                Crouton.makeText(getActivity(), getString(errorMsg), alertStyle.build()).show();
            }
            updateCollectionView(data.getResult());
        }
    }

    @Override
    public void onLoaderReset(Loader<AsyncTaskResult<List<SearchedAuthor>>> listLoader) {

    }
}