package com.airlocksoftware.hackernews.fragment;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.airlocksoftware.hackernews.R;
import com.airlocksoftware.hackernews.adapter.ThreadsAdapter;
import com.airlocksoftware.hackernews.interfaces.SharePopupInterface;
import com.airlocksoftware.hackernews.loader.ThreadsLoader;
import com.airlocksoftware.hackernews.model.Request;
import com.airlocksoftware.hackernews.model.Result;
import com.airlocksoftware.hackernews.model.StoryTimestamp;
import com.airlocksoftware.hackernews.parser.CommentsParser.ThreadsResponse;
import com.airlocksoftware.holo.actionbar.interfaces.ActionBarClient;
import com.airlocksoftware.holo.actionbar.interfaces.ActionBarController;
import com.airlocksoftware.holo.image.IconView;
import com.airlocksoftware.holo.utils.ViewUtils;
public class ThreadsFragment extends ListFragment implements ActionBarClient,
LoaderManager.LoaderCallbacks<ThreadsResponse> {
// State
private ListView mList;
private ThreadsAdapter mAdapter;
private View mError, mLoading, mMoreButton;
private TextView mMoreButtonText;
private IconView mMoreIcon;
private int mScrollPosition;
private String mUsername;
Request mRequest = Request.EMPTY;
private Result mLastResult;
private boolean mIsLoading = false;
// Listeners
private View.OnClickListener mMoreListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
mRequest = Request.MORE;
// change more link text & icon
mMoreButtonText.setText(getActivity().getString(R.string.loading_));
mMoreIcon.setVisibility(View.GONE);
getLoaderManager().restartLoader(0, null, ThreadsFragment.this);
refreshContentVisibility();
}
};
// Constants
private static final String SCROLL_POSITION = ThreadsFragment.class.getSimpleName() + ".scrollPosition";
@SuppressWarnings("unused")
private static final String TAG = ThreadsFragment.class.getSimpleName();
public static final String USERNAME = ThreadsFragment.class.getSimpleName() + ".username";
public ThreadsFragment() {
// default no-arg constructor
}
@Override
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
mUsername = getArguments().getString(USERNAME); // TODO can args ever be null?
getLoaderManager().initLoader(0, null, this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frg_loadinglist, container, false);
findViews(view);
setupMoreButton(inflater);
mAdapter = new ThreadsAdapter(getActivity(), mList, ((SharePopupInterface) getActivity()).getSharePopup());
setListAdapter(mAdapter);
refreshContentVisibility();
return view;
}
private void setupMoreButton(LayoutInflater inflater) {
// inflate & add the more button
mMoreButton = inflater.inflate(R.layout.vw_more_link, mList, false);
mMoreButton.setOnClickListener(mMoreListener);
mMoreButton.setVisibility(View.GONE);
mMoreButtonText = (TextView) mMoreButton.findViewById(R.id.txt_more);
mMoreIcon = (IconView) mMoreButton.findViewById(R.id.icv_more);
mList.addFooterView(mMoreButton, null, false);
}
private void findViews(View view) {
mError = view.findViewById(R.id.cnt_error);
mLoading = view.findViewById(R.id.cnt_loading);
ViewUtils.fixBackgroundRepeat(mError);
ViewUtils.fixBackgroundRepeat(mLoading);
mList = (ListView) view.findViewById(android.R.id.list);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// restoring saved state
if (savedInstanceState != null) {
mUsername = savedInstanceState.getString(USERNAME);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putString(USERNAME, mUsername);
outState.putInt(SCROLL_POSITION, mScrollPosition);
super.onSaveInstanceState(outState);
}
@Override
public Loader<ThreadsResponse> onCreateLoader(int id, Bundle args) {
mIsLoading = true;
return new ThreadsLoader(getActivity(), mRequest, mUsername);
}
@Override
public void onLoadFinished(Loader<ThreadsResponse> loader, ThreadsResponse response) {
mIsLoading = false;
mLastResult = response.result;
switch (mLastResult) {
case SUCCESS: // first page
mAdapter.clear();
mAdapter.addThreads(response.threads);
break;
case MORE: // new data from web
mAdapter.addThreads(response.threads);
break;
case FNID_EXPIRED: // the link was expired - refresh the page
Toast.makeText(getActivity(), getActivity().getString(R.string.link_expired), Toast.LENGTH_SHORT)
.show();
// start loader with refresh request
mRequest = Request.REFRESH;
getLoaderManager().restartLoader(0, null, this);
break;
case FAILURE: // Show error message
Toast.makeText(getActivity(), getActivity().getString(R.string.problem_downloading_content), Toast.LENGTH_SHORT)
.show();
break;
default:
break;
}
refreshMoreButtonVisibility(response.timestamp);
refreshContentVisibility();
}
private void refreshMoreButtonVisibility(StoryTimestamp timestamp) {
mMoreButtonText.setText(getActivity().getString(R.string.load_more));
mMoreIcon.setVisibility(View.VISIBLE);
// show more link (timestamp is only not null if we have a valid moreFnid)
mMoreButton.setVisibility(ViewUtils.boolToVis(timestamp != null));
}
@Override
public void onLoaderReset(Loader<ThreadsResponse> loader) {
// TODO Auto-generated method stub
}
@Override
public void setupActionBar(Context context, ActionBarController ab) {
ab.setTitleText(context.getString(R.string.threads));
}
@Override
public void cleanupActionBar(Context context, ActionBarController ab) {
ab.setTitleText(null);
}
/** Determines which view (List, Error, or Loading) show be visible. **/
private void refreshContentVisibility() {
// can't refresh visibility until / unless all views are created
if (mAdapter == null || mError == null || mLoading == null) return;
boolean loadingVis = mIsLoading;
boolean errorVis = mLastResult == Result.FAILURE && !mIsLoading;
boolean listVis = !loadingVis && !errorVis;
mError.setVisibility(ViewUtils.boolToVis(errorVis));
mLoading.setVisibility(ViewUtils.boolToVis(loadingVis));
mList.setVisibility(ViewUtils.boolToVis(listVis));
}
}