package se.alexanderblom.delicious.fragments;
import java.io.IOException;
import java.util.List;
import se.alexanderblom.delicious.DeliciousAccount;
import se.alexanderblom.delicious.R;
import se.alexanderblom.delicious.adapter.PostsAdapter;
import se.alexanderblom.delicious.http.Request;
import se.alexanderblom.delicious.http.Response;
import se.alexanderblom.delicious.model.Post;
import se.alexanderblom.delicious.model.PostsParser;
import se.alexanderblom.delicious.ui.BaseActivity;
import se.alexanderblom.delicious.ui.MainActivity;
import se.alexanderblom.delicious.util.AsyncLoader;
import android.app.Activity;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.ShareActionProvider;
public class PostListFragment extends ErrorListFragment implements LoaderCallbacks<List<Post>> {
private static final String TAG = "PostListFragment";
private static final String RECENTS_URL = "https://api.del.icio.us/v1/json/posts/recent";
private static final String ARG_TAG = "tag";
private static final int POSTS_LOADER = 1;
private PostsAdapter adapter;
private String tag;
public static PostListFragment newInstance(String tag) {
PostListFragment f = new PostListFragment();
f.setArguments(createArgs(tag));
return f;
}
public static Bundle createArgs(String tag) {
Bundle args = new Bundle();
args.putString(ARG_TAG, tag);
return args;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments() != null ? getArguments() : Bundle.EMPTY;
tag = args.getString(ARG_TAG);
adapter = new PostsAdapter(getActivity());
setListAdapter(adapter);
setHasOptionsMenu(true);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
getListView().setMultiChoiceModeListener(new PostActionMode());
BaseActivity activity = (BaseActivity) getActivity();
if (activity.hasAccount()) {
setListShown(false);
getLoaderManager().initLoader(POSTS_LOADER, null, this);
}
}
@Override
public void onStart() {
super.onStart();
Activity activity = getActivity();
if (tag != null) {
activity.setTitle(getString(R.string.page_tag, tag));
} else {
activity.setTitle(R.string.page_recent);
}
if (tag == null && activity instanceof MainActivity) {
MainActivity main = (MainActivity) activity;
main.setSelectedPage(R.id.page_recent);
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_refresh, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.menu_refresh) {
Log.d(TAG, "Refreshing posts");
getLoaderManager().restartLoader(POSTS_LOADER, null, this);
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
Post post = adapter.getItem(position);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(post.getLink()));
startActivity(intent);
}
@Override
public Loader<List<Post>> onCreateLoader(int id, Bundle args) {
String url = RECENTS_URL;
if (tag != null) {
url = Uri.parse("https://api.del.icio.us/v1/json/posts/all").buildUpon()
.appendQueryParameter("tag", tag)
.build()
.toString();
}
setListShown(false);
return new PostsLoader(getActivity(), DeliciousAccount.get(getActivity()), url);
}
@Override
public void onLoadFinished(Loader<List<Post>> loader, List<Post> posts) {
if (posts != null) {
adapter.setList(posts);
setListShown(true);
} else {
// There was an error
showLoadingError();
}
}
@Override
public void onLoaderReset(Loader<List<Post>> loader) {
adapter.clear();
}
@Override
protected void onRetry() {
getLoaderManager().initLoader(POSTS_LOADER, null, this);
}
private void showLoadingError() {
getLoaderManager().destroyLoader(POSTS_LOADER);
showError();
}
private static class PostsLoader extends AsyncLoader<List<Post>> {
private static final String TAG = "PostsLoader";
private DeliciousAccount account;
private String url;
public PostsLoader(Context context, DeliciousAccount account, String url) {
super(context);
this.account = account;
this.url = url;
}
@Override
public List<Post> loadInBackground() {
try {
Response response = Request.get(url)
.addAuth(account)
.execute();
try {
return new PostsParser(response.getReader()).getPosts();
} finally {
response.disconnect();
}
} catch (IOException e) {
Log.e(TAG, "Failed to fetch posts", e);
return null;
}
}
}
private class PostActionMode implements ListView.MultiChoiceModeListener, ShareActionProvider.OnShareTargetSelectedListener {
private ActionMode actionMode;
private ShareActionProvider provider;
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
actionMode = mode;
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context_post, menu);
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
provider = null;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
provider = (ShareActionProvider) menu.findItem(R.id.menu_share).getActionProvider();
provider.setOnShareTargetSelectedListener(this);
return false;
}
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
if (checked) {
// Only allow the user to check one item
SparseBooleanArray checkedArray = getListView().getCheckedItemPositions();
checkedArray.clear();
checkedArray.put(position, true);
provider.setShareIntent(createShareIntent(adapter.getItem(position)));
} else {
mode.finish();
}
}
@Override
public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
// Close action mode after user has shared
actionMode.finish();
return false;
}
private Intent createShareIntent(Post post) {
return new Intent(Intent.ACTION_SEND)
.setType("text/plain")
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
.putExtra(Intent.EXTRA_SUBJECT, post.getTitle())
.putExtra(Intent.EXTRA_TEXT, post.getLink());
}
}
}